Guía Detallada de Logging
Vamos a profundizar en nuestras prácticas de logging, utilizando el contexto de la funcionalidad de "Solicitud de Feedback" para que el aprendizaje sea más práctico y relevante. Esta guía tiene como objetivo detallar cómo aplicar las mejores prácticas de logging en cada etapa del flujo, desde la creación de la solicitud hasta la aprobación y el envío a los evaluadores.
¿Por Qué el Logging es Crucial? 🤔
En un sistema distribuido como el nuestro, el logging es esencial para:
- Depuración y Solución de Problemas (Troubleshooting): Identificar y corregir errores rápidamente.
- Monitoreo de la Aplicación: Seguir el rendimiento y la salud del sistema.
- Análisis de Negocio: Extraer información valiosa sobre el comportamiento de los usuarios y el uso de las funcionalidades.
- Auditoría: Rastrear eventos importantes para fines de seguridad y cumplimiento.
Estrategias Generales de Logging 📝
- Logging Estructurado: Utilice un formato consistente (preferiblemente JSON) para facilitar el análisis y el filtrado de los logs.
- Niveles de Log Apropiados: Utilice los niveles DEBUG, INFO, WARN y ERROR según la severidad del evento.
- Contexto Enriquecido: Incluya información relevante en el log, como:
transactionId: Para rastrear la solicitud de feedback en todo el flujo.userId: ID del colaborador que creó la solicitud.pdmId: ID del PDM que aprobó/rechazó la solicitud.feedbackRequestId: ID de la solicitud de feedback.
- Logs de Eventos de Negocio: Registre eventos importantes desde el punto de vista del negocio para generar KPIs y métricas.
- Privacidad: Evite registrar información sensible (ej: contraseñas, datos de tarjetas de crédito).
- Rendimiento: Un exceso de logs puede afectar el rendimiento. Sea estratégico al elegir qué registrar y en qué nivel.
Logging en Acción: Solicitud de Feedback 🚀
Vamos a detallar cómo aplicar el logging en cada etapa del flujo de "Solicitud de Feedback".
1. Creación de la Solicitud (Colaborador)
- Acción: El colaborador accede a la pantalla de listado de solicitudes de feedback.
INFO: "Usuario accedió a la pantalla de listado de solicitudes de feedback",userId,transactionId
- Acción: El colaborador hace clic en el botón "Nueva Solicitud".
INFO: "Usuario inició la creación de una nueva solicitud de feedback",userId,transactionId
- Acción: El colaborador llena el formulario.
DEBUG: (Si es necesario) Registrar las preguntas personalizadas ingresadas por el colaborador (con cuidado de no registrar información sensible).
- Acción: El colaborador agrega evaluadores (nombre y correo electrónico).
DEBUG: (Si es necesario) Registrar los evaluadores agregados (con cuidado de no registrar información sensible).WARN: Si el correo del evaluador es de CI&T, registrar: "Intento de agregar evaluador con correo de CI&T",userId,transactionId,emailEvaluador
- Acción: El colaborador hace clic en el botón "Guardar Solicitud".
INFO: "Usuario guardó la solicitud de feedback",userId,feedbackRequestId,transactionIdERROR: Si ocurre un error al guardar la solicitud (ej: fallo en la base de datos), registrar: "Fallo al guardar la solicitud de feedback",userId,transactionId,error,stackTrace
2. Notificación al PDM
- Acción: El sistema envía un correo de notificación al PDM.
INFO: "Correo de notificación enviado al PDM",pdmId,feedbackRequestId,transactionIdERROR: Si ocurre un error al enviar el correo, registrar: "Fallo al enviar correo de notificación al PDM",pdmId,feedbackRequestId,transactionId,error,stackTrace
3. Aprobación/Rechazo del PDM
- Acción: El PDM accede a la pantalla de listado de feedbacks por aprobar.
INFO: "PDM accedió a la pantalla de listado de solicitudes de feedback por aprobar",pdmId,transactionId
- Acción: El PDM aprueba o rechaza la solicitud.
INFO: "PDM aprobó la solicitud de feedback",pdmId,feedbackRequestId,transactionIdINFO: "PDM rechazó la solicitud de feedback",pdmId,feedbackRequestId,transactionId,comentarios(comentarios del PDM)ERROR: Si ocurre un error al aprobar/rechazar la solicitud, registrar: "Fallo al aprobar/rechazar la solicitud de feedback",pdmId,feedbackRequestId,transactionId,error,stackTrace
4. Envío de Correo a los Evaluadores (Si se aprueba)
- Acción: El sistema envía un correo a los evaluadores.
INFO: "Correo de solicitud de feedback enviado a los evaluadores",feedbackRequestId,numeroEvaluadores,transactionIdERROR: Si ocurre un error al enviar el correo, registrar: "Fallo al enviar correo de solicitud de feedback a los evaluadores",feedbackRequestId,transactionId,error,stackTrace
5. Edición de la Solicitud (Si se rechaza)
- Acción: El colaborador edita la solicitud rechazada.
INFO: "Colaborador inició la edición de la solicitud de feedback rechazada",userId,feedbackRequestId,transactionId
- Acción: El colaborador guarda la solicitud editada.
INFO: "Colaborador guardó la solicitud de feedback editada",userId,feedbackRequestId,transactionId
Ejemplo de Logs Estructurados (JSON) 📊
Aquí hay algunos ejemplos de cómo se verían los logs estructurados en JSON:
{
"timestamp": "2024-10-27T10:00:00.000Z",
"level": "INFO",
"message": "Usuario accedió a la pantalla de listado de solicitudes de feedback",
"userId": "user123",
"transactionId": "txn456"
}
{
"timestamp": "2024-10-27T10:05:00.000Z",
"level": "WARN",
"message": "Intento de agregar evaluador con correo de CI&T",
"userId": "user123",
"transactionId": "txn456",
"emailEvaluador": "email@ciandt.com"
}
{
"timestamp": "2024-10-27T10:10:00.000Z",
"level": "ERROR",
"message": "Fallo al guardar la solicitud de feedback",
"userId": "user123",
"feedbackRequestId": "fbq789",
"transactionId": "txn456",
"error": "Error de conexión con la base de datos",
"stackTrace": "..."
}
Ejemplo de Logs Estructurados con Lombok (Spring Boot) 🛠️
Para simplificar la creación de logs estructurados en Spring Boot, podemos usar Lombok para generar automáticamente el logger:
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.Map;
@Service
@Slf4j // Genera automáticamente el logger
public class FeedbackService {
public void crearSolicitud(String userId) {
UUID transactionId = UUID.randomUUID();
log.info("Usuario inició la creación de una nueva solicitud de feedback", Map.of(
"userId", userId,
"transactionId", transactionId
));
// ...
}
public void notificarPdm(String pdmId, String feedbackRequestId) {
UUID transactionId = UUID.randomUUID();
log.info("Correo de notificación enviado al PDM", Map.of(
"pdmId", pdmId,
"feedbackRequestId", feedbackRequestId,
"transactionId", transactionId
));
// ...
}
public void agregarEvaluador(String userId, String emailEvaluador) {
if (emailEvaluador.contains("@ciandt.com")) {
UUID transactionId = UUID.randomUUID();
log.warn("Intento de agregar evaluador con correo de CI&T", Map.of(
"userId", userId,
"transactionId", transactionId,
"emailEvaluador", emailEvaluador
));
throw new IllegalArgumentException("No es posible agregar evaluadores con correo de CI&T");
}
}
}
Monitoreo y Métricas 📈
Con los logs estructurados, podemos monitorear la aplicación y extraer métricas importantes:
- Número de solicitudes de feedback creadas por día/semana/mes.
- Tiempo promedio para que el PDM apruebe/rechace una solicitud.
- Número de correos enviados a los evaluadores.
- Número de errores al guardar solicitudes.
Herramientas y Tecnologías 🛠️
- Spring Boot: Utilice
SLF4JyLogbackpara logging estructurado. Use Lombok para simplificar la creación del logger. - FastAPI: Utilice el módulo
loggingde Python y configure un handler para formatear los logs en JSON. - ELK Stack (Elasticsearch, Logstash, Kibana) o Grafana Loki: Para la recolección, almacenamiento y análisis de los logs.
Enviando Logs a Grafana Loki 📤
Grafana Loki es una excelente opción para centralizar y analizar sus logs. Para enviar sus logs a Loki, necesita configurar un "appender" (en el caso de Logback) o un "handler" (en el caso de Python) que formatee los logs en el formato esperado por Loki y los envíe al servidor.
- Formateando los Logs: Loki espera los logs en un formato específico, generalmente con una marca de tiempo (timestamp) y una etiqueta (label) que identifica la fuente del log.
- Configurando Appenders/Handlers:
- Logback (Spring Boot): Puede usar un appender como
Loki4jAppenderpara enviar los logs directamente a Loki. - Python: Puede crear un handler personalizado que formatee los logs y los envíe a la API de Loki.
- Logback (Spring Boot): Puede usar un appender como
Ejemplo de Configuración de Logback para Loki:
-
Agregue la dependencia de
Loki4jAppendera su proyecto:<dependency> <groupId>com.github.loki4j</groupId> <artifactId>loki4j-logback-appender</artifactId> <version>1.5</version> </dependency> -
Configure el
logback.xml:<configuration> <appender name="Loki" class="com.github.loki4j.logback.Loki4jAppender"> <url>http://localhost:3100/loki/api/v1/push</url> <!-- Reemplace con la URL de su 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}", <!-- Si usa MDC --> "userId": "%mdc{userId}" <!-- Si usa MDC --> } </pattern> </jsonLayout> </format> <label class="com.github.loki4j.logback.StaticLabelProvider"> <label> <name>app</name> <value>feedback-service</value> <!-- Nombre de su aplicación --> </label> </label> </appender> <root level="INFO"> <appender-ref ref="Loki"/> </root> </configuration>
Creando Appenders/Handlers Personalizados:
Si las opciones existentes no satisfacen sus necesidades, puede crear sus propios appenders/handlers para formatear y enviar los logs a Loki o a cualquier otra herramienta de análisis.
Conclusión 🎉
Espero que esta guía detallada les ayude a implementar un sistema de logging robusto y eficiente en la funcionalidad de "Solicitud de Feedback". Recuerden que el logging es una habilidad esencial para cualquier desarrollador y que la práctica lleva a la perfección.
Si tienen dudas o sugerencias, ¡no duden en compartirlas! Estamos juntos en este viaje. 💪