BTW.Logging.Loki 1.0.2

dotnet add package BTW.Logging.Loki --version 1.0.2
                    
NuGet\Install-Package BTW.Logging.Loki -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BTW.Logging.Loki" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BTW.Logging.Loki" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="BTW.Logging.Loki" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BTW.Logging.Loki --version 1.0.2
                    
#r "nuget: BTW.Logging.Loki, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BTW.Logging.Loki@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BTW.Logging.Loki&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=BTW.Logging.Loki&version=1.0.2
                    
Install as a Cake Tool

BTW.Logging.Loki

Paquete NuGet para configuración centralizada de logging con Serilog y Grafana Loki para proyectos BTW.

📋 Tabla de Contenidos

✨ Características

  • ⚡ Configuración de Serilog en 1 línea de código
  • 📊 Envío automático de logs a Grafana Loki
  • 🔗 CorrelationId automático en todos los requests
  • 📱 Detección de dispositivos (Desktop, Mobile, Tablet)
  • 🤖 Detección de bots y crawlers
  • ⏱️ Medición de tiempo de respuesta (ElapsedMs)
  • 🏢 Soporte multi-tenancy (opcional)
  • 🚫 Filtros automáticos para health checks, swagger y metrics
  • 🔇 Namespaces de terceros silenciados por defecto (Microsoft, EntityFrameworkCore, System)
  • 📝 Logs estructurados en formato JSON
  • 🔐 Integración con Infisical para gestión de secretos

📦 Instalación

dotnet add package BTW.Logging.Loki

🚀 Configuración Rápida

Paso 1: Configurar appsettings.json

{
  "Loki": {
    "ServiceName": "mi-servicio-api"
  }
}

Paso 2: Configurar URL de Loki en Infisical

Agregar la siguiente variable en Infisical:

Loki__Url=http://0.0.0.0:3100

Paso 3: Actualizar Program.cs

using BTW.Logging.Loki.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Cargar secretos de Infisical
builder.AddInfisicalSecrets(); // Loki__Url viene de aquí

// ⚡ Configurar logging (1 línea)
builder.AddBTWLogging();

// ...resto de servicios
builder.Services.AddControllers();

var app = builder.Build();

// 🔧 Activar logging (1 línea) - DEBE IR PRIMERO
app.UseBTWLogging();

// ...resto de middlewares
app.MapControllers();

app.Run();

⚙️ Configuración Avanzada

Opciones Completas

{
  "Loki": {
    "ServiceName": "mi-servicio-api",
    "Environment": "Production",
    "MinimumLevel": "Warning",
    "EnableLoki": true,
    "FilterHealthChecks": true,
    "FilterSwagger": true,
    "FilterMetrics": true,
    "SampleSuccessfulRequests": 0,
    "MinimumLevelOverrides": {
      "Microsoft.EntityFrameworkCore": "Warning"
    }
  }
}

📋 Parámetros de Configuración

Parámetro Descripción Valor por Defecto Requerido
ServiceName Nombre del servicio (aparece como label app en Loki) - ✅ Sí
Environment Ambiente de ejecución (aparece como label env en Loki) Production No
MinimumLevel Nivel mínimo de log: Information, Warning, Error Warning No
EnableLoki Habilitar envío de logs a Loki true No
FilterHealthChecks Filtrar endpoints /health de los logs true No
FilterSwagger Filtrar endpoints /swagger de los logs true No
FilterMetrics Filtrar endpoints /metrics de los logs true No
SampleSuccessfulRequests Loguear 1 de cada N requests exitosos (0 = sin sampling) 0 No
MinimumLevelOverrides Activar logs de namespaces de terceros {} No

⚠️ Importante: Namespaces Silenciados por Defecto

Por defecto, el paquete silencia completamente los logs de los siguientes namespaces de terceros:

  • Microsoft (nivel Fatal)
  • Microsoft.AspNetCore (nivel Fatal)
  • Microsoft.EntityFrameworkCore (nivel Fatal)
  • System (nivel Fatal)
  • System.Net.Http (nivel Fatal)

Esto significa que NO verás ningún log de estos namespaces a menos que los actives explícitamente en MinimumLevelOverrides.

Ejemplo - Activar logs de EntityFrameworkCore:

{
  "Loki": {
    "ServiceName": "mi-api",
    "MinimumLevel": "Information",
    "MinimumLevelOverrides": {
      "Microsoft.EntityFrameworkCore": "Warning",
      "Microsoft.EntityFrameworkCore.Database.Command": "Information"
    }
  }
}

📊 Propiedades Automáticas en Logs

Cada request automáticamente incluye las siguientes propiedades:

Propiedad Descripción
CorrelationId ID único del request (propagado entre servicios)
RequestPath Path del endpoint llamado
RequestMethod Método HTTP (GET, POST, etc.)
StatusCode Código HTTP de respuesta
ElapsedMs Tiempo de respuesta en milisegundos
ContainerId Nombre de la máquina/contenedor
ClientIp IP del cliente
RequestHost Host del request
RequestScheme Esquema del request (http/https)
ServiceName Nombre del servicio
Environment Ambiente de ejecución
TenantId ID del tenant (si aplica) o "no-tenant"
DeviceType Tipo de dispositivo (Desktop, Mobile, Tablet, Other, Unknown)
IsBot Si el request viene de un bot (true/false)
RequestSizeKB Tamaño del request en KB

🔍 Consultas en Grafana Loki

Ver todos los logs de un servicio

{app="mi-servicio-api"}

Filtrar por ambiente

{app="mi-servicio-api", env="production"}

Ver solo errores

{app="mi-servicio-api"} | json | Level="Error"

Requests que tardan más de 1 segundo

{app="mi-servicio-api"} | json | ElapsedMs > 1000

Promedio de tiempo de respuesta

avg_over_time({app="mi-servicio-api"} | json | unwrap ElapsedMs [5m])

Filtrar por CorrelationId

{app="mi-servicio-api"} | json | CorrelationId="abc-123-def"

Detectar requests desde mobile

{app="mi-servicio-api"} | json | DeviceType="Mobile"

Filtrar bots

{app="mi-servicio-api"} | json | IsBot="true"

Requests por tenant

{app="mi-servicio-api"} | json | TenantId="tenant1"

🛠️ Características del CorrelationIdMiddleware

El middleware incluye las siguientes capacidades:

  • Exclusión de Health Checks: Detecta y excluye automáticamente endpoints de salud (/health, /ready, /alive, /ping)
  • 🔗 Correlation ID: Genera o extrae el ID de correlación del header X-Correlation-Id y lo propaga en la respuesta
  • 🏢 Multi-tenancy: Soporte opcional para aplicaciones multi-tenant mediante:
    • Header X-Tenant-Id
    • Detección automática por subdomain (ej: tenant1.miapp.com)
  • 📱 Detección de Dispositivos: Identifica si el request viene de Desktop, Mobile, Tablet u Otro dispositivo
  • 🤖 Detección de Bots: Identifica requests de bots, crawlers, herramientas de testing (Postman, curl, wget, googlebot, etc.)
  • 📦 Request Size: Registra el tamaño del request en KB
  • ⏱️ Elapsed Time: Mide el tiempo de respuesta de cada request en milisegundos
  • 🌐 Client IP: Captura la IP del cliente

🔧 Troubleshooting

No veo logs en Loki

  1. Verificar que EnableLoki esté en true
  2. Verificar que Loki__Url esté configurado en Infisical
  3. Verificar conectividad de red con el servidor Loki
  4. Revisar logs de consola para ver si hay errores de conexión

No veo CorrelationId en los logs

El CorrelationId se agrega automáticamente mediante LogContext. Asegúrate de:

  1. Llamar app.UseBTWLogging() ANTES de otros middlewares
  2. Los logs se generan dentro del contexto del request

No veo logs de EntityFrameworkCore/Microsoft

Por defecto, estos namespaces están silenciados (nivel Fatal). Si necesitas ver sus logs, actívalos explícitamente:

{
  "Loki": {
    "MinimumLevelOverrides": {
      "Microsoft.EntityFrameworkCore": "Warning"
    }
  }
}

¿Cómo medir performance de endpoints?

Usa la propiedad ElapsedMs que se registra automáticamente en cada request:

# Requests que tardan más de 1 segundo
{app="mi-api"} | json | ElapsedMs > 1000

# Promedio de tiempo de respuesta
avg_over_time({app="mi-api"} | json | unwrap ElapsedMs [5m])

📝 Ejemplo Completo

Estructura del Proyecto

MiProyecto.Api/
├── Program.cs
├── appsettings.json
├── appsettings.Development.json
└── appsettings.Production.json

appsettings.json

{
  "Loki": {
    "ServiceName": "mi-proyecto-api",
    "Environment": "Development",
    "MinimumLevel": "Information",
    "EnableLoki": false,
    "FilterHealthChecks": true,
    "FilterSwagger": true
  }
}

appsettings.Production.json

{
  "Loki": {
    "Environment": "Production",
    "MinimumLevel": "Warning",
    "EnableLoki": true
  }
}

Program.cs

using BTW.Logging.Loki.Extensions;
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

// 1. Cargar secretos de Infisical
builder.AddInfisicalSecrets();

// 2. Configurar logging (1 línea)
builder.AddBTWLogging();

// 3. Registrar servicios
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 4. Health checks
builder.Services.AddHealthChecks();

var app = builder.Build();

// 5. Activar logging - DEBE IR PRIMERO
app.UseBTWLogging();

// 6. Middleware
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();

// 7. Endpoints
app.MapControllers();
app.MapHealthChecks("/health");

app.Run();

Usar el Logger en un Controller

using Microsoft.AspNetCore.Mvc;

namespace MiProyecto.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly ILogger<ProductsController> _logger;

    public ProductsController(ILogger<ProductsController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult GetProducts()
    {
        _logger.LogInformation("Obteniendo lista de productos");
        
        try
        {
            // Lógica de negocio
            var products = new[] { "Product 1", "Product 2" };
            
            _logger.LogInformation("Se obtuvieron {Count} productos", products.Length);
            return Ok(products);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error al obtener productos");
            return StatusCode(500, "Error interno del servidor");
        }
    }
}

⚠️ Notas Importantes

  1. Orden de Middlewares: app.UseBTWLogging() debe llamarse PRIMERO, antes que cualquier otro middleware
  2. URL de Loki: Siempre debe venir de Infisical como Loki__Url para mayor seguridad
  3. ServiceName: Es el único campo obligatorio en la configuración
  4. Health Checks: Se excluyen automáticamente para evitar saturar los logs
  5. CorrelationId: Se propaga automáticamente en el header X-Correlation-Id de la respuesta

📄 Licencia

Uso interno BTW Company

💬 Soporte

Para dudas o problemas, contactar al equipo de desarrollo de BTW.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 418 12/10/2025