Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
Asp.Net Core

.NET Core: Structured Logging with Serilog

- 25.07.26 - ErcanOPAK

📝 Serilog = Structured Logging

Text logs are hard to search. Serilog provides structured logging with rich data for better observability.

📝 Serilog Setup

// Program.cs
using Serilog;

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console()
    .WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
    .WriteTo.Elasticsearch()
    .Enrich.WithProperty("Application", "MyApp")
    .Enrich.WithProperty("Environment", "Production")
    .CreateLogger();

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();

// appsettings.json
{
    "Serilog": {
        "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],
        "MinimumLevel": "Information",
        "WriteTo": [
            { "Name": "Console" },
            { 
                "Name": "File", 
                "Args": { 
                    "path": "logs/app.log", 
                    "rollingInterval": "Day" 
                }
            }
        ],
        "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"]
    }
}

🎯 Structured Logging

// Traditional (bad)
_logger.LogInformation($"User {user.Id} logged in at {DateTime.Now}");

// Structured (good)
_logger.LogInformation("User {UserId} logged in at {LoginTime}", 
    user.Id, DateTime.UtcNow);

// With context
_logger.LogInformation(
    "User {UserId} purchased {ProductName} for {Price:C}",
    user.Id, product.Name, product.Price);

// Error with details
try {
    // operation
} catch (Exception ex) {
    _logger.LogError(ex, 
        "Failed to process order {OrderId} for user {UserId}",
        order.Id, order.UserId);
}

// Using ForContext
var userLogger = _logger.ForContext("User", user);
userLogger.LogInformation("User logged in");

// Correlation IDs
using (_logger.BeginScope(new { CorrelationId = correlationId }))
{
    // All logs in this scope include CorrelationId
    _logger.LogInformation("Processing request");
}

// Timed operations
using var timer = _logger.BeginTimedOperation("Database query", 
    new { Query = sql, Parameters = parameters });
var result = await db.QueryAsync(sql, parameters);

💡 Logging Best Practices

  • Use structured logging
  • Include correlation IDs
  • Log at appropriate levels
  • Use property names consistently
  • Don’t log sensitive data

Structured logging transforms debugging from guesswork to science. It’s essential for modern applications.

— Observability Engineer

Related posts:

.NET Core: Enable Response Compression for Smaller Payloads

ASP.NET Core Dependency Injection: Master the Container

.NET Core: Build Background Tasks with Worker Services

Post Views: 8

Post navigation

Git: Master Cherry-Pick for Selective Commits
SQL: Optimize Performance with Stored Procedures

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

October 2026
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  
« Sep    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (973)
  • How to make theater mode the default for Youtube (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (939)
  • Get the First and Last Word from a String or Sentence in SQL (847)
  • How to select distinct rows in a datatable in C# (837)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (624)
  • Add Constraint to SQL Table to ensure email contains @ (590)
  • Average of all values in a column that are not zero in SQL (553)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (526)
  • Find numbers with more than two decimal places in SQL (468)

Recent Posts

  • CSS: Fix a prefers-color-scheme Media Query That Gets Silently Overridden by a Browser Extension’s Forced Dark Mode
  • Git: Fix a Merge Commit That Silently Drops a File Because Both Branches Deleted It Differently
  • HTML5: Fix a Native Lazy-Loading Image That Never Loads Because It Sits Inside a Hidden Tab Until the User Clicks It
  • The AI Prompt That Traces a Null Reference Exception Back to the Exact Line That First Produced the Null
  • The AI Prompt That Turns a Gym Membership Contract’s Fine Print Into a Plain-English List of Cancellation Steps
  • Photoshop: Fix a Color Profile Mismatch That Makes Printed Output Look Nothing Like What You Saw On Screen
  • WordPress: Fix Search Results That Return Pages From a Theme You Deactivated Months Ago
  • Visual Studio: Fix a Test Project That Builds Fine Alone but Fails to Discover Any Tests After a NuGet Restore
  • ASP.NET Core: Fix a File Upload That Times Out on Slow Connections Only Because Kestrel’s Minimum Data Rate Feature Kicked In
  • JavaScript: Fix an Array Destructuring Default Value That Silently Never Applies Because null Was Passed Instead of Undefined

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (973)
  • How to make theater mode the default for Youtube (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (939)
  • Get the First and Last Word from a String or Sentence in SQL (847)
  • How to select distinct rows in a datatable in C# (837)

Recent Posts

  • CSS: Fix a prefers-color-scheme Media Query That Gets Silently Overridden by a Browser Extension’s Forced Dark Mode
  • Git: Fix a Merge Commit That Silently Drops a File Because Both Branches Deleted It Differently
  • HTML5: Fix a Native Lazy-Loading Image That Never Loads Because It Sits Inside a Hidden Tab Until the User Clicks It
  • The AI Prompt That Traces a Null Reference Exception Back to the Exact Line That First Produced the Null
  • The AI Prompt That Turns a Gym Membership Contract’s Fine Print Into a Plain-English List of Cancellation Steps

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com