Agent Skills: Logging Backend - Wide Events

Implementa Wide Events (Canonical Log Lines) para logging backend estructurado. Se activa cuando el usuario dice "agregar logging", "add logging", "mejorar logs", "improve logs", "wide events", "observabilidad", "observability", "canonical log lines", "structured logging", o necesita logs estructurados en un backend Node.js/Java.

UncategorizedID: testacode/llm-toolkit/logging-backend

Install this agent skill to your local

pnpm dlx add-skill https://github.com/testacode/llm-toolkit/tree/HEAD/skills/logging-backend

Skill Files

Browse the full folder contents for logging-backend.

Download Skill

Loading file tree…

skills/logging-backend/SKILL.md

Skill Metadata

Name
logging-backend
Description
Implementa Wide Events (Canonical Log Lines) para logging backend estructurado. Se activa cuando el usuario dice "agregar logging", "add logging", "mejorar logs", "improve logs", "wide events", "observabilidad", "observability", "canonical log lines", "structured logging", o necesita logs estructurados en un backend Node.js/Java.

Logging Backend - Wide Events

Implementa Wide Events (tambien conocidos como Canonical Log Lines): un evento estructurado por request que contiene TODO el contexto relevante en un solo registro.

Concepto Core

Un Wide Event es un unico log JSON que captura el ciclo completo de un request. En lugar de multiples logs dispersos ("user logged in", "fetched data", "returned response"), emitir UN evento al final con toda la informacion agregada.

Beneficios:

  • Debuggear con UN query en vez de correlacionar multiples logs
  • Analisis con SQL simple sobre campos estructurados
  • Sin perdida de contexto entre logs
  • Tail sampling efectivo (solo guardar eventos interesantes)

Comparacion: Log tradicional vs Wide Event:

// Log tradicional - multiples lineas dispersas
[10:30:00] INFO: User 789 logged in
[10:30:01] INFO: Fetching orders for user 789
[10:30:02] DEBUG: Query executed in 45ms
[10:30:02] INFO: Found 3 orders
[10:30:03] ERROR: Failed to send email notification

// Wide Event - todo en un solo registro
{
  "timestamp": "2024-01-15T10:30:03.000Z",
  "user": { "id": "789" },
  "action": "fetch_orders",
  "result": { "count": 3 },
  "infra": { "db_time_ms": 45 },
  "error": { "type": "email_failed", "message": "SMTP timeout" }
}

Estructura de un Wide Event

{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "level": "info",
  "service": "api-gateway",
  "trace_id": "abc123",

  "request": { "method": "POST", "path": "/api/orders", "duration_ms": 245 },
  "user": { "id": "user_789", "plan": "premium" },
  "business": { "order_id": "ord_456", "total": 150.00, "items_count": 3 },
  "infra": { "db_queries": 4, "db_time_ms": 120, "cache_hits": 2 },
  "error": null
}

Ver references/wide-event-schema.md para esquema completo con todos los campos recomendados.

Workflow de Implementacion

Fase 1: Middleware Base

  1. Crear middleware que inicializa el wide event al inicio del request
  2. Adjuntar el evento al contexto (req.wideEvent, AsyncLocalStorage, etc.)
  3. Emitir el log al finalizar el request

Ver references/implementation.md para codigo del middleware.

Fase 2: Enriquecimiento

  1. En cada handler/service, agregar campos al wide event
  2. Usar helpers tipados: enrichUser(), enrichBusiness(), enrichError()
  3. Acumular metricas: queries, cache hits, llamadas externas

Fase 3: Tail Sampling

  1. Implementar funcion de sampling que decide que loggear
  2. Siempre loggear: errores, latencia alta, usuarios especificos
  3. Samplear porcentaje de requests exitosos normales

Ver references/implementation.md para funcion de tail sampling.

Fase 4: Colorizacion (Desarrollo)

  1. Configurar colores por nivel (ERROR=rojo, WARN=amarillo)
  2. Configurar colores por contexto (Request=azul, User=verde)
  3. Formatear output legible en terminal

Ver references/colorization.md para configuracion de colores.

Checklist Rapido

  • [ ] Middleware que crea wide event por request
  • [ ] Contexto accesible en toda la cadena (AsyncLocalStorage / req)
  • [ ] Campos request: method, path, status, duration_ms
  • [ ] Campos user: id, plan, roles (si aplica)
  • [ ] Campos business: entidades del dominio
  • [ ] Campos infra: db_queries, cache_hits, external_calls
  • [ ] Campos error: code, message, stack (si hay error)
  • [ ] Tail sampling configurado
  • [ ] Formato JSON en prod, coloreado en dev

Anti-patrones

Ver references/anti-patterns.md para errores comunes:

  • Confundir structured logging con wide events
  • Depender solo de OpenTelemetry
  • Loggear multiples veces por request
  • No incluir contexto de negocio

Referencias

  • references/wide-event-schema.md - Esquema JSON completo con todos los campos
  • references/implementation.md - Codigo de middleware y helpers
  • references/anti-patterns.md - Que NO hacer
  • references/colorization.md - Configuracion de colores para dev

Troubleshooting

El wide event no captura datos del usuario

Sintoma: user: null en todos los logs

Causa comun: El middleware de auth corre despues del wide event middleware.

Solucion:

// Orden incorrecto
app.use(wideEventMiddleware('my-service'));
app.use(authMiddleware); // user no disponible cuando se crea el evento

// Orden correcto
app.use(authMiddleware);
app.use(wideEventMiddleware('my-service')); // user ya esta en req

Los logs salen vacios en infra.db

Sintoma: db: { queries_count: 0, total_time_ms: 0 }

Causa comun: No se estan usando los helpers de tracking.

Solucion: Wrappear las queries:

const query = async (sql: string) => {
  const start = Date.now();
  const result = await db.query(sql);
  trackDbQuery(Date.now() - start);
  return result;
};

Logs demasiado grandes en produccion

Sintoma: Costos altos de almacenamiento/ingesta

Solucion: Implementar tail sampling agresivo:

const shouldLog = (event: WideEvent): boolean => {
  if (event.level === 'error') return true;
  if (event.request.duration_ms > 1000) return true;
  return Math.random() < 0.01; // Solo 1% del resto
};

No puedo correlacionar logs entre servicios

Sintoma: Cada servicio tiene su propio trace_id

Causa: No se esta propagando el header.

Solucion: Ver references/implementation.md seccion "Propagacion Cross-Service".

Lecturas Recomendadas