Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serilog - How do I render formatted message to string manually?

I have written a logging framework that uses Log4Net, Nlog and Serilog interchangeably. Every call to the logger, fires an event before the log entry is written. This optionally pushes entries via SignalR to connected web clients.

Before the serilog addition, I used string.Format to get the formatted text. Now with that great destructuring has come great responsibility. string.Format obviously doesn't like {@0} or {data} in the string.

// log the event before engaging with the logger
LogEventBus.Handle(LogLevels.Info, DateTime.Now, msg, args);
if (DiagnosticLevel < level)
    return;
_logger.Info(msg, args);

Is there any way to get the serilog generated output, directly as string?

I started writing a memory sink, but that moves away from my centralised event based logging, and completely breaks away from the other libraries I have implemented.

Any suggestions?

like image 968
reckface Avatar asked Dec 06 '22 18:12

reckface


2 Answers

You can convert Serilog's message format to a standard .NET format string ({0} etc) like this:

var parser = new MessageTemplateParser();
var template = parser.Parse(templateMessage);
var format = new StringBuilder();
var index = 0;
foreach (var tok in template.Tokens)
{
    if (tok is TextToken)
        format.Append(tok);
    else
        format.Append("{" + index++ + "}");
}
var netStyle = format.ToString();

Once you have a standard format string you can pass this through or use string.Format() with it and args.

It's not going to be super-efficient - hooking deeper into the Serilog pipleine (ILogEventEnricher) should be better. As another commenter suggested, it may be better just to embrace a single logging framework here.

like image 55
Nicholas Blumhardt Avatar answered Jan 02 '23 03:01

Nicholas Blumhardt


Do your logging in two steps.

  1. Write log message to a TextWriter and read the value from the TextWriter (https://github.com/serilog/serilog/wiki/Provided-Sinks#textwriter)
  2. Write that already formatted value into the real logger

Whilst this might work, I worry about your architecture here. It all sounds like yuo are creating huge dependencies on Serilog, whilst you are also using several other logging frmeworks. Choose one logging framework OR use really generic features. C# has introduced string interpolation, not as fancy as Serilogs serialization etc, but works. I'd go back to KISS.

like image 36
Tamayi Avatar answered Jan 02 '23 04:01

Tamayi