DEV Community

Willane Paiva
Willane Paiva

Posted on

Observabilidade em aplicações móveis

Observalidade é um conceito importante no desenvolvimento de aplicações móveis, servindo para acompanhar a saúde do sistema, ajudando a identificar problemas mais rápido, facilitando o entendimento de um fluxo entre outros.

Dentro da observabilidade temos logs, alertas entre outros conceitos, sendo os dois primeiros abordados a seguir.

Logs

Os logs nos trazem algum tipo de informação do sistema, podendo ser de diferentes tipos:

  • info: uma mensagem de fluxo, como ao iniciar a execução de um método, indicar o resultado de uma execução
  • Error: algum problema que aconteceu, como uma exceção lançada numa requisição de dados
  • Warn: indica alguma informação que precisa de atenção, mas não necessariamente é algo critico

Esses sãos os tipos mais relevantes de forma inicial, podendo serem explorados mais a parte. Os logs são uma ferramenta poderosa, que permitem identificar todo o caminho feito para obter um dado, como quais requisições foram feitas e os seus retornos, mesmo entre diferentes sistemas, como ao usar trace id, que seria um identificar desse caminho.

Alertas

Os alertas indicam incidência no sistema, como um comportamento ocorrendo em um intervalo de tempo, podendo ser combinado com outras ferramentas para notificar em canal do slack, por exemplo, ligar para responsável pelo sistema/ on-call, servindo para assim identificar comportamentos indesejados no sistema e corrigi-los.

Ferramentas

Existem diferentes ferramentas disponíveis para enviar e gerenciar esses logs como o New Relic, Splunk, Sentry entre outras, onde a escolha por uma delas vai depender do uso desejado, custo, integração com plataforma usada no project etc.

Exemplo em flutter

A seguir temos um exemplo de como usar logs usando flutter, nesse caso foi criada uma classe AppLogger , que é responsável por gerenciar diferentes tipos de logs e pode ser alterada para envia-los para a ferramenta desejada, podendo ser usada em diferentes locais do projeto, centralizado as definições e facilitando manutenções futuras. O que o log vai incluir depende do que se espera, pode ser uma mensagem sobre o contexto atual (’usuário requisitou dado’), assim como incluir erro ocorrido, id do usuário entre tantos outros.
Outro ponto interessante pode ser considerar se a aplicação está em modo de desenvolvimento ou não para fazer os envios do log para a ferramenta ou apenas logar localmente, evitando assim custos extras.

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'dart:developer' as developer;

class AppLogger {
  AppLogger({this.isDebug = false});
  final bool isDebug;
  void logInfo(String message) {
    if (isDebug) {
      debugPrint('INFORMAÇÃO: $message');
      return;
    }
    // Aqui poderia enviar para um serviço invés do log
    developer.log(message, name: 'AppLogger', level: 800);
  }

  void logError(String message) {
    if (isDebug) {
      debugPrint('ERRO: $message');
      return;
    }
    developer.log(message, name: 'AppLogger', level: 1000);
  }

  void logWarn(String message) {
    if (isDebug) {
      debugPrint('AVISO: $message');
      return;
    }
    developer.log(message, name: 'AppLogger', level: 900);
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final logger = AppLogger(isDebug: kDebugMode);

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Controle do App Logger',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text('Controle do App Logger')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton.icon(
                onPressed: () {
                  logger.logInfo(
                    'O usuário iniciou um registro de informação.',
                  );
                },
                icon: const Icon(Icons.info_outline),
                label: const Text('Registrar Mensagem de Informação'),
              ),
              const SizedBox(height: 16.0),
              ElevatedButton.icon(
                onPressed: () {
                  logger.logWarn('Um problema potencial foi detectado.');
                },
                icon: const Icon(Icons.warning_amber),
                label: const Text('Registrar Mensagem de Aviso'),
              ),
              const SizedBox(height: 16.0),
              ElevatedButton.icon(
                onPressed: () {
                  logger.logError('Ocorreu um erro crítico!');
                },
                icon: const Icon(Icons.error_outline),
                label: const Text('Registrar Mensagem de Erro'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.red,
                  foregroundColor: Colors.white,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(const MyApp());
}
Enter fullscreen mode Exit fullscreen mode

App após clicar nos botões:

Referências

https://pub.dev/documentation/logging/latest/logging/Level-class.html

Top comments (0)