I'm trying to log to my Elasticsearch instance some data from .NET 6.0
Web Api with Serilog.AspNetCore and Serilog.Sinks.Elasticsearch installed, but I need to use custom properties for example:
- bankName
- totalValue
- customer.name
and others similar to this, but I created custom Enricher
:
public class ApiEnricher : ILogEventEnricher
{
private const string bankName = "Total Bank";
private const decimal totalValue = 21;
private const string customerName = "Adam";
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
// Add default values for required fields
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("bankName", bankName));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("total.value", totalValue));
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("cusotmer.name", cusomerName));
}
}
I tried to add this to my appsettings.json:
"Serilog": {
"Using": [ "Serilog.Sinks.Elasticsearch", "WebApi.Common" ],
"MinimumLevel": "Debug",
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "ApiEnricher" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "http://host.docker.internal:9200",
"indexFormat": "logs-myApp-example-{0:yyyy.MM}",
"autoRegisterTemplate": true,
"inlineFields": true,
"numberOfReplicas": 2,
"numberOfShards": 2
}
}
]
},
But with no luck, only example output I'm getting is:
{
"@timestamp": "2023-11-27T14:02:24.2061221+00:00",
"level": "Information",
"messageTemplate": "Example {bankName} {totalValue} {customerName}",
"message": "Example \"Forbank\" 21.0 \"Bar\"",
"bankName": "Forbank",
"totalValue": 21.0,
"customerName": "Bar",
"SourceContext": "WebApi.Controllers.SolutionController",
"ActionId": "1a52a98f-ecc6-40f2-a632-dc045d53811b",
"ActionName": "WebApi.Controllers.SolutionController.Init",
"RequestId": "0HMVFA5SJN8GJ:00000004",
"RequestPath": "/api/example/init",
"ConnectionId": "0HMVFA5SJN8GJ"
}
Logging with: logger.LogInformation("Example {bankName} {totalValue} {customerName}", bankName, 21, "Bar");
works but I want solution that does not enforce rewriting each logs, also if possible I want it to be configurable from appsettings.json
and I will prefer for those props to be only available on Elasticsearch sink.
EDIT:
Let me clarify where the question came from.
I received requirements from an external company regarding what the logs sent to Elastic should look like.
Among these requirements, I have a list of parameters that must appear in elastic, such as: user.name
, user.phone
, class
, exception
, etc.
And I was wondering if it could be done in some clever way without having to redo all the logs.
This could be done with just
appsettings.json
configuration, addingProperties
section, see this example from official docs: