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}
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)?
2
Answers
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:
if you use
System.Text.Json.Serialization
instead ofNewtonsoft.Json
like below.then you will get log printed in your desired format without any special character like this.
Hope it helps.