Dinaup.Logs (Logging)
¿Por qué Dinaup.Logs?
Dinaup.Logs nace de la necesidad de centralizar y estandarizar los registros de la plataforma Dinaup, aportando:
Trazabilidad completa de cada request y proceso.
Métricas automáticas para detectar cuellos de botella.
ElasticSearch como backend opcional para búsquedas y paneles en tiempo real.
Inicialización
Se recomienda inicializar Dinaup.Logs una vez al comienzo de la aplicación (por ejemplo, en Program.cs
o en la rutina de arranque). Para ello, utiliza el método estático Logs.Initialize(...)
, proporcionando parámetros clave como el nombre y versión de la aplicación, la configuración de Elasticsearch (si se utiliza), la ruta del archivo de log, el entorno de ejecución y la opción autoExportContextMetric
. Por ejemplo:
using Dinaup.Logs;
var elastic = new Logs.ElasticConfig("https://elastic.xxx.xxx", "xxxxx");
Logs.Initialize(
applicationName: "XXXX",
applicationVersion: "1.0.0",
elasticConfig: elastic,
logFilePath: "logs/log.txt",
environment: Env.IsDevelopment() ? "Debug" : "Release",
autoExportContextMetric: false
);
Niveles y formato de logging
Dinaup.Logs envuelve Serilog, así que dispones de los niveles clásicos (Verbose
, Debug
, Information
, Warning
, Error
, Fatal
).
Logs.Information("Usuario {UserId} inició sesión", userId);
Logs.Warning("Balance negativo detectado: {Balance}", balance);
Cambia el nivel global en caliente si lo necesitas:
Logs.SetLoggingLevel(LogEventLevel.Debug);
Contextos enriquecidos
Los contextos añaden metadatos automáticos a cada mensaje sin esfuerzo:
5.1 BeginContext
BeginContext
Agrupa los logs de un proceso concreto y opcionalmente incrementa un contador.
Recomendación clave: pasa siempre los parámetros usando nameof(MiClase)
y nameof(MiMétodo)
en lugar de magic strings. De este modo tu código es refactoring‑safe: si cambias el nombre de la clase o del método, el compilador lo detectará inmediatamente.
public class PagosService
{
public void GenerarFactura()
{
using (Logs.BeginContext(nameof(PagosService), nameof(GenerarFactura)))
{
Logs.Debug("Preparando borrador de factura");
// ... tu lógica aquí
}
}
}
5.2 BeginCorrelationContext
BeginCorrelationContext
Ideal para flujos distribuidos: incluye un CorrelationId
que viaja por microservicios.
var correlationId = Guid.NewGuid().ToString();
using (Logs.BeginCorrelationContext(nameof(PagosService), nameof(GenerarFactura), correlationId))
{
...
}
Métricas integradas
Cuando activas autoExportContextMetric
, cada llamada a BeginContext
incrementa un CounterMetric etiquetado con component
y action
.
Crear contadores manuales:
static CounterMetric pagosOk = new CounterMetric("pagos_ok", "hit", 0, new() {{"status", "ok"}});
...
pagosOk.Increment();
Estas métricas se envían a Elastic Search.
Helpers HandleAction
y HandleActionAsync
HandleAction
y HandleActionAsync
Envuelven código en un bloque try/catch con cronómetro incorporado y logean éxito o excepción.
var resultado = Logs.HandleAction(nameof(PagosService), nameof(Cobrar), () =>
{
/// ...
}, new { pedido.Id, pedido.Total });
if (!resultado.IsOk) return Results.BadRequest(resultado.MessageException);
Versión asíncrona:
await Logs.HandleActionAsync(nameof(EmailService), nameof(EnviarFactura), async () =>
{
await emailSender.SendAsync(...);
});
Buenas prácticas
No silencies excepciones: si atrapas una, logéala con
Error
y vuelve a lanzarla o maneja el resultado.Evita logs sensibles (tokens, contraseñas). Usa propiedades parametrizadas.
Cierra al apagar la app:
Logs.CloseAndFlush();
Última actualización