Este guia tem como objetivo fornecer insights e práticas fundamentais para garantir que você possa monitorar e solucionar problemas de seus serviços com mais eficiência. No desenvolvimento de aplicativos, o registro em log é frequentemente esquecido, mas é um componente crucial na construção de um sistema robusto e observável. Práticas adequadas de registro em log podem aumentar a visibilidade do seu aplicativo, aprofundar sua compreensão de seu funcionamento interno e melhorar a integridade geral do aplicativo. Registro padrão Incorporar mecanismos de registro padrão nos pontos de entrada do seu aplicativo é altamente benéfico. Esse registro automático pode capturar interações essenciais e potencialmente incluir os argumentos do ponto de entrada. No entanto, é crucial ter cuidado, pois o registro de informações confidenciais, como senhas, pode representar riscos de privacidade e segurança. Pontos de entrada comuns : registre detalhes sobre solicitações e respostas recebidas Endpoints de API : registre pontos de início do trabalho, detalhes de execução e resultados Trabalhos em segundo plano : registre o tratamento de eventos assíncronos e interações relacionadas Eventos assíncronos Registro abrangente Cada ação significativa executada pelo seu aplicativo deve produzir uma entrada de log, especialmente aquelas ações que alteram seu estado. Essa abordagem exaustiva de registro em log é fundamental para identificar e resolver rapidamente os problemas quando eles surgirem, oferecendo uma visão transparente da integridade e da funcionalidade do seu aplicativo. Essa diligência no registro garante diagnóstico e manutenção mais fáceis. Escolhendo o nível de registro apropriado Adotar níveis de log apropriados é crucial para gerenciar e interpretar a grande quantidade de dados gerados pela sua aplicação. Ao categorizar os registros com base em sua gravidade e relevância, você garante que problemas críticos sejam prontamente identificados e resolvidos, enquanto informações menos urgentes permanecem acessíveis sem sobrecarregar seus esforços de monitoramento. Abaixo está uma diretriz para utilizar os níveis de log de forma eficaz: Nível Descrição e exemplos Uso aceito Não aceito ERROR Eventos fatais que interrompem as operações do sistema. por exemplo, conexão perdida com o banco de dados Erros críticos do sistema Erros não críticos, como tentativas malsucedidas de login do usuário WARN Há um problema, mas o sistema pode continuar a execução e concluir a operação solicitada Questões potenciais que levam a problemas Mudanças de estado de rotina INFO Insights sobre funções normais do aplicativo, como criação de conta de usuário ou gravação de dados Mudanças de estado Operações somente leitura sem alterações DEBUG Informações detalhadas de diagnóstico, como início/fim do processo As etapas do processo de registro em log não alteram o estado do sistema Mudanças de estado de rotina ou operações de alta frequência TRACE O nível mais detalhado, incluindo entradas/saídas de métodos Compreender o fluxo e os detalhes de um processo Registrando informações confidenciais Quais IDs registrar – abordagem hierárquica Ao registrar ações em seu aplicativo, incluir os IDs das entidades diretamente envolvidas é crucial para vincular as informações de log aos dados do banco de dados. Uma abordagem hierárquica ajuda você a encontrar rapidamente todos os logs conectados a uma parte específica do seu aplicativo, vinculando itens aos seus grupos ou categorias principais. Por exemplo, em vez de registrar apenas o ID de um chat quando uma mensagem falha no envio, você também deve registrar os IDs da sala de chat e da empresa à qual ela pertence. Dessa forma, você ganha mais contexto e pode ver o impacto mais amplo do problema. Exemplo de entrada de registro: Failed to send the message - chat=$roomId, chatRoomId=chatRoomId, company=$companyId Exemplo de registros de produção Abaixo está um exemplo de como os logs de produção podem parecer ao usar a abordagem hierárquica: Consistência e Padronização Prefixos padrão A padronização dos formatos de log em todas as equipes pode tornar seus logs muito mais fáceis de ler e entender. Aqui estão alguns prefixos padronizados a serem considerados: fazer algo Começando a fazer algo Falha ao fazendo algo Concluiu fazer alguma coisa Deixei de fazer algo novamente Tente Registrar valores de variáveis separadamente Separar nomes e valores de variáveis do corpo das mensagens de log oferece diversas vantagens: facilita a filtragem e a localização de informações específicas Simplifica a pesquisa e análise de logs: mantém o processo de gravação de mensagens de log simples Simplifica a criação de mensagens de log: valores grandes não atrapalham a legibilidade da mensagem de log Evita confusão de mensagens: Exemplo de formato de registro: Log message - valueName=value Exemplos de registros que utilizam práticas propostas Exemplo Teórico Aqui estão exemplos de entradas de log bem estruturadas seguindo as práticas recomendadas discutidas: 2023-10-05 14:32:01 [INFO] Successful login attempt - userId=24543, teamId=1321312 2023-10-05 14:33:17 [WARN] Failed login attempt - userId=536435, teamId=1321312 Esses exemplos demonstram: : prefixos claros e consistentes como "Tentativa de login bem-sucedida" e "Tentativa de login com falha" tornam os logs fáceis de entender. Prefixos de log padronizados : os nomes e valores das variáveis são separados da mensagem de log, mantendo a clareza e simplificando as pesquisas. Valores de variáveis separados : o formato estruturado garante que os logs sejam fáceis de ler e analisar, auxiliando na solução de problemas e no monitoramento eficientes. Legibilidade e consistência Exemplo de registros de produção Abaixo está um exemplo de como os logs de produção podem parecer ao usar as práticas propostas: IDs de rastreamento Para associar efetivamente os logs a uma ação específica do usuário, é crucial incluir um ou como também é chamado de em seus logs. A ID deve permanecer consistente em todos os logs gerados pela lógica acionada por esse ponto de entrada, oferecendo uma visão clara da sequência de eventos. traceId correlationId Exemplo de implementação Embora alguns serviços de monitoramento como o Datadog forneçam agrupamento de logs prontos para uso, isso também pode ser implementado manualmente. Em um aplicativo Kotlin usando Spring, você pode implementar um ID de rastreamento para solicitações REST usando um HandlerInterceptor. @Component class TraceIdInterceptor : HandlerInterceptor { companion object { private const val TRACE_ID = "traceId" } override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean { val traceId = UUID.randomUUID().toString() MDC.put(TRACE_ID, traceId) return true } override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?) { MDC.remove(TRACE_ID) } } Este interceptor gera um exclusivo para cada solicitação, adicionando-o ao MDC no início da solicitação e removendo-o após a conclusão da solicitação. traceId Logs de exemplo com traceId A implementação dessa agregação de logs permitirá filtrar logs semelhantes ao exemplo abaixo Usando UUID versus IDs longos em logs Em muitos sistemas, as entidades podem usar ou IDs como identificadores primários, enquanto alguns sistemas podem usar ambos os tipos de IDs para finalidades diferentes. Compreender as implicações de cada tipo para fins de exploração madeireira é crucial para fazer uma escolha informada. UUID Long Aqui está uma análise do que deve ser considerado: IDs são mais fáceis de ler e consideravelmente mais curtos, especialmente se não estiverem no limite superior do alcance. Legibilidade: Long Long os IDs fornecem exclusividade em todo o sistema, permitindo pesquisar logs usando um ID sem enfrentar problemas de colisões de ID. Colisões aqui significam que há uma chance de que 2 entidades de tabelas de banco de dados não relacionadas tenham o mesmo ID . Valor exclusivo: UUID Long : em sistemas que usam chaves primárias longas como IDs de entidades, adicionar um ID aleatório geralmente é simples; em um sistema distribuído com IDs de entidade , pode ser desafiador ou caro ter IDs especificamente para registro. Limitações do sistema UUID UUID Long a consistência no tipo de IDs usados nos logs é crítica, pelo menos por entidade. Se o sistema já produz logs para algumas entidades e você não está pensando em alterar todos eles, é melhor ficar com o tipo já utilizado para identificar a entidade. O registro de ambos os IDs pode ser considerado durante um período de transição, mas ter vários IDs permanentemente sobrecarregará desnecessariamente os logs. Logs existentes: Conclusão Práticas adequadas de registro são essenciais para uma observabilidade eficaz do serviço. Ao incorporar registro abrangente, níveis de registro apropriados, IDs de rastreamento e formatos de registro padronizados, você pode aprimorar significativamente sua capacidade de monitorar e solucionar problemas de seus aplicativos. Essas práticas melhoram a clareza e a consistência dos seus logs, facilitando o diagnóstico e a resolução rápida de problemas. Obrigado por reservar um tempo para ler esta postagem!