Logging in C# (.NET): Overview of the Best Solutions
Logging is not just about recording errors. It is a fundamental tool for monitoring application state, auditing user actions, and debugging in a production environment. In the C# (.NET) ecosystem, there are several mature libraries, each solving the logging task in its own way. In this article, we will break down the most popular solutions: NLog, Serilog, log4net, and the built-in Microsoft.Extensions.Logging.
1. Microsoft.Extensions.Logging (Built-in ILogger)
Starting with .NET Core, Microsoft provides an abstraction for logging — the ILogger<T> interface and the ILoggerFactory factory. This is not a full-fledged library, but a contract to which any implementation (NLog, Serilog, etc.) can be connected.
Pros: built into ASP.NET Core, requires no additional dependencies for basic logging, easily replaceable with another library.
Cons: limited functionality out of the box (only levels: Trace, Debug, Information, Warning, Error, Critical). No structured data.
Usage example:
using Microsoft.Extensions.Logging;
public class OrderService{ private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger) { _logger = logger; }
public void ProcessOrder(int orderId) { _logger.LogInformation("Processing order {OrderId}", orderId); try { // Processing logic } catch (Exception ex) { _logger.LogError(ex, "Error processing order {OrderId}", orderId); } }}2. Serilog (Structured Logging)
Serilog is the leader in flexibility and popularity. Its main feature is structured logging. Instead of string messages, you pass objects that are automatically serialized into JSON or another format. This makes it easy to analyze logs via Elasticsearch, Seq, or Grafana.
Pros: excellent integration with .NET, powerful enrichers (context enrichment), support for sinks (output to file, database, console, cloud services).
Cons: can be overkill for simple applications, requires configuration.
Configuration and usage example:
using Serilog;
// Configuration in Program.csLog.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .WriteTo.File("logs/myapp-.log", rollingInterval: RollingInterval.Day) .WriteTo.Seq("http://localhost:5341") .Enrich.WithProperty("Application", "MyApp") .CreateLogger();
try{ Log.Information("Starting application"); var user = new { Id = 1, Name = "Ivan" }; Log.Information("User {User} logged in", user);}catch (Exception ex){ Log.Fatal(ex, "Critical error");}finally{ Log.CloseAndFlush();}3. NLog (Performance and Flexibility)
NLog is another powerful framework with a rich history. It is known for its performance and support for complex routing rules. Configuration can be set both in an XML file (nlog.config) and programmatically.
Pros: very fast, supports asynchronous logging, can send logs via email, to databases, to EventLog. Excellent support for .NET Framework and .NET Core.
Cons: XML configuration syntax can seem cumbersome.
Example of nlog.config configuration:
<?xml version="1.0" encoding="utf-8" ?><nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets>