Skip to content

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.


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.


  • 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 e IHostBuilder.
  • 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.

  • 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).

  • ServiceCollectionExtension: Clase con métodos de extensión para configurar el logging en IServiceCollection.
  • AddLogger: Método de extensión que agrega los servicios de logging y las opciones de configuración a IServiceCollection.
  • UseSerilog: Método de extensión que configura Serilog para el IHostBuilder.
  • 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

En esta sección, aprenderás a instalar y configurar la librería CodeDesignPlus.Net.Logger en tu proyecto de .NET.

  • .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.

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:

Terminal window
dotnet add package CodeDesignPlus.Net.Logger

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();
  1. 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"
    }
    }
  2. Ejecutar Docker Compose para levantar el contenedor de OTel:

    services:
    otel-collector:
    image: otel/opentelemetry-collector
    ports:
    - "4317:4317"
    - "4318:4318"
    volumes:
    - ./settings/collector-config.yaml:/etc/otelcol/config.yaml
    restart: always
  3. 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;
    }
    }
  4. Regisrramos los servicios del log en el host

    //...
    .ConfigureServices((context, services) =>
    {
    services.AddLogging();
    services.AddLogger(context.Configuration);
    })
    .UseSerilog();
  5. 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 #0
    2024-12-09 17:48:08 Resource SchemaURL: https://opentelemetry.io/schemas/v1.13.0
    2024-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 #0
    2024-12-09 17:48:08 ScopeLogs SchemaURL:
    2024-12-09 17:48:08 InstrumentationScope CodeDesignPlus.Net.Logger.Sample.FakeBackgroundService
    2024-12-09 17:48:08 LogRecord #0
    2024-12-09 17:48:08 ObservedTimestamp: 2024-12-09 22:48:08.577921 +0000 UTC
    2024-12-09 17:48:08 Timestamp: 2024-12-09 22:48:08.577921 +0000 UTC
    2024-12-09 17:48:08 SeverityText: Information
    2024-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: 0
    2024-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 #0
    2024-12-09 17:48:10 Resource SchemaURL: https://opentelemetry.io/schemas/v1.13.0
    2024-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 #0
    2024-12-09 17:48:10 ScopeLogs SchemaURL:
    2024-12-09 17:48:10 InstrumentationScope Microsoft.Hosting.Lifetime
    2024-12-09 17:48:10 LogRecord #0
    2024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5921085 +0000 UTC
    2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5921085 +0000 UTC
    2024-12-09 17:48:10 SeverityText: Information
    2024-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: 0
    2024-12-09 17:48:10 LogRecord #1
    2024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5955355 +0000 UTC
    2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5955355 +0000 UTC
    2024-12-09 17:48:10 SeverityText: Information
    2024-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: 0
    2024-12-09 17:48:10 LogRecord #2
    2024-12-09 17:48:10 ObservedTimestamp: 2024-12-09 22:48:08.5956514 +0000 UTC
    2024-12-09 17:48:10 Timestamp: 2024-12-09 22:48:08.5956514 +0000 UTC
    2024-12-09 17:48:10 SeverityText: Information
    2024-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: 0
    2024-12-09 17:48:10 {"kind": "exporter", "data_type": "logs", "name": "debug"}

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:


ServiceCollectionExtensions contiene los métodos de extensión para registrar los servicios necesarios en el contenedor de dependencias.


CodeDesignPlus.Net.Logger utiliza la clase LoggerOptions para personalizar la configuración del logger y la exportación de logs a OTel.


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.