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
<PackageReference Include="BTW.Logging.Loki" Version="1.0.2" />
<PackageVersion Include="BTW.Logging.Loki" Version="1.0.2" />
<PackageReference Include="BTW.Logging.Loki" />
paket add BTW.Logging.Loki --version 1.0.2
#r "nuget: BTW.Logging.Loki, 1.0.2"
#:package BTW.Logging.Loki@1.0.2
#addin nuget:?package=BTW.Logging.Loki&version=1.0.2
#tool nuget:?package=BTW.Logging.Loki&version=1.0.2
BTW.Logging.Loki
Paquete NuGet para configuración centralizada de logging con Serilog y Grafana Loki para proyectos BTW.
📋 Tabla de Contenidos
- Características
- Instalación
- Configuración Rápida
- Configuración Avanzada
- Propiedades Automáticas
- Consultas en Grafana Loki
- Ejemplo Completo
- Troubleshooting
- Soporte
✨ 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-Idy 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)
- Header
- 📱 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
- Verificar que
EnableLokiesté entrue - Verificar que
Loki__Urlesté configurado en Infisical - Verificar conectividad de red con el servidor Loki
- 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:
- Llamar
app.UseBTWLogging()ANTES de otros middlewares - 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
- Orden de Middlewares:
app.UseBTWLogging()debe llamarse PRIMERO, antes que cualquier otro middleware - URL de Loki: Siempre debe venir de Infisical como
Loki__Urlpara mayor seguridad - ServiceName: Es el único campo obligatorio en la configuración
- Health Checks: Se excluyen automáticamente para evitar saturar los logs
- CorrelationId: Se propaga automáticamente en el header
X-Correlation-Idde la respuesta
📄 Licencia
Uso interno BTW Company
💬 Soporte
Para dudas o problemas, contactar al equipo de desarrollo de BTW.
| Product | Versions 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. |
-
net8.0
- Serilog (>= 4.3.0)
- Serilog.AspNetCore (>= 10.0.0)
- Serilog.Enrichers.Environment (>= 3.0.1)
- Serilog.Enrichers.Thread (>= 4.0.0)
- Serilog.Formatting.Compact (>= 3.0.0)
- Serilog.Sinks.Console (>= 6.1.1)
- Serilog.Sinks.File (>= 7.0.0)
- Serilog.Sinks.Grafana.Loki (>= 8.3.1)
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 |