Skip to content

Logging Estructurado

Beto Ramirez edited this page Aug 15, 2026 · 1 revision

Logging estructurado (Common/Logging)

Serilog reemplaza por completo al logging provider por defecto — todo ILogger<T> existente (incluido el de GlobalExceptionHandler) sigue funcionando igual, solo cambia quién procesa los logs.

  • Nivel y overrides por configuración: sección Serilog:MinimumLevel en appsettings.json (mismo patrón que Jwt/RateLimiting/Cors), vía Serilog.Settings.Configuration.
  • Sinks por entorno, decididos en código, no en configuración: consola en texto legible en Development, consola en JSON estructurado en el resto. Un sink real de producción (Seq, Elasticsearch, Application Insights, etc.) es un punto de extensión — agregarlo en Common/Logging/LoggingRegistration.cs.
  • Correlation ID por request: reusa el mismo HttpContext.TraceIdentifier que ya se expone como traceId en cada ProblemDetails de error (Common/ErrorHandling) — un solo ID conecta lo que ve el cliente con lo que aparece en los logs, sin generar un ID paralelo. UseCorrelationId() lo mete en el LogContext de Serilog (todo log dentro del request lo hereda) y lo devuelve como header X-Correlation-Id en cada respuesta.
  • Un log por request: UseAppRequestLogging() (envuelve UseSerilogRequestLogging()), excluyendo /health/* — un orquestador les pega cada pocos segundos y son ruido, no señal.

Detalle de implementación no obvio: AddSerilogLogging() usa preserveStaticLogger: true — necesario para que WebApplicationFactory pueda levantar varios hosts en paralelo en los tests sin que se pisen entre sí (el Log.Logger estático es compartido por proceso). El efecto colateral es que cualquier cosa que dependa del Log.Logger estático por default (como UseSerilogRequestLogging()) necesita el logger configurado pasado explícitamente — por eso existe UseAppRequestLogging() en vez de llamar a la extensión de Serilog directo.


Ver también: Manejo-Global-de-Errores · Health-Checks · Home

Clone this wiki locally