Sprint.Shared.Logs
1.3.2
dotnet add package Sprint.Shared.Logs --version 1.3.2
NuGet\Install-Package Sprint.Shared.Logs -Version 1.3.2
<PackageReference Include="Sprint.Shared.Logs" Version="1.3.2" />
<PackageVersion Include="Sprint.Shared.Logs" Version="1.3.2" />
<PackageReference Include="Sprint.Shared.Logs" />
paket add Sprint.Shared.Logs --version 1.3.2
#r "nuget: Sprint.Shared.Logs, 1.3.2"
#:package Sprint.Shared.Logs@1.3.2
#addin nuget:?package=Sprint.Shared.Logs&version=1.3.2
#tool nuget:?package=Sprint.Shared.Logs&version=1.3.2
Shared.Logs
High-performance structured logging library designed for the Sprint ecosystem (.NET 10+). Provides two independent logging pipelines — Application Event Logging (via Serilog Sink) and HTTP Request/Response Logging (via Middleware) — both using asynchronous batch writes to MySQL with automatic table partitioning.
Key Features
- Non-blocking Architecture: All log entries are queued in-memory (
ConcurrentQueue) and flushed to MySQL by a background worker — zero impact on request latency. - Requires .NET 10.0+
- Auto MySQL Partitioning: Tables are auto-created and partitioned by a configurable day interval (default: every 7 days, 365 days ahead). Partition boundaries continue seamlessly from the last existing partition on each deploy — no gaps, no data loss.
- Dual Logging Pipelines:
AddAppLogging— Captures structured Serilog events (level, message, exception, trace ID, metadata) intologs_apptable.AddHttpLogging— Captures full HTTP pairs (method, URL, headers, body, status code, duration) intologs_httptable.
- Configurable Batch Flush: Flush is triggered when batch reaches
BatchSizeOR whenBatchTimeoutSecondselapses — whichever comes first. - Path Filtering: HTTP logging supports
IgnorePathsto skip health checks, metrics endpoints, etc. - App Log Level Filtering:
AppLogMinimumLevelcontrols the minimum Serilog level stored in MySQL (e.g.Warningto skipInformation/Debugentirely). - Outbound HTTP Tracing:
HttpLoggingHandler(DelegatingHandler) logs outgoing HTTP client calls to a dedicated MySQL table (defaultlogs_http_partner) viaIHttpLogQueue, with table name configurable per deployment. - Multi-table Support:
MySqlHttpLogRepositoryaccepts an optionaltableNameparameter — register separate pipelines for inbound and outbound logs without any code duplication. - Reference Header Indexing: Configure
SharedLog:ReferenceHeadersto extract business-key headers (e.g.x-order-id,x-log-key) into a separatelogs_referencetable, enabling fast reverse lookup from a business key back to the originatingTraceId.
Installation & Setup
1. Register Services in Program.cs
App Event Logging (Serilog → MySQL)
using Shared.Logs.Extensions;
// Option 1: Automatic from Configuration
builder.AddAppLogging(builder.Configuration);
// Option 2: Manual setup via Action
builder.AddAppLogging(options => {
options.ConnectionString = "Server=localhost;Database=logs_db;...";
options.ServiceName = "Order-Core-API";
options.BatchSize = 200;
options.BatchTimeoutSeconds = 10;
});
HTTP Request/Response Logging
// Option 1: Automatic from Configuration
builder.AddHttpLogging(builder.Configuration);
// Option 2: Manual setup via Action
builder.AddHttpLogging(options => {
options.ConnectionString = "Server=localhost;Database=logs_db;...";
options.ServiceName = "Order-Core-API";
options.IgnorePaths = new List<string> { "/health", "/metrics" };
});
2. Enable Middleware in Program.cs
var app = builder.Build();
// Enable HTTP logging middleware (must be registered early in the pipeline)
app.UseHttpLogging("Order-Core-API");
app.Run();
3. Configuration Template (appsettings.json)
{
"ConnectionStrings": {
"LogEvent": "Server=localhost;Port=3306;Database=sprint_logs;Uid=root;Pwd=secret;",
"LogRequest": "Server=localhost;Port=3306;Database=sprint_logs;Uid=root;Pwd=secret;"
},
"SharedLog": {
"ServiceName": "Sprint-OMS-Order-API",
"BatchSize": 100,
"BatchTimeoutSeconds": 5,
"AppLogMinimumLevel": "Warning",
"PartitionIntervalDays": 7,
"PartitionLookAheadDays": 365,
"IgnorePaths": [
"/health",
"/favicon.ico",
"/metrics"
],
"ReferenceHeaders": [
"x-log-key",
"x-order-id"
]
}
}
App Log Minimum Level
Control which Serilog levels get persisted to MySQL via SharedLog:AppLogMinimumLevel. Accepts any Serilog LogEventLevel value:
| Value | Stored levels |
|---|---|
Verbose |
All |
Debug |
Debug and above |
Information |
Information and above (default) |
Warning |
Warning, Error, Fatal only |
Error |
Error and Fatal only |
Fatal |
Fatal only |
Serilog console output is unaffected — this filter applies only to MySQL storage.
Outbound HTTP Client Tracing
HttpLoggingHandler is a DelegatingHandler that logs every outgoing HTTP call to MySQL.
It requires an IHttpLogQueue instance — register a keyed "outbound" queue pointing to a separate table:
// In your integration DI registration:
var connStr = configuration.GetConnectionString("LogRequest") ?? string.Empty;
var serviceName = configuration["SharedLog:ServiceName"] ?? "unknown";
var outboundTable = configuration["SharedLog:OutboundTableName"] ?? "logs_http_partner";
services.AddKeyedSingleton<IHttpLogQueue, HttpLogQueueService>("outbound");
services.AddHostedService(sp => new HttpLogProcessingWorker(
sp.GetRequiredKeyedService<IHttpLogQueue>("outbound"),
new MySqlHttpLogRepository(new HttpLogOptions { ConnectionString = connStr, ServiceName = serviceName }, outboundTable),
sp.GetRequiredService<ILogger<HttpLogProcessingWorker>>(),
sp.GetRequiredService<HttpLogOptions>()
));
services.AddTransient<HttpLoggingHandler>(sp => new HttpLoggingHandler(
sp.GetRequiredService<ILogger<HttpLoggingHandler>>(),
sp.GetRequiredKeyedService<IHttpLogQueue>("outbound"),
sp.GetRequiredService<HttpLogOptions>(),
sp.GetRequiredService<IHttpContextAccessor>()
));
// Attach to Refit/HttpClient:
services.AddRefitClient<IMyClient>()
.AddHttpMessageHandler<HttpLoggingHandler>();
Outbound rows are distinguishable by IpAddress IS NULL in the logs_http_partner table.
Config (appsettings.json):
"SharedLog": {
"OutboundTableName": "logs_http_partner"
}
MySQL Table Schema
logs_app — Application Event Log
| Column | Type | Description |
|---|---|---|
| Id | BIGINT AUTO_INCREMENT | Primary key |
| Timestamp | DATETIME(6) | UTC event time |
| ServiceName | VARCHAR(100) | Name of the originating service |
| TraceId | VARCHAR(100) | Distributed trace correlation ID |
| Level | VARCHAR(20) | Serilog log level (Information, etc.) |
| Message | LONGTEXT | Rendered log message |
| Exception | LONGTEXT | Full exception string (nullable) |
| SourceContext | VARCHAR(255) | Class/namespace origin (nullable) |
| Metadata | JSON | Additional log properties (nullable) |
logs_http / logs_http_partner — HTTP Request/Response Log
| Column | Type | Description |
|---|---|---|
| Id | BIGINT AUTO_INCREMENT | Primary key |
| Timestamp | DATETIME(6) | UTC request time |
| ServiceName | VARCHAR(100) | Name of the originating service |
| TraceId | VARCHAR(100) | Distributed trace correlation ID |
| Method | VARCHAR(10) | HTTP method (GET, POST, etc.) |
| Url | TEXT | Full request URL |
| RequestHeaders | JSON | Captured request headers (nullable) |
| RequestBody | LONGTEXT | Request body (nullable) |
| StatusCode | INT | HTTP response status code |
| ResponseHeaders | JSON | Captured response headers (nullable) |
| ResponseBody | LONGTEXT | Response body (nullable) |
| DurationMs | BIGINT | Request duration in milliseconds |
| IpAddress | VARCHAR(50) | Client IP address — NULL for outbound calls |
logs_reference — Request Header Reference Index
ใช้สำหรับ trace ย้อนกลับจาก business key (เช่น x-order-id: 12345) ไปยัง trace_id ของ HTTP request ที่ส่ง header นั้นเข้ามา ตารางจะถูกสร้างและ partition โดยอัตโนมัติเช่นเดียวกับตารางอื่น เมื่อ SharedLog:ReferenceHeaders ถูกกำหนดอย่างน้อยหนึ่งค่า
| Column | Type | Description |
|---|---|---|
| id | BIGINT AUTO_INCREMENT | Primary key |
| timestamp | DATETIME(6) | UTC request time (ตรงกับ logs_http.timestamp) |
| trace_id | VARCHAR(100) | Distributed trace correlation ID |
| reference_key | VARCHAR(100) | Header name (เช่น x-order-id) |
| reference_value | VARCHAR(512) | Raw header value |
มี composite index (reference_key, reference_value) สำหรับ reverse lookup:
-- หา trace_id ทั้งหมดที่ผูกกับ order 12345
SELECT trace_id FROM logs_reference
WHERE reference_key = 'x-order-id' AND reference_value = '12345';
-- join กลับไปดู request log
SELECT h.*
FROM logs_http h
JOIN logs_reference r ON r.trace_id = h.trace_id
WHERE r.reference_key = 'x-order-id' AND r.reference_value = '12345';
ถ้า request ไม่มี header ที่กำหนดใน
ReferenceHeaders→ ไม่บันทึก row ถ้าReferenceHeadersว่าง → ไม่สร้างตาราง ไม่เปิด worker (no-op)
All tables are auto-partitioned by range (
PARTITION BY RANGE (TO_DAYS(timestamp))). Partition size and look-ahead window are controlled byPartitionIntervalDays(default:7) andPartitionLookAheadDays(default:365). On each deploy the library continues partitions from the last existing boundary — no gap, no data loss.
Resilience Design
- Zero-loss on insert failure: MySQL errors are caught silently — a failed batch does not crash the worker or the application.
- Self-sealing loop: The background worker catches all unhandled exceptions, logs them, and retries after 1 second.
- Graceful shutdown: When Kubernetes sends
SIGTERM, both workers drain all remaining queue items to MySQL before the process exits. No log entries are lost during rolling deploys or scale-down events. - Manual flush for batch jobs: For CronJobs or short-lived processes that exit immediately after finishing work, call
FlushAsync()explicitly before the process exits:
// At the end of a batch job
await httpLogQueue.FlushAsync();
await appLogQueue.FlushAsync();
© 2026 Sprint-OMS Development Team
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.9)
- Microsoft.Extensions.Hosting (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
- MySql.Data (>= 9.6.0)
- Serilog (>= 4.3.1)
- Serilog.AspNetCore (>= 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.