LogSystem.Client
2.4.0
See the version list below for details.
dotnet add package LogSystem.Client --version 2.4.0
NuGet\Install-Package LogSystem.Client -Version 2.4.0
<PackageReference Include="LogSystem.Client" Version="2.4.0" />
<PackageVersion Include="LogSystem.Client" Version="2.4.0" />
<PackageReference Include="LogSystem.Client" />
paket add LogSystem.Client --version 2.4.0
#r "nuget: LogSystem.Client, 2.4.0"
#:package LogSystem.Client@2.4.0
#addin nuget:?package=LogSystem.Client&version=2.4.0
#tool nuget:?package=LogSystem.Client&version=2.4.0
.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 was computed. 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)
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.0)
-
net6.0
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 2.0.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.4.0: Production-ready SimpleJsonSerializer validated with 144 comprehensive tests covering edge cases, Unicode, number precision, special values, deep nesting (20 levels), wide objects (500 keys), and regression tests against System.Text.Json behavior. ZERO external dependencies except Microsoft.Extensions.Logging.Abstractions 2.0.0. Perfect compatibility with all .NET versions including ASP.NET Core 2.1+.