LogSystem.Client
2.8.1
dotnet add package LogSystem.Client --version 2.8.1
NuGet\Install-Package LogSystem.Client -Version 2.8.1
<PackageReference Include="LogSystem.Client" Version="2.8.1" />
<PackageVersion Include="LogSystem.Client" Version="2.8.1" />
<PackageReference Include="LogSystem.Client" />
paket add LogSystem.Client --version 2.8.1
#r "nuget: LogSystem.Client, 2.8.1"
#:package LogSystem.Client@2.8.1
#addin nuget:?package=LogSystem.Client&version=2.8.1
#tool nuget:?package=LogSystem.Client&version=2.8.1
.NET SDK for LogSystem
Enterprise-grade logging SDK for .NET Framework 4.7.2+, .NET Core 2.0+, and .NET 6+, with file-based logging, distributed tracing, and seamless integration with ILogger and Log4Net.
π Features
- β File-Based Logging - Synchronous file writes with thread safety (optimized for .NET Framework)
- β Logger API - Node.js-style convenience methods (Debug/Info/Warn/Error/Fatal)
- β Distributed Tracing - Built-in trace_id, span_id auto-generation
- β ILogger Integration - Seamless Microsoft.Extensions.Logging support
- β Log4Net Integration - Custom appender for existing Log4Net applications
- β Multi-Target - Supports .NET Framework 4.7.2+, .NET Core 2.0+, .NET 6+, .NET 8+
- β Auto-Enrich - Automatic @timestamp, service, host, trace fields injection
- β Exception Handling - Automatic stack trace extraction
- β Vector Compatible - Works with Vector agent for log collection
π¦ Installation
# Core client library
dotnet add package LogSystem.Client
# Log4Net integration (optional)
dotnet add package LogSystem.Log4Net
π Examples
- Console Application: See
FormatExample/for basic usage and Format methods - ASP.NET Core Web API: See
WebFormatExample/for REST API integration with dependency injection
Quick test:
# Test console example
cd sdks/dotnet/FormatExample
dotnet run
# Test web API example
cd sdks/dotnet/WebFormatExample
dotnet run
# Visit http://localhost:5289/swagger
π Quick Start
Basic Usage (File-Based Logging)
using LogSystem.Client;
var logger = new LogClient(new LogClientOptions
{
ApiKey = "your-api-key",
Service = "my-service",
LogDirectory = "C:\\logs\\myapp", // Windows
// LogDirectory = "/var/logs/myapp", // Linux
Logger = "MyApp.MainClass", // Optional: adds logger field
EnableTracing = true
});
// Use logger API methods
logger.Info("Application started", new Dictionary<string, object>
{
["version"] = "1.0.0",
["environment"] = "production"
});
logger.Debug("Configuration loaded", new Dictionary<string, object>
{
["config_file"] = "app.json"
});
logger.Warn("High memory usage", new Dictionary<string, object>
{
["memory_mb"] = 950,
["threshold_mb"] = 1024
});
// Error with exception
try {
ProcessOrder();
} catch (Exception ex) {
logger.Error("Order processing failed", ex, new Dictionary<string, object>
{
["order_id"] = "12345"
});
}
// Dispose to ensure all logs are written
logger.Dispose();
Logger API Methods
// Available log levels (matching Node.js SDK)
logger.Debug(message, properties); // Detailed diagnostic info
logger.Info(message, properties); // General informational messages
logger.Warn(message, properties); // Warning messages
logger.Error(message, properties); // Error messages
logger.Fatal(message, properties); // Critical errors
// Exception handling (auto-extracts error message and stack trace)
logger.Error(message, exception, properties);
logger.Fatal(message, exception, properties);
// log4net-style Format methods
logger.DebugFormat(format, ...args); // Debug with string.Format
logger.InfoFormat(format, ...args); // Info with string.Format
logger.WarnFormat(format, ...args); // Warn with string.Format
logger.ErrorFormat(format, ...args); // Error with string.Format
logger.FatalFormat(format, ...args); // Fatal with string.Format
Format Method Examples:
var logger = new LogClient(new LogClientOptions
{
ApiKey = "your-api-key",
Service = "order-service",
LogDirectory = "C:\\logs",
Logger = "OrderService"
});
// Like log4net's DebugFormat
logger.DebugFormat("CreateMtpDataοΌcompanyOrderId={0},sellid={1},qty={2}",
companyOrderId, sellid, qty);
// InfoFormat with currency formatting
logger.InfoFormat("Order {0} created by user {1} with total amount {2:C}",
orderId, userId, 299.99m);
// WarnFormat with threshold checking
logger.WarnFormat("Product {0} stock is low: {1} units remaining (threshold: {2})",
productId, currentStock, threshold);
// ErrorFormat with error code
logger.ErrorFormat("Payment gateway {0} failed for order {1} with error code {2}",
gatewayName, orderId, errorCode);
Log Output Format
Each log entry is written as a single-line JSON:
{
"@timestamp": "2025-12-06T00:58:35Z",
"api_key": "your-api-key",
"service": "my-service",
"host": "DESKTOP-PC",
"logger": "MyApp.MainClass",
"trace_id": "trace_abc123...",
"span_id": "span_def456...",
"level": "INFO",
"message": "Application started",
"version": "1.0.0",
"environment": "production"
}
ILogger Integration (ASP.NET Core)
// Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddProvider(new LogSystemLoggerProvider(new LogClientOptions
{
ApiKey = "your-api-key",
Service = "my-api",
LogDirectory = "C:\\logs\\myapi",
Logger = "API"
}));
var app = builder.Build();
// In controller
public class OrderController : ControllerBase
{
private readonly ILogger<OrderController> _logger;
public OrderController(ILogger<OrderController> logger)
{
_logger = logger;
}
[HttpPost]
public IActionResult CreateOrder([FromBody] OrderRequest request)
{
_logger.LogInformation("Order created: {OrderId} by {UserId}",
request.OrderId, request.UserId);
return Ok();
}
}
Log4Net Integration
<log4net>
<appender name="LogSystemAppender" type="LogSystem.Log4Net.LogSystemAppender, LogSystem.Log4Net">
<ApiKey value="your-api-key" />
<ServiceName value="my-app" />
<LogDirectory value="C:\logs\myapp" />
<Logger value="Log4NetApp" />
<BatchInterval value="5000" />
</appender>
<root>
<level value="INFO" />
<appender-ref ref="LogSystemAppender" />
</root>
</log4net>
using log4net;
var logger = LogManager.GetLogger(typeof(Program));
logger.Info("Application started");
logger.Error("Something went wrong", new Exception("Test exception"));
π Distributed Tracing
Generate Trace IDs
// Generate trace and span IDs
var traceId = LogClient.GenerateTraceId(); // trace_abc123...
var spanId = LogClient.GenerateSpanId(); // span_xyz789...
await client.SendAsync(new Dictionary<string, object>
{
["trace_id"] = traceId,
["span_id"] = spanId,
["level"] = "INFO",
["message"] = "Request started"
});
Extract Trace Context from HTTP Headers
// In ASP.NET Core middleware
public async Task InvokeAsync(HttpContext context)
{
var headers = context.Request.Headers.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.ToString()
);
var (traceId, parentId) = LogClient.ExtractTraceContext(headers);
var currentSpanId = LogClient.GenerateSpanId();
// Store in HttpContext for use in controllers
context.Items["trace_id"] = traceId ?? LogClient.GenerateTraceId();
context.Items["span_id"] = currentSpanId;
context.Items["parent_id"] = parentId;
await _next(context);
}
Create Trace Headers for Downstream Calls
var traceId = context.Items["trace_id"].ToString();
var spanId = context.Items["span_id"].ToString();
var httpClient = new HttpClient();
var traceHeaders = LogClient.CreateTraceHeaders(traceId, spanId);
foreach (var header in traceHeaders)
{
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var response = await httpClient.PostAsync("http://downstream-service/api", content);
Complete Microservice Example
// API Gateway
var rootTraceId = LogClient.GenerateTraceId();
var gatewaySpanId = LogClient.GenerateSpanId();
await logger.SendAsync(new Dictionary<string, object>
{
["trace_id"] = rootTraceId,
["span_id"] = gatewaySpanId,
["parent_id"] = null, // root span
["level"] = "INFO",
["message"] = "Gateway received request"
});
// Call Order Service
var orderHeaders = LogClient.CreateTraceHeaders(rootTraceId, gatewaySpanId);
// ... add headers to HttpClient request
// Order Service receives request
var (orderTraceId, orderParentId) = LogClient.ExtractTraceContext(receivedHeaders);
var orderSpanId = LogClient.GenerateSpanId();
await logger.SendAsync(new Dictionary<string, object>
{
["trace_id"] = orderTraceId, // inherited from Gateway
["span_id"] = orderSpanId,
["parent_id"] = orderParentId, // gatewaySpanId
["level"] = "INFO",
["message"] = "Order service processing"
});
βοΈ Configuration Options
LogClientOptions
| Property | Type | Default | Description |
|---|---|---|---|
ApiKey |
string | (required) | API key for authentication |
Service |
string | (required) | Service name identifier |
Endpoint |
string | http://localhost:8888 |
Log server HTTP endpoint |
Host |
string | Environment.MachineName |
Host identifier |
BatchSize |
int | 100 |
Maximum logs in batch queue |
BatchInterval |
int | 5000 |
Batch send interval (ms) |
EnableBatch |
bool | true |
Enable batch sending |
EnableTracing |
bool | true |
Auto-generate trace_id |
Environment Variables (appsettings.json)
{
"LogSystem": {
"ApiKey": "your-api-key",
"Service": "order-service",
"Endpoint": "http://localhost:8888",
"BatchSize": 100,
"BatchInterval": 5000
}
}
// Load from configuration
var options = new LogClientOptions();
builder.Configuration.GetSection("LogSystem").Bind(options);
builder.Logging.AddProvider(new LogSystemLoggerProvider(options));
π API Reference
LogClient
Constructor
public LogClient(LogClientOptions options)
Methods
SendAsync(Dictionary<string, object> logData)
Send a log entry asynchronously. Returns immediately after queuing.
await client.SendAsync(new Dictionary<string, object>
{
["level"] = "INFO",
["message"] = "User logged in",
["user_id"] = 12345
});
Send(Dictionary<string, object> logData)
Send a log entry synchronously (blocking). Use SendAsync for better performance.
client.Send(new Dictionary<string, object>
{
["level"] = "ERROR",
["message"] = "Critical error"
});
FlushAsync()
Flush queued logs immediately.
await client.FlushAsync();
Flush()
Flush synchronously (blocking).
client.Flush();
Static Methods
GenerateTraceId()
Generate a unique trace ID.
var traceId = LogClient.GenerateTraceId(); // "trace_abc123..."
GenerateSpanId()
Generate a unique span ID.
var spanId = LogClient.GenerateSpanId(); // "span_xyz789..."
ExtractTraceContext(IDictionary<string, string> headers)
Extract trace context from HTTP headers.
var (traceId, parentId) = LogClient.ExtractTraceContext(requestHeaders);
CreateTraceHeaders(string traceId, string spanId)
Create HTTP headers for downstream calls.
var headers = LogClient.CreateTraceHeaders(traceId, spanId);
// { "X-Trace-Id": "trace_...", "X-Span-Id": "span_..." }
LogSystemLoggerProvider
ILoggerProvider implementation for Microsoft.Extensions.Logging.
// With existing LogClient
public LogSystemLoggerProvider(LogClient client, bool disposeClient = false)
// With options
public LogSystemLoggerProvider(LogClientOptions options)
LogSystemAppender (Log4Net)
Log4Net appender with HTTP support.
Configuration Properties:
ApiKey- API key (required)ServiceName- Service name (required)Endpoint- HTTP endpointBatchSize- Batch sizeBatchInterval- Batch interval (ms)EnableBatch- Enable batchingEnableTracing- Auto trace_id
π― Best Practices
1. Use Structured Logging
// β
Good: Structured fields
await client.SendAsync(new Dictionary<string, object>
{
["level"] = "INFO",
["message"] = "Order created",
["order_id"] = "ORD-12345",
["user_id"] = "user_789",
["amount"] = 99.99
});
// β Bad: All in message
await client.SendAsync(new Dictionary<string, object>
{
["level"] = "INFO",
["message"] = "Order ORD-12345 created by user_789 for $99.99"
});
2. Propagate Trace Context
// Extract from incoming request
var (traceId, parentId) = LogClient.ExtractTraceContext(request.Headers);
// Use in current service
var currentSpanId = LogClient.GenerateSpanId();
// Pass to downstream services
var downstreamHeaders = LogClient.CreateTraceHeaders(
traceId ?? LogClient.GenerateTraceId(),
currentSpanId
);
3. Use ILogger for ASP.NET Core
// Leverage ILogger's structured logging
_logger.LogInformation(
"Order {OrderId} created by {UserId} for {Amount} {Currency}",
"ORD-123", "user_789", 99.99, "USD"
);
// Automatically becomes:
// {
// "message": "Order ORD-123 created by user_789 for 99.99 USD",
// "OrderId": "ORD-123",
// "UserId": "user_789",
// "Amount": 99.99,
// "Currency": "USD"
// }
4. Dispose Properly
// Use using statement
using var client = new LogClient(options);
await client.SendAsync(logData);
// Auto-flush on dispose
// Or manual flush
await client.FlushAsync();
client.Dispose();
5. Handle Errors Gracefully
try
{
await RiskyOperation();
}
catch (Exception ex)
{
await client.SendAsync(new Dictionary<string, object>
{
["trace_id"] = traceId,
["span_id"] = spanId,
["level"] = "ERROR",
["message"] = "Operation failed",
["error_message"] = ex.Message,
["error_type"] = ex.GetType().Name,
["error_stack"] = ex.StackTrace
});
}
π Examples
Run the included examples:
cd examples
dotnet run # All examples
dotnet run --project BasicExample # Basic usage
dotnet run --project ILoggerExample # ILogger integration
dotnet run --project TraceExample # Distributed tracing
π Migration from File-Based SDK (v1.x)
| v1.x (File-based) | v2.x (HTTP-based) |
|---|---|
new LogClient(apiKey, service, logDirectory) |
new LogClient(new LogClientOptions { ApiKey, Service, Endpoint }) |
client.Write(logData) |
await client.SendAsync(logData) |
| No batching | Built-in batch queue |
| Vector Agent required | Direct HTTP (Vector optional) |
π§ͺ Testing
# Build all projects
dotnet build
# Run examples
cd examples
dotnet run
# Run with custom endpoint
$env:LOG_ENDPOINT="http://production-server:8888"
dotnet run
π€ Compatibility
| Target Framework | .NET Version | Status |
|---|---|---|
net472 |
.NET Framework 4.7.2+ | β Supported |
netstandard2.0 |
.NET Core 2.0+ | β Supported |
net6.0 |
.NET 6 | β Supported |
net8.0 |
.NET 8 | β Supported |
π License
MIT
π Related
- Node.js SDK - JavaScript/TypeScript SDK
- Main Documentation - Platform overview
Version: 2.0.0
Last Updated: 2025-12-05
Status: β
Production Ready
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.0)
-
.NETFramework 4.8
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.0)
-
.NETStandard 2.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.1.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.0)
-
net6.0
-
net8.0
NuGet packages (2)
Showing the top 2 NuGet packages that depend on LogSystem.Client:
| Package | Downloads |
|---|---|
|
LogSystem.Log4Net
LogSystem Appender for log4net - Seamlessly integrate your existing log4net applications with LogSystem distributed tracing and structured logging. Drop-in replacement requiring minimal configuration changes. Zero external dependencies except log4net. Supports .NET Framework 4.7.2+, .NET Standard 2.0, .NET Core 2.0+, .NET 6+, and .NET 8+. |
|
|
LogSystem.NLog
LogSystem Target for NLog - Seamlessly integrate your existing NLog applications with LogSystem distributed tracing and structured logging. Drop-in replacement requiring minimal configuration changes. Zero external dependencies except NLog. Supports .NET Framework 4.7.2+, .NET Standard 2.0, .NET Core 2.0+, .NET 6+, and .NET 8+. |
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.8.1: Added monotonic numeric sequence field to every log entry to preserve deterministic order when multiple logs share the same millisecond timestamp.