SyslogLogging is a comprehensive .NET logging library that provides high-performance, thread-safe logging to multiple destinations including syslog servers, console, and files. The library features async support, structured logging, Microsoft.Extensions.Logging integration, background queuing, and message batching.
- Namespace declaration MUST be at the top of the file (not within namespace block)
- Using statements MUST be inside the namespace block, grouped logically
- Standard framework usings come first, then third-party, then project-specific
namespace SyslogLogging
{
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
}- NEVER use
var- always specify explicit types - Use underscore + PascalCase for private fields:
_MyField - Use PascalCase for public/protected members:
MyProperty - Use camelCase for local variables and parameters:
myVariable
// Correct
List<string> messages = new List<string>();
private readonly LoggingModule _Logger;
// Incorrect
var messages = new List<string>();
private readonly LoggingModule logger;- ALL async methods MUST accept
CancellationToken token = defaultas the LAST parameter - ALL async calls MUST use
ConfigureAwait(false) - Async method names MUST end with "Async"
public async Task LogAsync(string message, CancellationToken token = default)
{
await WriteToFileAsync(message, token).ConfigureAwait(false);
}- ALL public APIs MUST call
ThrowIfDisposed()at the beginning - Use
ArgumentNullException.ThrowIfNull()for null parameter checks on .NET 6+ - Implement both
IDisposableandIAsyncDisposablefor classes with resources
public void Log(string message)
{
ThrowIfDisposed();
if (string.IsNullOrEmpty(message)) return;
// Implementation
}- ALL public APIs MUST have XML documentation
- Include
<exception>tags for all thrown exceptions - Include
<param>tags for all parameters - Include meaningful
<summary>descriptions
/// <summary>
/// Logs a message asynchronously to all configured destinations.
/// </summary>
/// <param name="message">The message to log.</param>
/// <param name="token">Cancellation token.</param>
/// <exception cref="ObjectDisposedException">Thrown when the logger is disposed.</exception>
/// <exception cref="ArgumentNullException">Thrown when message is null.</exception>
public async Task LogAsync(string message, CancellationToken token = default)- Use
lockstatements for thread synchronization - Console color operations MUST use
Console.ResetColor()to prevent race conditions - Background processing MUST use proper cancellation token handling
lock (_ConsoleLock)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor(); // CRITICAL for thread safety
}Main entry point for all logging operations. Features:
- Async/sync logging methods for all severity levels
- Multiple destination support (console, file, syslog)
- Thread-safe operations with proper disposal
- Background queue processing integration
Structured logging support with:
- Property-based metadata
- Correlation ID tracking
- JSON serialization
- Fluent builder pattern
Background processing service providing:
- Per-destination message queues
- Batch processing for I/O optimization
- Thread-safe console color handling
- Configurable batching and delays
File-backed message queue featuring:
- Persistence across application restarts
- Memory limit enforcement
- Automatic file rotation
- Corruption recovery
SyslogLoggerProvider.cs- ILoggerProvider implementationSyslogExtensions.cs- DI container extensions- Full compatibility with .NET logging framework
- Complete SyslogServer project integration
- UDP syslog message reception
- File-based logging with timestamp support
- Settings-based configuration
All logging methods have async variants with proper cancellation token support:
await logger.InfoAsync("Message", cancellationToken);
await logger.LogEntryAsync(entry, cancellationToken);Rich metadata support with fluent API:
logger.BeginStructuredLog(Severity.Info, "User login")
.WithProperty("UserId", userId)
.WithProperty("IpAddress", ipAddress)
.WithCorrelationId(correlationId)
.Write();Non-blocking logging with configurable batching:
- Separate queues per destination
- Batch size optimization
- Memory pressure handling
- Graceful shutdown support
Comprehensive thread-safe operations:
- Console color race condition prevention
- Lock-free queue operations where possible
- Proper disposal in multi-threaded environments
dotnet buildcd src/Test
dotnet rundotnet pack src/LoggingModule/LoggingModule.csprojdotnet cleansrc/
├── LoggingModule/ # Main library
│ ├── LoggingModule.cs # Core logging class
│ ├── LogEntry.cs # Structured logging
│ ├── LogProcessingService.cs # Background processing
│ ├── PersistentLogQueue.cs # Persistent queue
│ ├── SyslogLoggerProvider.cs # ILogger integration
│ ├── SyslogExtensions.cs # DI extensions
│ └── [Other core files]
├── Test/ # Comprehensive test suite
│ └── Program.cs # All capability testing
└── SyslogServer/ # Integrated syslog server
├── SyslogServer.cs # UDP syslog receiver
└── Settings.cs # Server configuration
The test program validates ALL library capabilities:
- Constructor Testing - All initialization patterns
- Basic Logging - All severity levels, sync/async
- Structured Logging - Properties, correlation IDs, JSON
- Fluent Logging - Builder pattern validation
- Exception Logging - Error capture and formatting
- Settings Validation - Configuration edge cases
- Background Processing - Queue and batch operations
- Thread Safety - Concurrent access validation
- Multiple Destinations - Syslog, console, file combinations
- Persistent Queuing - Restart survival testing
- Error Handling - Failure mode validation
- Disposal - Resource cleanup verification
- Performance - Throughput and latency metrics
- SyslogServer Integration - End-to-end validation
Each test category includes both success and failure cases with clear pass/fail reporting.
- Throughput: >100K messages/second (background mode)
- Latency: <1ms for queue operations
- Memory: Configurable limits with pressure handling
- Batching: Optimized I/O operations
- Threading: Lock-free where possible
- .NET Standard 2.0+ / .NET Framework 4.6.2+ / .NET 6.0+
- Microsoft.Extensions.Logging.Abstractions (8.0.0)
- System.Text.Json (8.0.5)
- SerializationHelper (2.0.1) - for SyslogServer
- v2.0.9 - Latest release with all new features
- Added async support with CancellationToken
- Implemented structured logging and semantic patterns
- Created ILogger implementation and Microsoft.Extensions.Logging integration
- Implemented persistent background queue with per-target queues
- Added message batching for I/O optimization
- Refactored LoggingModule to use new architecture
- Optimized UdpClient management
- Fixed console color race conditions
- Integrated SyslogServer project
- Always use async methods in async contexts
- Dispose properly - use
usingstatements or explicit disposal - Configure background processing for high-throughput scenarios
- Use structured logging for searchable, analyzable logs
- Set appropriate batch sizes based on your I/O characteristics
- Monitor queue depths to detect backpressure
- Use correlation IDs for request tracing
- Test failure scenarios including network outages and disk full
using SyslogLogging;
LoggingModule logger = new LoggingModule("localhost", 514, true);
await logger.InfoAsync("Application started");logger.BeginStructuredLog(Severity.Warning, "Rate limit exceeded")
.WithProperty("RequestsPerSecond", rps)
.WithProperty("ClientId", clientId)
.WithCorrelationId(Request.Headers["X-Correlation-ID"])
.WriteAsync();services.AddLogging(builder =>
{
builder.AddSyslog("localhost", 514, configure: module =>
{
module.Settings.EnableBackgroundQueue = true;
module.Settings.BatchSize = 100;
});
});try
{
await riskyOperation();
}
catch (Exception ex)
{
await logger.ExceptionAsync("Operation failed", ex);
throw;
}- Console colors bleeding - Fixed in v2.0.9 with proper Console.ResetColor()
- High memory usage - Configure queue limits and batch sizes
- Slow performance - Enable background processing
- Network timeouts - Adjust UDP timeout settings
- File access denied - Check permissions on log directory
Enable detailed diagnostics:
logger.Settings.EnableDebug = true;
logger.Settings.EnableConsole = true;This will show internal operations and queue states for troubleshooting.