Pular para conteúdo

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 📝

  1. Logging Estruturado: Utilize um formato consistente (preferencialmente JSON) para facilitar a análise e a filtragem dos logs.
  2. Níveis de Log Apropriados: Utilize os níveis DEBUG, INFO, WARN e ERROR de acordo com a severidade do evento.
  3. 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.
  4. Logs de Eventos de Negócio: Registre eventos importantes do ponto de vista do negócio para gerar KPIs e métricas.
  5. Privacidade: Evite logar informações sensíveis (ex: senhas, dados de cartão de crédito).
  6. 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, transactionId
    • ERROR: 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, transactionId
    • ERROR: 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, transactionId
    • INFO: "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, transactionId
    • ERROR: 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 SLF4J e Logback para logging estruturado. Use Lombok para simplificar a criação do logger.
  • FastAPI: Utilize o módulo logging do 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.

  1. 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.
  2. Configurando Appenders/Handlers:
    • Logback (Spring Boot): Você pode usar um appender como o Loki4jAppender para 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.

Exemplo de Configuração do Logback para Loki:

  1. Adicione a dependência do Loki4jAppender ao seu projeto:

    <dependency>
        <groupId>com.github.loki4j</groupId>
        <artifactId>loki4j-logback-appender</artifactId>
        <version>1.5</version>
    </dependency>
    
  2. 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. 💪