Home > database >  Serilog loses List<object> property values when serializing
Serilog loses List<object> property values when serializing

Time:10-13

Edit1: as pointed by @CodingMytra JsonConvert.SerializeObject(log) serializes good to valid C# string form (meaning it has escape symbols \). The problem rises on Serilog.Sinks.File and Serilog.Sinks.MSSqlServer sinks as they take it as raw value (with escape \ symbols).

File sink uses JSON type

"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",

SQLServer sink has LogEvent that stores JSON

"addStandardColumns": [ "LogEvent" ],

Serilog.Sinks.Console outputs to console without escape characters (maybe it's same conversion as Console.WriteLine()). Text visualizer/json on debugger will get rid of escape characters too. Default Serilog serializer takes into account valid JSON and saves without escape backslash but I have to use Newtonsoft because Serilog serializer doesn’t work with ArrayList/List<object> (original post problem).

I tried getting rid of backslash with

var token = JToken.Parse(JsonConvert.SerializeObject(log)); //{"Properties":{"Log":[[[]],[[]],[[[[[]],[[]]]]],[[]],[[]],[[]],[[]]]}}
var myCleanJsonObject = JObject.Parse(JsonConvert.SerializeObject(log)); //{"Properties":{"Log":[[[]],[[]],[[[[[]],[[]]]]],[[]],[[]],[[]],[[]]]}}
string cleanJson = Regex.Unescape(JsonConvert.SerializeObject(log)); // still has backslashes
string jsonString = JsonConvert.SerializeObject(log).Replace("\\", string.Empty); // still has backslashes

but it either loses object on logging or still has backslashes.

How can I make

_logger.LogInformation("Angular logging {Log}", JsonConvert.SerializeObject(log));

save valid JSON into File/MSSQLServer sinks (meaning without escape symbols)?


Original: I’m having problem transforming object to JSON with Serilog.

Problem: Property List<object> gets destructed into [[[[]],[[]]]].

I log events on Angular with ngx-logger and send to my ASP .NET 6 backend endpoint

    [HttpPost("logs")]
    public IActionResult SaveFrontendLog([FromBody] LogDto log)
    {
        _logger.LogInformation("Serilog Destruct 1 {@Log}", log, log.Additional);
        _logger.LogInformation("JsonConvert Serialize 2 {@Log}", JsonConvert.SerializeObject(log));
        return Ok();
    }

public class LogDto
{
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public NgxLoggerLevel Level { get; set; }
    public string Message { get; set; }
    public List<object> Additional { get; set; } // <<<<<
    public DateTime Timestamp { get; set; }
    public string FileName { get; set; }
    public int LineNumber { get; set; }
    public int ColumnNumber { get; set; }
}

Here is the POST api/logs request body:

{"level":2,"additional":[{"editionId":"fe8a19f9-838a-4c8e-9e9e-0f9041b7f5a6","url":"https://valor-software.com/ngx-bootstrap/#/components/popover?tab=api"}],"message":"Viewed URL edition","timestamp":"2022-10-11T14:08:25.795Z","fileName":"main.js","lineNumber":13191,"columnNumber":19}

Received object: enter image description here

Api endpoint two logging results:

_logger.LogInformation("JsonConvert Serialize 2 {@Log}", JsonConvert.SerializeObject(log)):

{"Properties":{"Log":"{\"Level\":2,\"Message\":\"Viewed URL edition\",\"Additional\":[{\"editionId\":\"fe8a19f9-838a-4c8e-9e9e-0f9041b7f5a6\",\"url\":\"https://valor-software.com/ngx-bootstrap/#/components/popover?tab=api\"}],\"Timestamp\":\"2022-10-11T14:08:25.795Z\",\"FileName\":\"main.js\",\"LineNumber\":13191,\"ColumnNumber\":19}"}}

Need like shown below but with all values

_logger.LogInformation("Serilog Destruct 1 {@Log}", log): 

{"Properties":{"Log":{"Level":"INFO","Message":"Viewed URL edition","Additional":[[[[]],[[]]]],"Timestamp":"2022-10-11T14:08:25.7950000Z","FileName":"main.js","LineNumber":13191,"ColumnNumber":19}}}

I need to have object stored without special characters that I could query it on t-SQL. Result JSON should be like Serilog destruct but it should have “Additional” properties. How can I make it work (not lose values)?

CodePudding user response:

if you use System.Text.Json.Serialization instead of Newtonsoft.Json like below.

_logger.LogInformation("JsonConvert Serialize 2 {@Log}", JsonSerializer.Serialize(log));

then you will get log printed in your desired format without any special character like this.

enter image description here

Hope it helps.

CodePudding user response:

I added Destructurama.JsonNet to Serilog config to enable dynamic types and now none of my samples (LogDto, JObject/JToken) produce empty brackets and saves to File/MSSqlServer sinks as valid JSON.

This is producing whole object now:

_logger.LogInformation("Angular logging {@Log}", log);
  • Related