elastic / ecs-dotnet

https://www.elastic.co/guide/en/ecs-logging/dotnet/current/setup.html
Apache License 2.0
108 stars 54 forks source link

[BUG] Messages properties when objects serialized incorrectly. #385

Closed thompson-tomo closed 1 month ago

thompson-tomo commented 2 months ago

ECS integration/library project(s) (e.g. Elastic.CommonSchema.Serilog): Elastic.CommonSchema.NLog

ECS schema version (e.g. 1.4.0): 8.11

ECS .NET assembly version (e.g. 1.4.2): 8.11

.NET framework / OS: Net 8

Description of the problem, including expected versus actual behavior: When i am passing objects into my log events they are not being serialized as individual properties but rather the ToString of the object

Steps to reproduce:

  1. Setup your application to generate a log line
MetricDef metricDef = new MetricDef()
_logger.LogInformation(new EventId(88, "Event88"), "Number is {num} and key is {metricDef.Key}", num.ToString(), metricDef);
  1. Observe Log generated as below
{"@timestamp":"2024-05-26T20:45:14.3990603+10:00","log.level":"Info","message":"Number is 10 and key is Skidata.Dashboard.Models.MetricDef","labels":{"num":"10","metricDef.Key":"Skidata.Dashboard.Models.MetricDef","EventName":"Event88","agent":{"type":"Elastic.CommonSchema.NLog","version":"8.11.0\u002B20346170742d13e4c2b26ef5c7aaad534970f06b"},"event":{"code":"88","created":"2024-05-26T20:45:14.3990603+10:00","duration":367244451000,"kind":"metric","severity":6,"timezone":"AUS Eastern Standard Time"},"metadata":{"EventId":88},"MessageTemplate":"Number is {num} and key is {metricDef.Key}"}

5.

The expectation is that it would operate as per the microsoft logging ie use the property from the object passed it and in terms of labels each property should be logged as a seperate label using dotted notation.

thompson-tomo commented 2 months ago

Note this could very well be an issue with Microsoft.Extensions.Logging but don't believe so based on the fact that the original object being available in the logevent properties dictionary.

Mpdreamz commented 1 month ago

You need to use @ to force a json like value in your message see:

https://github.com/NLog/NLog/wiki/How-to-use-structured-logging#formatting-of-the-message

e.g:

MetricDef metricDef = new MetricDef()
_logger.LogInformation(new EventId(88, "Event88"), "Number is {num} and key is {@metricDefKey}", num.ToString(), metricDef);
thompson-tomo commented 1 month ago

thanks @Mpdreamz will discuss with NLOG project how i can achieve what i am looking for. As the both example doesn't quite do it as i want my log message to have only 1 property "key" from my class but happy for other properies to be added as labels., Anyway will close this issue as doesn't appear to be an elastic issue

Mpdreamz commented 1 month ago

You could send the key as an anonymous object instead?

new { Key = metricDef.Key }

Combined with @ for structured representation in the message itself?

I might not have fully understood the problem though :)

thompson-tomo commented 1 month ago

no worries, thanks for the input. For reference I am looking to have all properties from object added as labels and only 1 or more of the properties to be substituted into the message.

thompson-tomo commented 1 month ago

So after spending some more time on this, I have managed to get close to what I want by using log generators. with the fix for #397 the most desired outcome will be possible which is to Populate ecs fields with user defined info with minimal effort provided it isn't more the 2 levels deep.