Overview
La librería CodeDesignPlus.Net.Logger proporciona un marco robusto para la gestión centralizada de logs en aplicaciones .NET Core, utilizando Serilog como motor principal y ofreciendo la capacidad de exportar logs a OpenTelemetry (OTel) para un análisis más profundo. Esta librería facilita la configuración de logs enriquecidos con información contextual, mejorando la capacidad de depuración y monitoreo de aplicaciones.
Propósito y alcance
El objetivo principal de CodeDesignPlus.Net.Logger
es simplificar la configuración y gestión de logs en aplicaciones .NET Core. Permite a los desarrolladores configurar fácilmente Serilog con enriquecimientos predefinidos, como el nombre de la aplicación, el entorno, el nombre del usuario, entre otros. Además, ofrece la flexibilidad de enviar estos logs a un sistema de telemetría como OTel, facilitando el análisis y la observación del comportamiento de la aplicación.
Principales características
- Integración con Serilog: Utiliza Serilog como motor principal para logs, proporcionando todas sus capacidades y flexibilidad.
- Enriquecimiento de logs: Agrega automáticamente información contextual a los logs, como el nombre de la aplicación, la máquina, el ID del proceso, etc.
- Exportación a OpenTelemetry (OTel): Facilita la exportación de logs a un colector OTel, si está configurado, para análisis y monitoreo avanzados.
- Configuración simplificada: Ofrece métodos de extensión para configurar los logs fácilmente en
IServiceCollection
eIHostBuilder
. - Personalización: Permite la configuración personalizada de Serilog mediante acciones adicionales.
- Detección de errores: Incluye destructores personalizados para excepciones de base de datos.
Casos de uso típicos
- Centralización de logs en aplicaciones distribuidas.
- Monitoreo y análisis de rendimiento de microservicios.
- Depuración y diagnóstico de problemas en aplicaciones .NET Core.
- Estandarización del formato de logs en múltiples proyectos.
- Integración de logs con herramientas de observabilidad (e.g., Prometheus, Grafana).
Componentes Principales
ServiceCollectionExtension
: Clase con métodos de extensión para configurar el logging enIServiceCollection
.AddLogger
: Método de extensión que agrega los servicios de logging y las opciones de configuración aIServiceCollection
.UseSerilog
: Método de extensión que configura Serilog para elIHostBuilder
.LoggerOptions
: Clase que representa las opciones de configuración del logger, incluyendo la configuración de OTel.Exceptions.LoggerException
: Excepción que se lanza cuando la configuración del logger no es válida.
Directorysrc
DirectoryCodeDesignPlus.Net.Logger
DirectoryExceptions
- LoggerException.cs
DirectoryExtensions
- ServiceCollectionExtension.cs
DirectoryOptions
- LoggerOptions.cs
Primeros Pasos
En esta sección, aprenderás a instalar y configurar la librería CodeDesignPlus.Net.Logger
en tu proyecto de .NET.
Requisitos previos
- .NET 8 o superior.
- Un IDE compatible con .NET (Visual Studio, Visual Studio Code, etc.)
- Conocimiento básico de desarrollo en .NET Core.
- Una instancia de OTel si se desea exportar los logs.
Instalación
Para instalar la librería CodeDesignPlus.Net.Logger
, puedes utilizar el administrador de paquetes NuGet o la CLI de .NET. A continuación, se muestra un ejemplo de cómo instalar la librería utilizando la CLI de .NET:
dotnet add package CodeDesignPlus.Net.Logger
Install-Package CodeDesignPlus.Net.Logger
<PackageReference Include="CodeDesignPlus.Net.Logger" Version="1.0.0" />
Ejemplo rápido
El ejemplo CodeDesignPlus.Net.Logger.Sample muestra cómo configurar el logger en una aplicación .NET Core. A continuación, se muestra un ejemplo de cómo configurar el logger en tu proyecto:
// See https://aka.ms/new-console-template for more information
using CodeDesignPlus.Net.Logger.Extensions;using CodeDesignPlus.Net.Logger.Sample;
var builder = Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); config.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); }) .ConfigureServices((context, services) => { services.AddLogging(); services.AddLogger(context.Configuration);
services.AddHostedService<FakeBackgroundService>(); }) .UseSerilog();
var host = builder.Build();
host.Run();
-
Agregar configuración en
appsettings.json
:{"Core": {"Business": "CodeDesignPlus","AppName": "sample-logger","Version": "v1","Description": "Sample of CodeDesignPlus.Net.Core","Contact": {"Name": "CodeDesignPlus","Email": "custom@outlook.com"}},"Logger": {"Enable": true,"OTelEndpoint": "http://localhost:4317"}} -
Ejecutar Docker Compose para levantar el contenedor de OTel:
services:otel-collector:image: otel/opentelemetry-collectorports:- "4317:4317"- "4318:4318"volumes:- ./settings/collector-config.yaml:/etc/otelcol/config.yamlrestart: always -
Creamos el servicio
FakeBackgroundService
que escribira logs cuando se inicie el programa.using System;namespace CodeDesignPlus.Net.Logger.Sample;public class FakeBackgroundService(ILogger<FakeBackgroundService> logger) : BackgroundService{protected override Task ExecuteAsync(CancellationToken stoppingToken){logger.LogInformation("The FakeBackgroundService is running.");return Task.CompletedTask;}} -
Regisrramos los servicios del log en el host
//....ConfigureServices((context, services) =>{services.AddLogging();services.AddLogger(context.Configuration);}).UseSerilog(); -
En la contenedor de OTel, podemos ver los logs generados por la aplicación.
2024-12-09 17:47:40 2024-12-09T22:47:40.052Zinfoservice@v0.114.0/service.go:166Setting up own telemetry...2024-12-09 17:47:40 2024-12-09T22:47:40.056Zinfotelemetry/metrics.go:70Serving metrics{"address": "localhost:8888", "metrics level": "Normal"}2024-12-09 17:47:40 2024-12-09T22:47:40.056Zinfobuilders/builders.go:26Development component. May change in the future.{"kind": "exporter", "data_type": "logs", "name": "debug"}2024-12-09 17:47:40 2024-12-09T22:47:40.057Zinfobuilders/builders.go:26Development component. May change in the future.{"kind": "exporter", "data_type": "traces", "name": "debug"}2024-12-09 17:47:40 2024-12-09T22:47:40.058Zinfobuilders/builders.go:26Development component. May change in the future.{"kind": "exporter", "data_type": "metrics", "name": "debug"}2024-12-09 17:47:40 2024-12-09T22:47:40.059Zinfoservice@v0.114.0/service.go:238Starting otelcol...{"Version": "0.114.0", "NumCPU": 32}2024-12-09 17:47:40 2024-12-09T22:47:40.059Zinfoextensions/extensions.go:39Starting extensions...2024-12-09 17:47:40 2024-12-09T22:47:40.060Zwarninternal@v0.114.0/warning.go:40Using the 0.0.0.0 address exposes this server to every network interface, which may facilitate Denial of Service attacks.{"kind": "receiver", "name": "otlp", "data_type": "logs", "documentation": "https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks"}2024-12-09 17:47:40 2024-12-09T22:47:40.061Zinfootlpreceiver@v0.114.0/otlp.go:112Starting GRPC server{"kind": "receiver", "name": "otlp", "data_type": "logs", "endpoint": "0.0.0.0:4317"}2024-12-09 17:47:40 2024-12-09T22:47:40.062Zwarninternal@v0.114.0/warning.go:40Using the 0.0.0.0 address exposes this server to every network interface, which may facilitate Denial of Service attacks.{"kind": "receiver", "name": "otlp", "data_type": "logs", "documentation": "https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks"}2024-12-09 17:47:40 2024-12-09T22:47:40.063Zinfootlpreceiver@v0.114.0/otlp.go:169Starting HTTP server{"kind": "receiver", "name": "otlp", "data_type": "logs", "endpoint": "0.0.0.0:4318"}2024-12-09 17:47:40 2024-12-09T22:47:40.063Zinfoservice@v0.114.0/service.go:261Everything is ready. Begin running and processing data.2024-12-09 17:48:08 2024-12-09T22:48:08.698ZinfoLogs{"kind": "exporter", "data_type": "logs", "name": "debug", "resource logs": 1, "log records": 1}2024-12-09 17:48:08 2024-12-09T22:48:08.698ZinfoResourceLog #02024-12-09 17:48:08 Resource SchemaURL: https://opentelemetry.io/schemas/v1.13.02024-12-09 17:48:08 Resource attributes:2024-12-09 17:48:08 -> service.name: Str(MyMicroservice)2024-12-09 17:48:08 -> service.version: Str(v1)2024-12-09 17:48:08 -> service.description: Str(Sample of CodeDesignPlus.Net.Core)2024-12-09 17:48:08 -> service.business: Str(CodeDesignPlus)2024-12-09 17:48:08 -> service.contact.name: Str(CodeDesignPlus)2024-12-09 17:48:08 -> service.contact.email: Str(custom@outlook.com)2024-12-09 17:48:08 ScopeLogs #02024-12-09 17:48:08 ScopeLogs SchemaURL:2024-12-09 17:48:08 InstrumentationScope CodeDesignPlus.Net.Logger.Sample.FakeBackgroundService2024-12-09 17:48:08 LogRecord #02024-12-09 17:48:08 ObservedTimestamp: 2024-12-09 22:48:08.577921 +0000 UTC2024-12-09 17:48:08 Timestamp: 2024-12-09 22:48:08.577921 +0000 UTC2024-12-09 17:48:08 SeverityText: Information2024-12-09 17:48:08 SeverityNumber: Info(9)2024-12-09 17:48:08 Body: Str(The FakeBackgroundService is running.)2024-12-09 17:48:08 Attributes:2024-12-09 17:48:08 -> MachineName: Str(AORUSX570)2024-12-09 17:48:08 -> ThreadId: Int(1)2024-12-09 17:48:08 -> ProcessId: Int(131648)2024-12-09 17:48:08 -> ProcessName: Str(CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:08 -> EnvironmentUserName: Str(AORUSX570\coded)2024-12-09 17:48:08 -> AppName: Str(MyMicroservice)2024-12-09 17:48:08 -> message_template.text: Str(The FakeBackgroundService is running.)2024-12-09 17:48:08 -> message_template.hash.md5: Str(592ad19be63a7296241d676c000a02bb)2024-12-09 17:48:08 Trace ID:2024-12-09 17:48:08 Span ID:2024-12-09 17:48:08 Flags: 02024-12-09 17:48:08 {"kind": "exporter", "data_type": "logs", "name": "debug"}2024-12-09 17:48:10 2024-12-09T22:48:10.728ZinfoLogs{"kind": "exporter", "data_type": "logs", "name": "debug", "resource logs": 1, "log records": 3}2024-12-09 17:48:10 2024-12-09T22:48:10.728ZinfoResourceLog #02024-12-09 17:48:10 Resource SchemaURL: https://opentelemetry.io/schemas/v1.13.02024-12-09 17:48:10 Resource attributes:2024-12-09 17:48:10 -> service.name: Str(MyMicroservice)2024-12-09 17:48:10 -> service.version: Str(v1)2024-12-09 17:48:10 -> service.description: Str(Sample of CodeDesignPlus.Net.Core)2024-12-09 17:48:10 -> service.business: Str(CodeDesignPlus)2024-12-09 17:48:10 -> service.contact.name: Str(CodeDesignPlus)2024-12-09 17:48:10 -> service.contact.email: Str(custom@outlook.com)2024-12-09 17:48:10 ScopeLogs #02024-12-09 17:48:10 ScopeLogs SchemaURL:2024-12-09 17:48:10 InstrumentationScope Microsoft.Hosting.Lifetime2024-12-09 17:48:10 LogRecord #02024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5921085 +0000 UTC2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5921085 +0000 UTC2024-12-09 17:48:10 SeverityText: Information2024-12-09 17:48:10 SeverityNumber: Info(9)2024-12-09 17:48:10 Body: Str(Application started. Press Ctrl+C to shut down.)2024-12-09 17:48:10 Attributes:2024-12-09 17:48:10 -> MachineName: Str(AORUSX570)2024-12-09 17:48:10 -> ThreadId: Int(1)2024-12-09 17:48:10 -> ProcessId: Int(131648)2024-12-09 17:48:10 -> ProcessName: Str(CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:10 -> EnvironmentUserName: Str(AORUSX570\coded)2024-12-09 17:48:10 -> AppName: Str(MyMicroservice)2024-12-09 17:48:10 -> message_template.text: Str(Application started. Press Ctrl+C to shut down.)2024-12-09 17:48:10 -> message_template.hash.md5: Str(33343b9e9ae6b19943b4680fc45dba3e)2024-12-09 17:48:10 Trace ID:2024-12-09 17:48:10 Span ID:2024-12-09 17:48:10 Flags: 02024-12-09 17:48:10 LogRecord #12024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5955355 +0000 UTC2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5955355 +0000 UTC2024-12-09 17:48:10 SeverityText: Information2024-12-09 17:48:10 SeverityNumber: Info(9)2024-12-09 17:48:10 Body: Str(Hosting environment: Production)2024-12-09 17:48:10 Attributes:2024-12-09 17:48:10 -> EnvName: Str(Production)2024-12-09 17:48:10 -> MachineName: Str(AORUSX570)2024-12-09 17:48:10 -> ThreadId: Int(1)2024-12-09 17:48:10 -> ProcessId: Int(131648)2024-12-09 17:48:10 -> ProcessName: Str(CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:10 -> EnvironmentUserName: Str(AORUSX570\coded)2024-12-09 17:48:10 -> AppName: Str(MyMicroservice)2024-12-09 17:48:10 -> message_template.text: Str(Hosting environment: {EnvName})2024-12-09 17:48:10 -> message_template.hash.md5: Str(4d9ec9b8e5e077b29c981b666ca9117e)2024-12-09 17:48:10 Trace ID:2024-12-09 17:48:10 Span ID:2024-12-09 17:48:10 Flags: 02024-12-09 17:48:10 LogRecord #22024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5956514 +0000 UTC2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5956514 +0000 UTC2024-12-09 17:48:10 SeverityText: Information2024-12-09 17:48:10 SeverityNumber: Info(9)2024-12-09 17:48:10 Body: Str(Content root path: G:\Repos\CodeDesignPlus.Net.Sdk\examples\CodeDesignPlus.Net.Logger.Sample\src\CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:10 Attributes:2024-12-09 17:48:10 -> ContentRoot: Str(G:\Repos\CodeDesignPlus.Net.Sdk\examples\CodeDesignPlus.Net.Logger.Sample\src\CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:10 -> MachineName: Str(AORUSX570)2024-12-09 17:48:10 -> ThreadId: Int(1)2024-12-09 17:48:10 -> ProcessId: Int(131648)2024-12-09 17:48:10 -> ProcessName: Str(CodeDesignPlus.Net.Logger.Sample)2024-12-09 17:48:10 -> EnvironmentUserName: Str(AORUSX570\coded)2024-12-09 17:48:10 -> AppName: Str(MyMicroservice)2024-12-09 17:48:10 -> message_template.text: Str(Content root path: {ContentRoot})2024-12-09 17:48:10 -> message_template.hash.md5: Str(8468f8e3d95716a49ff2b521b7133155)2024-12-09 17:48:10 Trace ID:2024-12-09 17:48:10 Span ID:2024-12-09 17:48:10 Flags: 02024-12-09 17:48:10 {"kind": "exporter", "data_type": "logs", "name": "debug"}
Métodos de extensión
CodeDesignPlus.Net.Logger
proporciona métodos de extensión para configurar los logs en IServiceCollection
e IHostBuilder
. A continuación, se muestran los métodos de extensión más importantes:
Service Collection
ServiceCollectionExtensions
contiene los métodos de extensión para registrar los servicios necesarios en el contenedor de dependencias.
Opciones de configuración
CodeDesignPlus.Net.Logger
utiliza la clase LoggerOptions
para personalizar la configuración del logger y la exportación de logs a OTel.
Conclusiones
CodeDesignPlus.Net.Logger
ofrece una solución eficiente y flexible para la gestión de logs en aplicaciones .NET Core. Facilita la configuración de Serilog con enriquecimientos automáticos y la posibilidad de exportar logs a OpenTelemetry, mejorando la observabilidad y la capacidad de diagnóstico de las aplicaciones.