Every application needs a log centralized log system and for that, in this article, I will configure ElasticSearch and Kibana in .NET core 6 using Serilog.
The first step is to install the docker desktop application on our machine (for production purposes it is recommended to use a VM).
Now let’s create a yml file for Elastic search and Kibana and save it as elk.yml:
services:
elasticsearch:
container_name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
ports:
- 9200:9200
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
environment:
- xpack.monitoring.enabled=true
- xpack.watcher.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
networks:
- customname
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:7.6.2
ports:
- 5601:5601
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_URL=http://localhost:9200
networks:
- customname
Now let’s run it on docker, using docker-compose up -d, and in the docker app, we’ll have 2 containers, 1 for Elastic search and 1 for Kibana. If everything is ready then we should have access to localhost:9200 for Elastic search and localhost:5601 for Kibana
Now, let’s start coding 🙂
In our .NET Core 6 application, we need to install some NuGet packages:
- Serilog.AspNetCore
- Serilog.Enrichers.Environment
- Serilog.Sinks.Debug
- Serilog.Sinks.ElasticSearch
Now configure in our program.cs file, add 2 new methods and after that call:
ConfigureLogging();
builder.Host.UseSerilog();
................................................................
void ConfigureLogging()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithEnvironmentName()
.WriteTo.Debug()
.WriteTo.Console()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment!))
.Enrich.WithProperty("Environment", environment!)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"]))
{
AutoRegisterTemplate = true,
IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}-{DateTime.UtcNow:yyyy-MM}"
};
}
Now in the appsettings.json change the Logging section with the code below and add the configuration for ElasticSearch:
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Error",
"System": "Warning"
}
}
},
"ElasticConfiguration": {
"Uri": "http://localhost:9200"
}
We are going to use Microsoft Error level because we want to define custom logs in our application. If you want to keep all the information from Microsoft you should keep Information.
Now, let’s create some logs in our application:
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("This is a wow message to test the logs");
return View();
}
Now let’s check in Kibana, to see our log message.
In this article, I used docker desktop to configure Elastic search and Kibana and Serilog in a .NET Core application.