Logging in C#: Best Practices for Beginner Developers

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Logging is the Foundation of a Stable Application



Any developer, especially a beginner, will sooner or later encounter a situation where the application crashes and the cause cannot be determined. Without logs, you are blind. Logging is not just writing messages to a file, but a powerful tool for monitoring, debugging, and analyzing program behavior. In the C# (.NET) ecosystem, there are several mature frameworks that allow flexible configuration of log output. In this article, we will break down the best logging practices for beginners: from choosing a library to structured data output.



1. Choosing a Logging Library: NLog vs Serilog



For .NET applications, there are two main players: NLog and Serilog. Both are free, actively maintained, and have thousands of integrations. Which one to choose?



NLog

  • Easy setup via XML or code.
  • Excellent performance under high loads.
  • Built-in support for file rotation, email sending, database logging.
  • Suitable for projects where a quick start is needed without extra dependencies.


Serilog

  • Focus on structured logging.
  • Logs are stored not as strings, but as objects with fields — this simplifies searching and analysis.
  • Ideal for microservices and systems where logs are collected in Elasticsearch or Grafana.
  • Syntax with placeholders {Property} makes code more readable.


Advice for beginners: Start with Serilog if you plan to work with modern monitoring tools. If the project is small and local, NLog will suffice.



// Example of Serilog setup in Program.cs (.NET 6+)using Serilog;

Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();

var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog(); // Connect Serilog to the host


2. Logging Levels: When and What to Write



One of the most common mistakes beginners make is writing everything at the Info or Error level. This clutters the logs and makes them useless. In .NET, the following levels are accepted (in increasing order of severity):



  • Trace — finest details: method entry/exit, loop iterations. Used only during deep debugging.
  • Debug — debugging information for the developer: variable values, object state.
  • Information — key application events: startup, shutdown, successful request processing.
  • Warning — potential issues that do not break operation: slow request, deprecated API version.
  • Error — exceptions and failures requiring intervention: database error, timeout.
  • Fatal — critical errors after which the application cannot continue running.


// Example of using different levelsILogger<MyService> _logger;

public async Task ProcessOrderAsync(int orderId){ _logger.LogInformation("Starting order processing {OrderId}", orderId);

try { var result = await _repository.GetOrderAsync(orderId); if (result == null) { _logger.LogWarning("Order {OrderId} not found", orderId); return; } // ... logic } catch (Exception ex) { _logger.LogError(ex, "Error processing order {OrderId}", orderId); throw; // Rethrow if recovery is not possible }}


Best practice

Blogs

Book Recommendations