LogSystem.Client 2.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package LogSystem.Client --version 2.2.0
                    
NuGet\Install-Package LogSystem.Client -Version 2.2.0
                    
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="LogSystem.Client" Version="2.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LogSystem.Client" Version="2.2.0" />
                    
Directory.Packages.props
<PackageReference Include="LogSystem.Client" />
                    
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 LogSystem.Client --version 2.2.0
                    
#r "nuget: LogSystem.Client, 2.2.0"
                    
#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 LogSystem.Client@2.2.0
                    
#: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=LogSystem.Client&version=2.2.0
                    
Install as a Cake Addin
#tool nuget:?package=LogSystem.Client&version=2.2.0
                    
Install as a Cake Tool

.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 endpoint
  • BatchSize - Batch size
  • BatchInterval - Batch interval (ms)
  • EnableBatch - Enable batching
  • EnableTracing - 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


Version: 2.0.0
Last Updated: 2025-12-05
Status: βœ… Production Ready

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.

Version Downloads Last Updated
2.8.1 179 2/9/2026
2.8.0 493 12/8/2025
2.7.0 212 12/7/2025
2.6.0 208 12/7/2025
2.5.0 210 12/6/2025
2.4.0 190 12/6/2025
2.3.0 169 12/6/2025
2.2.0 171 12/6/2025
2.1.0 180 12/6/2025
2.0.0 176 12/6/2025

v2.2.0: Migrated to System.Text.Json 8.0.5 (removed Newtonsoft.Json security vulnerabilities CVE-2024-43485), improved performance, reduced dependencies. Includes Vector latency optimization configurations.