Guia Detalhado de Logging
Vamos aprofundar nossas práticas de logging, utilizando o contexto do recurso de "Solicitação de Feedback" para tornar o aprendizado mais prático e relevante. Este guia tem como objetivo detalhar como aplicar as melhores práticas de logging em cada etapa do fluxo, desde a criação da solicitação até a aprovação e envio aos avaliadores.
Por Que Logging é Crucial? 🤔
Em um sistema distribuído como o nosso, o logging é essencial para:
- Debug e Troubleshooting: Identificar e corrigir erros rapidamente.
- Monitoramento da Aplicação: Acompanhar o desempenho e a saúde do sistema.
- Análise de Negócios: Extrair insights sobre o comportamento dos usuários e o uso dos recursos.
- Auditoria: Rastrear eventos importantes para fins de segurança e conformidade.
Estratégias Gerais de Logging 📝
- Logging Estruturado: Utilize um formato consistente (preferencialmente JSON) para facilitar a análise e a filtragem dos logs.
- Níveis de Log Apropriados: Utilize os níveis DEBUG, INFO, WARN e ERROR de acordo com a severidade do evento.
- Contexto Rico: Inclua informações relevantes no log, como:
transactionId: Para rastrear a solicitação de feedback em todo o fluxo.userId: ID do colaborador que criou a solicitação.pdmId: ID do PDM que aprovou/rejeitou a solicitação.feedbackRequestId: ID da solicitação de feedback.
- Logs de Eventos de Negócio: Registre eventos importantes do ponto de vista do negócio para gerar KPIs e métricas.
- Privacidade: Evite logar informações sensíveis (ex: senhas, dados de cartão de crédito).
- Performance: Logs excessivos podem impactar o desempenho. Seja estratégico ao escolher o que logar e em qual nível.
Logging em Ação: Solicitação de Feedback 🚀
Vamos detalhar como aplicar o logging em cada etapa do fluxo de "Solicitação de Feedback".
1. Criação da Solicitação (Colaborador)
- Ação: Colaborador acessa a tela de listagem de solicitações de feedback.
INFO: "Usuário acessou a tela de listagem de solicitações de feedback",userId,transactionId
- Ação: Colaborador clica no botão "Nova Solicitação".
INFO: "Usuário iniciou a criação de uma nova solicitação de feedback",userId,transactionId
- Ação: Colaborador preenche o formulário.
DEBUG: (Se necessário) Log das perguntas personalizadas inseridas pelo colaborador (com cuidado para não logar informações sensíveis).
- Ação: Colaborador adiciona avaliadores (nome e e-mail).
DEBUG: (Se necessário) Log dos avaliadores adicionados (com cuidado para não logar informações sensíveis).WARN: Se o e-mail do avaliador for da CI&T, logar: "Tentativa de adicionar avaliador com email da CI&T",userId,transactionId,emailAvaliador
- Ação: Colaborador clica no botão "Salvar Solicitação".
INFO: "Usuário salvou a solicitação de feedback",userId,feedbackRequestId,transactionIdERROR: Se ocorrer um erro ao salvar a solicitação (ex: falha no banco de dados), logar: "Falha ao salvar a solicitação de feedback",userId,transactionId,erro,stackTrace
2. Notificação ao PDM
- Ação: Sistema envia email de notificação ao PDM.
INFO: "Email de notificação enviado ao PDM",pdmId,feedbackRequestId,transactionIdERROR: Se ocorrer um erro ao enviar o email, logar: "Falha ao enviar email de notificação ao PDM",pdmId,feedbackRequestId,transactionId,erro,stackTrace
3. Aprovação/Rejeição do PDM
- Ação: PDM acessa a tela de listagem de feedbacks a aprovar.
INFO: "PDM acessou a tela de listagem de solicitações de feedback a aprovar",pdmId,transactionId
- Ação: PDM aprova ou rejeita a solicitação.
INFO: "PDM aprovou a solicitação de feedback",pdmId,feedbackRequestId,transactionIdINFO: "PDM rejeitou a solicitação de feedback",pdmId,feedbackRequestId,transactionId,comentarios(comentários do PDM)ERROR: Se ocorrer um erro ao aprovar/rejeitar a solicitação, logar: "Falha ao aprovar/rejeitar a solicitação de feedback",pdmId,feedbackRequestId,transactionId,erro,stackTrace
4. Envio de Email aos Avaliadores (Se Aprovado)
- Ação: Sistema envia email aos avaliadores.
INFO: "Email de solicitação de feedback enviado aos avaliadores",feedbackRequestId,numeroAvaliadores,transactionIdERROR: Se ocorrer um erro ao enviar o email, logar: "Falha ao enviar email de solicitação de feedback aos avaliadores",feedbackRequestId,transactionId,erro,stackTrace
5. Edição da Solicitação (Se Rejeitado)
- Ação: Colaborador edita a solicitação rejeitada.
INFO: "Colaborador iniciou a edição da solicitação de feedback rejeitada",userId,feedbackRequestId,transactionId
- Ação: Colaborador salva a solicitação editada.
INFO: "Colaborador salvou a solicitação de feedback editada",userId,feedbackRequestId,transactionId
Exemplo de Logs Estruturados (JSON) 📊
Aqui estão alguns exemplos de como os logs estruturados em JSON poderiam se parecer:
{
"timestamp": "2024-10-27T10:00:00.000Z",
"level": "INFO",
"message": "Usuário acessou a tela de listagem de solicitações de feedback",
"userId": "user123",
"transactionId": "txn456"
}
{
"timestamp": "2024-10-27T10:05:00.000Z",
"level": "WARN",
"message": "Tentativa de adicionar avaliador com email da CI&T",
"userId": "user123",
"transactionId": "txn456",
"emailAvaliador": "email@ciandt.com"
}
{
"timestamp": "2024-10-27T10:10:00.000Z",
"level": "ERROR",
"message": "Falha ao salvar a solicitação de feedback",
"userId": "user123",
"feedbackRequestId": "fbq789",
"transactionId": "txn456",
"erro": "Erro de conexão com o banco de dados",
"stackTrace": "..."
}
Exemplo de Logs Estruturados com Lombok (Spring Boot) 🛠️
Para simplificar a criação de logs estruturados no Spring Boot, podemos usar o Lombok para gerar automaticamente o logger:
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.Map;
@Service
@Slf4j // Gera automaticamente o logger
public class FeedbackService {
public void criarSolicitacao(String userId) {
UUID transactionId = UUID.randomUUID();
log.info("Usuário iniciou a criação de uma nova solicitação de feedback", Map.of(
"userId", userId,
"transactionId", transactionId
));
// ...
}
public void notificarPdm(String pdmId, String feedbackRequestId) {
UUID transactionId = UUID.randomUUID();
log.info("Email de notificação enviado ao PDM", Map.of(
"pdmId", pdmId,
"feedbackRequestId", feedbackRequestId,
"transactionId", transactionId
));
// ...
}
public void adicionarAvaliador(String userId, String emailAvaliador) {
if (emailAvaliador.contains("@ciandt.com")) {
UUID transactionId = UUID.randomUUID();
log.warn("Tentativa de adicionar avaliador com email da CI&T", Map.of(
"userId", userId,
"transactionId", transactionId,
"emailAvaliador", emailAvaliador
));
throw new IllegalArgumentException("Não é possível adicionar avaliadores com email da CI&T");
}
}
}
Monitoramento e Métricas 📈
Com os logs estruturados, podemos monitorar a aplicação e extrair métricas importantes:
- Número de solicitações de feedback criadas por dia/semana/mês.
- Tempo médio para o PDM aprovar/rejeitar uma solicitação.
- Número de emails enviados aos avaliadores.
- Número de erros ao salvar solicitações.
Ferramentas e Tecnologias 🛠️
- Spring Boot: Utilize o
SLF4JeLogbackpara logging estruturado. Use Lombok para simplificar a criação do logger. - FastAPI: Utilize o módulo
loggingdo Python e configure um handler para formatar os logs em JSON. - ELK Stack (Elasticsearch, Logstash, Kibana) ou Grafana Loki: Para coleta, armazenamento e análise dos logs.
Enviando Logs para o Grafana Loki 📤
O Grafana Loki é uma excelente opção para centralizar e analisar seus logs. Para enviar seus logs para o Loki, você precisa configurar um "appender" (no caso do Logback) ou um handler (no caso do Python) que formata os logs no formato esperado pelo Loki e os envia para o servidor.
- Formatando os Logs: O Loki espera os logs em um formato específico, geralmente com um timestamp e um rótulo (label) que identifica a fonte do log.
- Configurando Appenders/Handlers:
- Logback (Spring Boot): Você pode usar um appender como o
Loki4jAppenderpara enviar os logs diretamente para o Loki. - Python: Você pode criar um handler customizado que formata os logs e os envia para a API do Loki.
- Logback (Spring Boot): Você pode usar um appender como o
Exemplo de Configuração do Logback para Loki:
-
Adicione a dependência do
Loki4jAppenderao seu projeto:<dependency> <groupId>com.github.loki4j</groupId> <artifactId>loki4j-logback-appender</artifactId> <version>1.5</version> </dependency> -
Configure o
logback.xml:<configuration> <appender name="Loki" class="com.github.loki4j.logback.Loki4jAppender"> <url>http://localhost:3100/loki/api/v1/push</url> <!-- Substitua pela URL do seu Loki --> <format class="com.github.loki4j.logback.JsonFormatter"> <jsonLayout> <pattern> { "timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSSZ}", "level": "%level", "message": "%message", "logger": "%logger", "thread": "%thread", "transactionId": "%mdc{transactionId}", <!-- Se você usa MDC --> "userId": "%mdc{userId}" <!-- Se você usa MDC --> } </pattern> </jsonLayout> </format> <label class="com.github.loki4j.logback.StaticLabelProvider"> <label> <name>app</name> <value>feedback-service</value> <!-- Nome da sua aplicação --> </label> </label> </appender> <root level="INFO"> <appender-ref ref="Loki"/> </root> </configuration>
Criando Appenders/Handlers Customizados:
Se as opções existentes não atenderem às suas necessidades, você pode criar seus próprios appenders/handlers para formatar e enviar os logs para o Loki ou qualquer outra ferramenta de análise.
Conclusão 🎉
Espero que este guia detalhado ajude vocês a implementar um sistema de logging robusto e eficiente no recurso de "Solicitação de Feedback". Lembrem-se que o logging é uma habilidade essencial para qualquer desenvolvedor e que a prática leva à perfeição.
Se tiverem dúvidas ou sugestões, não hesitem em compartilhar! Estamos juntos nessa jornada. 💪