Modern web applications need more than just features — they need visibility. Without proper logging and diagnostics, identifying failures, understanding user behavior, and measuring system health becomes nearly impossible. ASP.NET Core provides a unified logging and diagnostics system that brings consistency, performance, and extensibility into application monitoring.
The goal of unified logging is simple: log once in your application and route the log output anywhere — console, files, cloud services, databases, or observability platforms — without changing your application code.
![ilogger-diagram]()
Why Logging Matters in Production
Logging is essential for:
Without logging, you’re blind.
Logging Architecture in ASP.NET Core
ASP.NET Core uses a provider-based logging architecture. You write logs using ILogger, and the framework sends those logs to multiple logging providers such as:
Console
Debug window
Event Viewer
File-based logs (Serilog, NLog)
Cloud providers (Azure App Insights, AWS CloudWatch)
Centralized log systems (ELK, Datadog)
Basic Logging Example
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Home page accessed");
return View();
}
}
ASP.NET Core automatically injects ILogger<T> via dependency injection.
Log Severity Levels
ASP.NET Core supports standard log levels:
| Level | Purpose |
|---|
| Trace | Detailed debugging |
| Debug | Developer diagnostics |
| Information | Normal events |
| Warning | Unexpected but handled |
| Error | Failures |
| Critical | Application crash |
Example:
_logger.LogError("Payment failed for UserId: {UserId}", userId);
Structured Logging
Instead of writing plain strings, ASP.NET Core promotes structured logging, allowing logs to contain key-value data.
_logger.LogInformation("Order {OrderId} processed for {Customer}", orderId, customerName);
This produces searchable and filterable logs in centralized systems.
Configuring Logging in appsettings.json
{"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}}}
Change log level without redeploying your app.
Logging Providers
Console Logging
Enabled by default:
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
Debug Output
builder.Logging.AddDebug();
File Logging (Using Serilog)
Install:
dotnet add package Serilog.AspNetCore
Configure:
builder.Host.UseSerilog((ctx, config) =>
{
config.WriteTo.File("logs/app.log");
});
Middleware-Based Logging
Log every incoming request:
app.Use(async (context, next) =>
{
var logger = context.RequestServices
.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Request: {method} {url}",
context.Request.Method, context.Request.Path);
await next();
});
Centralized Exception Logging
Global error handling:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exception = context.Features.Get<IExceptionHandlerFeature>()?.Error;
var logger = context.RequestServices.GetRequiredService<ILogger<Program>>();
logger.LogError(exception, "Unhandled exception");
await context.Response.WriteAsync("Something went wrong");
});
});
Diagnostic Tools
ASP.NET Core provides advanced diagnostic tools:
Built-In Metrics
Use .NET counters:
dotnet counters monitor
Health Checks
builder.Services.AddHealthChecks();
app.MapHealthChecks("/health");
Distributed Tracing
Logs alone are not enough in microservices. ASP.NET Core supports distributed tracing.
OpenTelemetry Example
builder.Services.AddOpenTelemetryTracing(builder =>
{
builder.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddJaegerExporter();
});
Traces flow across services.
Application Insights (Azure)
builder.Services.AddApplicationInsightsTelemetry();
Instant visibility into:
Errors
Performance
Dependencies
CPU / memory usage
Request flow
Correlation IDs
Trace requests across systems:
app.Use(async (context, next) =>
{
var correlationId = Guid.NewGuid().ToString();
context.Items["CID"] = correlationId;
var logger = context.RequestServices.GetRequiredService<ILogger<Program>>();
logger.LogInformation("CorrelationId: {CID}", correlationId);
await next();
});
Diagnostics with Activity API
using System.Diagnostics;
var activity = new Activity("DatabaseCall");
activity.Start();
// perform work
activity.Stop();
Logging Best Practices
✅ Never log secrets
✅ Always use structured logging
✅ Log exceptions with stack trace
✅ Use correlation IDs
✅ Enable metrics
✅ Centralize log storage
✅ Set log level per environment
✅ Avoid excessive logging
✅ Automate alerting
Logging Strategy in SaaS
Production SaaS systems log:
Authentication events
Business transactions
API calls
Invoices
Performance metrics
Abuse attempts
Modern SaaS systems combine:
Performance Considerations
Keep logging efficient:
Avoid logging large objects
Do not log in tight loops
Prefer async logging
Use sampling
Use centralized logging system
Conclusion
Unified logging and diagnostics in ASP.NET Core is one of its strongest enterprise features. It gives developers a single logging abstraction that works across all environments and platforms.
With proper logging, you can:
Predict failures
Debug faster
Scale confidently
Maintain visibility
Improve reliability
If your application has users, traffic, and data — logging is not optional. It is infrastructure, just as important as code.