Introduction: Why is Logging Important?
\n\nImagine your C# application is running in production. Suddenly, users report an error, but you can't figure out what went wrong. Without logs, you are like a pilot without instruments. Logging is the process of recording information about the application's operation: errors, warnings, debug messages, and key events.
\n\nIn this article, we will cover the best logging practices for beginner C# (.NET) developers. You will learn how to set up logging, which tools to use, and how to avoid common mistakes.
\n\n1. Choosing a Logging Tool in C#
\n\nIn the .NET ecosystem, there are several popular logging libraries. For beginners, we recommend three main options:
\n\n1.1. Built-in ILogger (Microsoft.Extensions.Logging)
\n\nStarting with .NET Core, Microsoft provides the built-in ILogger interface. It is simple to use and does not require installing third-party libraries.
using Microsoft.Extensions.Logging;\n\npublic class OrderService\n{\n private readonly ILogger<OrderService> _logger;\n\n public OrderService(ILogger<OrderService> logger)\n {\n _logger = logger;\n }\n\n public void ProcessOrder(int orderId)\n {\n _logger.LogInformation("Processing order {OrderId}", orderId);\n // Processing logic\n }\n}\n\n1.2. Serilog — Flexible and Powerful
\n\nSerilog is one of the most popular libraries. It supports structured logging, making data analysis easy. Install via NuGet: Install-Package Serilog.AspNetCore
using Serilog;\n\npublic class Program\n{\n public static void Main(string[] args)\n {\n Log.Logger = new LoggerConfiguration()\n .MinimumLevel.Debug()\n .WriteTo.Console()\n .WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)\n .CreateLogger();\n\n try\n {\n Log.Information("Application started");\n CreateHostBuilder(args).Build().Run();\n }\n catch (Exception ex)\n {\n Log.Fatal(ex, "Application terminated with an error");\n }\n finally\n {\n Log.CloseAndFlush();\n }\n }\n}\n\n1.3. NLog — Classic Choice
\n\nNLog is another mature library with extensive configuration options via configuration files.
\n\n// Configuration via appsettings.json\n{\n "NLog": {\n "targets": {\n "console": {\n "type": "Console",\n "layout": "${longdate}|${level:uppercase=true}|${message}"\n },\n "file": {\n "type": "File",\n "fileName": "logs/app.log",\n "layout": "${longdate}|${level:uppercase=true}|${message}"\n }\n },\n "rules": [\n { "logger": "*", "minLevel": "Info", "writeTo": "console,file" }\n ]\n }\n}\n\n2. Log Levels: When to Use What
\n\nProper use of log levels is the foundation of good practice. In C# (.NET), the following levels are defined (from most critical to least):
\n\n- \n
- Trace (0) — extremely detailed debug information. Used only for deep diagnostics. \n
- Debug (1) — debug messages for developers. Enabled in development environments but disabled in production. \n
- Information (2) — general informational messages about application operation (startup, successful operations). \n
- Warning (3) — warnings about potential issues that are not errors (e.g., exceeding execution time). \n
- Error (4) — errors that require attention but are not fatal to the application. \n
- Critical (5) — critical errors after which the app