Introduction
In modern enterprise applications, logs are your first line of defense against production issues.
When your system runs across multiple APIs, microservices, and background jobs, collecting and analyzing logs becomes a challenge.
That’s where Centralized Logging comes in — a single place to collect, search, and analyze logs in real time.
In this article, you’ll learn how to build a Centralized Logging and Monitoring system using:
Serilog for structured logging in ASP.NET Core
Elastic Stack (ELK) — Elasticsearch, Logstash, and Kibana — for log aggregation, processing, and visualization
Why Centralized Logging?
Let’s say you’re running a web application with multiple APIs.
When a user reports,
“Something failed when placing an order,”
you might have to check multiple log files across servers to find what went wrong.
Centralized logging solves that by:
Storing all logs in one place
Making logs searchable and filterable
Offering real-time dashboards and alerts
Enabling pattern detection for performance or security issues
Architecture Overview
Here’s how everything connects:
ASP.NET Core App
│
▼
[Serilog]
│
▼
[Logstash]
│
▼
[Elasticsearch]
│
▼
[Kibana Dashboard]
Explanation
ASP.NET Core app writes structured logs via Serilog .
Logs are sent to Logstash , which parses and processes them.
Elasticsearch stores and indexes logs efficiently.
Kibana visualizes the logs in dashboards and reports.
Step 1: Setting Up ELK Stack
Option 1: Using Docker (Recommended for Local Setup)
Create a docker-compose.yml file:
version: '3.3'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ports:
- "9200:9200"
logstash:
image: docker.elastic.co/logstash/logstash:8.10.0
ports:
- "5044:5044"
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:8.10.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
Logstash Configuration Example ( logstash.conf )
input {
tcp {
port => 5044
codec => json_lines
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "aspnetcore-logs-%{+YYYY.MM.dd}"
}
}
Step 2: Add Serilog to an ASP.NET Core Project
Install NuGet packages
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
dotnet add package Serilog.Sinks.Network
Step 3: Configure Serilog in Program.cs
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Configure Serilog
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("Logs/app-.log", rollingInterval: RollingInterval.Day)
.WriteTo.TCPSink("localhost", 5044) // Send to Logstash
.CreateLogger();
builder.Host.UseSerilog();
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();

Join the conversation! Your thoughts help the community grow.