For the reasons that I will cover in the background at the end of this post, I need to escape new lines in both logged messages and exceptions printed to console using Serilog (i.e. convert \r
and \n
to \\r
and \\n
respectively). I created two enrichers - one for exceptions, another for messages - in which I perform the substitutions and register new values as EscapedMessage
and EscapedException
. The exception enricher works fine, but the problem with the message enricher is that the LogEvent
object does not contain the formatted message, it only holds the message template. To generate the message, I call RenderMessage
:
public class MessageEnricher: ILogEventEnricher
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
if (logEvent.MessageTemplate == null)
return;
string message = logEvent.RenderMessage();
var logEventProperty = propertyFactory.CreateProperty(
"EscapedMessage",
message
.Replace("\r", "\\r")
.Replace("\n", "\\n"));
logEvent.AddPropertyIfAbsent(logEventProperty);
}
}
The RenderMessage
call gives me the formatted message, but there is one problem: it always wraps string value placeholder substitutions in quotes, so I end up with text like:
Something happened to '"this"' or '"that"'.
Assuming that the logging code was like:
_logger.LogDebug($"Something happened to '{0}' or '{1}'.", "this", "that");
Is there a better way to escape new lines in messages or apply the lj
modifiers to the RenderMessage
call when formatting the message? I saw some posts (e.g. this one) suggesting that just applying the j
modifier to a log message takes care of the new lines, but it does not seem to be the case (I suspect it would take care of the new lines in the embedded object, but when I tried to apply it to a message containing a new line, it did nothing).
Background: The reason why I need new lines removed is because when logs are processed by Azure, each new line gets converted to a separate log entry, so we lose all context (timestamp, correlation ID, etc. defined in the log entry template header) in the subsequent log entries. And the reason why I want to escape the new lines (instead of replacing them with, say, white space) is because later, we send Azure logs to Splunk and Splunk can revert the escaped new lines back to real new lines.