.NET logging Serilog

April 11, 2026

Sabrina

How to Use Serilog for Effective .NET Logging in 2026

How to Use Serilog for Effective.NET Logging

Mastering how to use Serilog is essential for any.NET developer seeking deep application visibility. You can gain invaluable insights into your application’s behavior, troubleshoot issues faster, and monitor performance with precision. This guide walks you through practical, real-world implementations to make Serilog a core part of your development workflow in 2026.

Expert Tip: Serilog’s structured logging capabilities transform raw log data into a queryable asset, enabling faster root cause analysis and more informed decision-making.

Featured Snippet: To effectively use Serilog, you must first install the necessary NuGet packages and configure your logger. This involves defining your desired log levels, choosing output destinations (sinks) like files or databases, and setting up formatting for readability. Proper Serilog usage transforms raw logs into actionable data.

In the experience of many.NET developers, the difference between an application that’s easy to debug and one that’s a black box often comes down to the quality of its logging. Serilog, a highly regarded.NET logging library, excels at providing structured, searchable logs that make this process smoother. Here’s what you need to know and how you can use its power effectively in 2026.

Latest Update (April 2026)

As of April 2026, Serilog continues to be a dominant force in the.NET logging ecosystem. Recent developments have focused on enhancing performance for high-throughput applications and improving integration with modern cloud-native observability platforms. According to HackerNoon’s recent analysis in August 2023, the integration of Serilog with Azure Application Insights remains a popular and effective strategy for cloud-based.NET applications, providing smooth telemetry collection and analysis. Developers are increasingly adopting Serilog’s structured logging features to meet the demands of complex microservice architectures and ensure complete monitoring. The library’s flexibility in handling various log levels and routing logs to diverse destinations like Seq, Elasticsearch, and cloud-specific services like Azure Monitor continues to be a key advantage.

Table of Contents

  • What’s Serilog and Why Use It?
  • Getting Started: Initial Serilog Setup
  • How to Configure Serilog Outputs (Sinks)
  • Using Serilog Enrichers for Context
  • Mastering Serilog Filtering and Log Levels
  • Practical Serilog Use Cases and Examples
  • Advanced Serilog Configurations
  • Serilog and Modern Observability
  • Frequently Asked Questions

What’s Serilog and Why Use It?

Serilog is an opinionated logging library for.NET applications that simplifies the process of writing diagnostic logs. Its primary advantage lies in its solid support for structured logging. Instead of merely dumping plain text into a file, Serilog allows you to log events as structured data, often in formats like JSON. This structured approach is easier for machines to parse and for humans to query, making it an indispensable tool for modern software development.

Why is structured logging so important in 2026? Imagine attempting to find all log entries related to a specific user ID, a particular transaction, or a known error code within millions of lines of unstructured text. This task can be incredibly time-consuming and error-prone. With Serilog, you can directly query for entries where UserId = 'user123' or TransactionId = 'abc-123' or ErrorCode = 500. This capability makes debugging, performance analysis, and security auditing exponentially faster and more effective, especially for maintaining complex, distributed applications.

Serilog’s design philosophy emphasizes ease of use, flexibility, and extensibility. It integrates well with the.NET ecosystem, including ASP.NET Core,.NET Core Worker Services, and other.NET applications. Its extensibility allows developers to create custom sinks, enrichers, and formatters to meet unique project requirements. As reported by various developer communities and technical blogs, Serilog is consistently ranked among the top logging frameworks for its reliability and feature set.

Getting Started: Initial Serilog Setup

To begin using Serilog, you’ll need to add the core Serilog package and any specific sink packages you plan to use. Here’s typically done via the NuGet Package Manager in Visual Studio or using the.NET CLI.

For ASP.NET Core applications, the Serilog.AspNetCore package is the common starting point, as it integrates Serilog directly with ASP.NET Core’s built-in logging infrastructure. Configuration usually occurs early in the application’s startup process, often within the Program.cs file for.NET 6 and later versions.

Here’s a typical setup example for an ASP.NET Core application:

1. Install Packages:

Using the.NET CLI:

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File

2. Configure in Program.cs (for.NET 6+):


using Serilog;
using Serilog.Events;

//... other using statements

var builder = WebApplication.CreateBuilder(args);

// Configure Serilog
Log.Logger = new LoggerConfiguration().MinimumLevel.Information() // Sets the minimum level for logs to be processed..MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // Override Microsoft logs to Warning level..Enrich.FromLogContext() // Enriches logs with properties from the LogContext..WriteTo.Console().WriteTo.File("logs/myapp-.txt", rollingInterval: RollingInterval.Day, shared: true).CreateLogger();

try
{
 builder.Host.UseSerilog(); // Integrate Serilog with the host

 // Add services to the container.
 builder.Services.AddControllersWithViews();

 var app = builder.Build();

 // Configure the HTTP request pipeline.
 if (!app.Environment.IsDevelopment()) 
 {
 app.UseExceptionHandler("/Home/Error");
 app.UseHsts();
 }

 app.UseHttpsRedirection();
 app.UseStaticFiles();

 app.UseRouting();

 app.UseAuthorization();

 app.MapControllerRoute(
 name: "default",
 pattern: "{controller=Home}/{action=Index}/{id?}");

 app.Run();
}
catch (Exception ex)
{
 Log.Fatal(ex, "Application start-up failed unexpectedly");
 return 1; // Indicate failure
}
finally
{
 Log.CloseAndFlush(); // Ensure all buffered events are written before exiting
}

This code snippet initializes Serilog, setting the minimum log level to Information. It also configures logs to be directed to both the console and a daily rolling file named logs/myapp-.txt. The builder.Host.UseSerilog() call is Key for integrating Serilog with the ASP.NET Core logging pipeline, ensuring that Serilog becomes the primary logging provider.

How to Configure Serilog Outputs (Sinks)

Sinks are the destinations where your log messages are sent. Serilog boasts an extensive library of sinks, allowing you to direct logs to virtually any service or storage system. The selection of appropriate sinks depends heavily on your application’s requirements, operational needs, and your team’s existing monitoring and analysis tools.

Common Sinks Include:

  • Console: Ideal for development environments, quick debugging, and simple applications where immediate feedback is needed.
  • File: Essential for persistent logging. File sinks are typically configured with rolling intervals (e.g., daily, hourly, size-based) to manage file sizes effectively and prevent disk space exhaustion.
  • Databases: For centralized log storage and complex querying. Serilog supports various databases, including SQL Server (via Serilog.Sinks.MSSqlServer), PostgreSQL, and others.
  • Seq: A popular, free, open-source log aggregation, management, and analysis tool In particular designed for structured logs. It provides a powerful web UI for searching and visualizing log data.
  • Elasticsearch: For integration with the ELK stack (Elasticsearch, Logstash, Kibana), a widely adopted solution for centralized logging and real-time analysis in large-scale systems.
  • Application Insights: A critical sink for developers working within the Azure cloud ecosystem, enabling complete application performance monitoring and telemetry. As highlighted by HackerNoon, this integration is a solid way to manage cloud application logs.
  • Other Cloud Services: Sinks for AWS CloudWatch, Google Cloud Logging, and other cloud platforms are also available.

You can configure Serilog to use multiple sinks concurrently, providing redundancy or directing different types of logs to different destinations. For instance, logging critical errors to a database while sending general information to a file and the console:


Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().WriteTo.File("logs/app_.txt", rollingInterval: RollingInterval.Hour, shared: true).WriteTo.Seq("http://localhost:5341") // Replace with your Seq server URL.CreateLogger();

Important Note on File Sinks: Always configure a rolling interval or size limit for file sinks. This prevents log files from growing indefinitely — which can lead to performance issues and disk space exhaustion. Common choices include RollingInterval.Day, RollingInterval.Hour, or size-based rolling.

Using Serilog Enrichers for Context

Enrichers are a cornerstone of Serilog’s structured logging power. They automatically add contextual information to every log event without requiring manual addition in every logging call. This enrichment transforms simple log messages into rich, context-aware records.

Commonly included enrichers add details such as:

  • Machine Name
  • Operating System Version
  • Process ID and Name
  • Thread ID
  • Application Version
  • Timestamp (with high precision)

Beyond these standard enrichments, Serilog offers powerful ways to add application-specific context. The Enrich.FromLogContext() method, when used with LogContext.PushProperty() or within ASP.NET Core middleware, can automatically include details like:

  • Current User Identity
  • Request ID or Correlation ID
  • Customer ID or Tenant ID
  • Specific operation names

This automatic injection of context is invaluable for tracing requests across distributed systems or identifying all activities related to a specific user or session.

Example: Adding Request ID with LogContext

In an ASP.NET Core application, you can enrich logs with a request ID using middleware:


// In Program.cs or Startup.cs

//... builder.Host.UseSerilog();...

app.UseMiddleware<RequestLoggingMiddleware>(); // Custom middleware or built-in if available

// Example of how LogContext can be used within middleware or controllers:
public class RequestLoggingMiddleware
{
 private readonly RequestDelegate _next;

 public RequestLoggingMiddleware(RequestDelegate next)
 {
 _next = next;
 }

 public async Task InvokeAsync(HttpContext context, ILogger<RequestLoggingMiddleware> logger)
 {
 var requestId = Guid.NewGuid().ToString();
 // Push the request ID into the log context for this request
 using (LogContext.PushProperty("RequestId", requestId))
 {
 context.Response.Headers.Add("X-Request-ID", requestId);
 await _next(context);
 }
 }
}

// In a controller, logs will now automatically include 'RequestId'
public class HomeController : Controller
{
 private readonly ILogger<HomeController> _logger;

 public HomeController(ILogger<HomeController> logger)
 {
 _logger = logger;
 }

 public IActionResult Index()
 {
 _logger.LogInformation("Processing request for the home page."); // This log will have RequestId
 return View();
 }
}

When the Index action is executed, the log message “Processing request for the home page.” will automatically be associated with the generated RequestId, making it easy to correlate logs related to a specific incoming web request.

Mastering Serilog Filtering and Log Levels

Effective logging isn’t just about capturing everything. it’s about capturing the right information at the right time. Serilog provides granular control over which log events are processed and outputted through its filtering and log level mechanisms.

Log Levels:

Serilog supports standard log levels, typically:

  • Verbose: Detailed information, typically only of interest when diagnosing problems.
  • Debug: Routine operational messages, used for debugging.
  • Information: General messages about application flow and significant events.
  • Warning: An event that indicates a potential problem or an unexpected, but recoverable, situation.
  • Error: An event that indicates a failure in the application or a service.
  • Fatal: A severe error event that will likely cause the application to terminate.

You set a MinimumLevel when configuring the logger. Any log event with a level below this minimum will be discarded immediately, saving processing and I/O overhead. For example, setting MinimumLevel.Information() means Verbose and Debug messages won’t be processed.

Overriding Log Levels:

It’s common to want to adjust the minimum level for specific namespaces or third-party libraries. For instance, you might want to see Debug logs from your own code but only Warning logs from the verbose Microsoft framework logs:


Log.Logger = new LoggerConfiguration().MinimumLevel.Debug() // Default minimum level.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // Override for Microsoft namespace.MinimumLevel.Override("MyApplication.Services", LogEventLevel.Verbose) // Increase verbosity for specific services.WriteTo.Console().CreateLogger();

Filtering Sinks:

You can also apply filters to individual sinks. This allows you to send different types or levels of logs to different destinations. For example, sending only Error and Fatal logs to a critical alerts system, while sending all logs to a general file.


Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information) // Console shows Info and above.WriteTo.File("logs/errors.txt",
 rollingInterval: RollingInterval.Day,
 restrictedToMinimumLevel: LogEventLevel.Error) // File only gets Errors and Fatals.CreateLogger();

This approach ensures that your most critical logs are captured and routed appropriately without being drowned out by less important information.

Practical Serilog Use Cases and Examples

Serilog’s versatility makes it suitable for a lots of scenarios in.NET development.

1. Debugging Web API Issues:

When a Web API endpoint is returning unexpected results or errors, Serilog can provide the necessary context. By logging request details, parameters, internal processing steps, and response data, developers can quickly pinpoint the source of the problem.


public class ProductsController : ControllerBase
{
 private readonly IProductService _productService;
 private readonly ILogger<ProductsController> _logger;

 public ProductsController(IProductService productService, ILogger<ProductsController> logger)
 {
 _productService = productService;
 _logger = logger;
 }

 [HttpGet("{id}")]
 public IActionResult GetProduct(int id)
 {
 _logger.LogInformation("Attempting to retrieve product with ID: {ProductId}", id);
 try
 {
 var product = _productService.GetById(id);
 if (product == null)
 {
 _logger.LogWarning("Product with ID: {ProductId} not found.", id);
 return NotFound();
 }
 _logger.LogInformation("Successfully retrieved product: {ProductName}", product.Name);
 return Ok(product);
 }
 catch (Exception ex)
 {
 _logger.LogError(ex, "An unexpected error occurred while retrieving product with ID: {ProductId}", id);
 return StatusCode(500, "An internal server error occurred.");
 }
 }
}

In this example, structured properties like {ProductId} and {ProductName} make querying for specific product lookups extremely efficient.

2. Monitoring Background Services:

For.NET Worker Services or background tasks, Serilog is essential for tracking progress, identifying failures, and understanding resource utilization.


public class MyBackgroundService : BackgroundService
{
 private readonly ILogger<MyBackgroundService> _logger;
 private readonly IConfiguration _configuration;

 public MyBackgroundService(ILogger<MyBackgroundService> logger, IConfiguration configuration)
 {
 _logger = logger;
 _configuration = configuration;
 }

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 {
 while (!stoppingToken.IsCancellationRequested)
 {
 _logger.LogInformation("Background service running at: {Timestamp:G}", DateTimeOffset.Now);
 try
 {
 // Simulate work
 await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
 ProcessData();
 }
 catch (Exception ex)
 {
 _logger.LogError(ex, "An error occurred during background service execution.");
 }
 }
 }

 private void ProcessData()
 {
 // Simulate a potential issue
 if (DateTime.Now.Second % 15 == 0)
 {
 _logger.LogWarning("Potential data processing issue detected at {Timestamp:G}", DateTimeOffset.Now);
 }
 _logger.LogDebug("Data processed successfully.");
 }
}

3. Auditing User Actions:

For security and compliance, logging user actions is critical. Serilog can capture who did what, when, and from where.


public void DeleteUser(int userId, ClaimsPrincipal user)
{
 var currentUserName = user.Identity?.Name ?? "Anonymous";
 _logger.LogInformation("User '{UserName}' initiated deletion of user ID: {TargetUserId}", currentUserName, userId);

 //... perform deletion logic...

 _logger.LogInformation("User ID {TargetUserId} deleted successfully by '{UserName}'.", userId, currentUserName);
}

By enriching logs with user identity (often pushed via LogContext in web applications), these audit trails become solid and easily searchable.

Advanced Serilog Configurations

Beyond basic setup, Serilog offers advanced features for fine-tuning your logging strategy.

1. Using `appsettings.json` for Configuration:

For larger applications, managing Serilog configuration directly in code can become cumbersome. Serilog supports reading its configuration from appsettings.json — which is a more maintainable approach, especially in dynamic environments.

First, install the Serilog.Settings.Configuration NuGet package:

dotnet add package Serilog.Settings.Configuration

Then, configure appsettings.json:


{
 "Serilog": {
 "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],
 "MinimumLevel": {
 "Default": "Information",
 "Override": {
 "Microsoft": "Warning",
 "Microsoft.AspNetCore": "Warning"
 }
 },
 "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
 "WriteTo": {
 "Console": [
 {
 "Name": "Console"
 }
 ],
 "File": [
 {
 "Name": "File",
 "Args": {
 "path": "logs/appsettings_log-.txt",
 "rollingInterval": "Day",
 "shared": true
 }
 }
 ]
 }
 }
}

In your Program.cs, load this configuration:


// In Program.cs
builder.Host.UseSerilog((context, configuration) =>
{
 configuration.ReadFrom.Configuration(context.Configuration.GetSection("Serilog")).Enrich.FromLogContext();
});

2. Custom Log Levels and Properties:

While Serilog has standard levels, you can define custom levels or, more commonly, use structured properties to categorize logs. For example, you might have events related to different modules or features.

You can push properties using LogContext.PushProperty:


using Serilog.Context;

public void PerformComplexOperation(int orderId)
{
 using (LogContext.PushProperty("OperationType", "OrderProcessing"))
 using (LogContext.PushProperty("OrderId", orderId))
 {
 _logger.LogInformation("Starting complex operation for order.");
 //... operation logic...
 _logger.LogInformation("Finished complex operation for order.");
 }
}

These properties become searchable fields in your log analysis tools.

3. Performance Considerations:

For high-throughput applications, logging can become a bottleneck. Serilog offers features to mitigate this:

  • Asynchronous Sinks: Many sinks support asynchronous writing, preventing logging operations from blocking the main application threads.
  • Batching: Sinks like Seq and Elasticsearch often batch log events before sending them, reducing network overhead.
  • Minimizing Logging Verbosity: Use appropriate log levels and avoid excessive logging in performance-critical code paths.
  • Optimized Formatters: Using efficient formats like JSON can speed up serialization and parsing.

Serilog and Modern Observability

In the evolving world of software development, observability has become really important. Serilog plays a vital role in enabling solid observability strategies for.NET applications.

Integration with Observability Platforms:

Serilog’s flexibility allows it to integrate smoothly with leading observability platforms. As previously mentioned, its integration with Azure Application Insights is a common pattern for cloud-native applications. Similarly, using sinks for Elasticsearch or directly sending logs to cloud provider services (AWS CloudWatch, Google Cloud Logging) allows for centralized data aggregation, advanced analysis, and correlation with other telemetry data like metrics and traces.

Structured Logging as the Foundation:

Modern observability relies heavily on structured data. Serilog’s core strength in structured logging means that log data isn’t just a stream of text but a rich dataset. This enables powerful querying, filtering, and visualization in tools like Kibana, Grafana, or specialized log management solutions. The ability to filter logs by specific fields (e.g., UserId, CorrelationId, ExceptionType) is fundamental for quickly identifying and diagnosing issues in complex systems.

Correlation Across Services:

In microservices architectures, tracing a request across multiple services is challenging. Serilog, when configured with correlation IDs (often managed via HTTP headers and propagated through requests), allows developers to follow a single request’s journey through the entire system. Each service logs its part of the operation, including the shared correlation ID, making it possible to reconstruct the full flow in the observability platform.

Frequently Asked Questions

what’s the difference between Serilog and Microsoft.Extensions.Logging?

Microsoft.Extensions.Logging is the abstraction provided by the.NET ecosystem for logging. Serilog is a concrete logging provider that implements this abstraction. You can configure your ASP.NET Core application to use Serilog as its logging provider, replacing the default one. Serilog offers more advanced features, especially in structured logging and sink flexibility, compared to the basic logging abstraction.

How do I configure Serilog to log to multiple files?

You can achieve this by adding multiple WriteTo.File calls in your LoggerConfiguration. For example, one for daily logs and another for hourly logs, or one for application logs and another for security audit logs, potentially with different `restrictedToMinimumLevel` settings.

Is Serilog thread-safe?

Yes, Serilog is designed to be thread-safe. The logging methods (like LogInformation, LogError) can be called concurrently from multiple threads without causing data corruption or race conditions. The library handles internal synchronization to ensure log events are processed correctly.

How can I view Serilog logs in real-time?

Using a sink like Serilog.Sinks.Seq is an excellent way to view logs in real-time. Seq provides a web-based interface where logs appear as they’re written. Other options include using real-time tailing features in log aggregation platforms like Elasticsearch/Kibana or cloud monitoring services.

What are the performance implications of using Serilog?

While Serilog is generally performant, excessive logging, especially at verbose levels in high-throughput scenarios, can impact performance. However, Serilog provides mechanisms to mitigate this, such as asynchronous sinks, batching, and efficient structured logging. For most applications, the performance overhead is negligible compared to the benefits of detailed logging. Careful configuration and appropriate log level management are key.

Conclusion

Serilog has firmly established itself as a best-in-class logging library for.NET developers in 2026. Its commitment to structured logging, extensive sink support, and powerful enrichment capabilities provide unparalleled visibility into application behavior. By implementing Serilog effectively, developers can accelerate debugging, enhance application monitoring, and build more reliable and observable systems. Whether you’re working on a small utility or a large-scale distributed system, mastering Serilog is a worthwhile investment for any.NET professional.