How to log a message correlation Id with ServiceStack.Logging ILog?

1.4k views Asked by At

I'm very satisfied with the current logging solution I have in place right now, which is the ServiceStack Interface being implemented by NLOG. The NLOG targets I am using are as follows:

xsi:type="Console"

xsi:type="Debugger"

xsi:type="File"

xsi:type="Seq"

of particular importance is Seq which is a log receiver on steroids and my lifeline to whats happening real-time with my services. The ability to query the structured logs is absolutely fantastic, so much so that now I'd like to query the Seq logs looking for all the messages with the same correlation Id, which, according to this post is possible with an enricher:

using (LogContext.PushProperty("MessageId", GetCurrentMessageId()))
{
  Log.Information("Processing {OrderId}", message.Order.Id); 

  // Later
  Log.Information("Order processing complete");
} 

<target name="seq" xsi:type="Seq" serverUrl="http://localhost:5341">
  <property name="CallSite" value="${callsite}" />
  <property name="Logger" value="${logger}" />
  <property name="MachineName" value="${machinename}" />
  <property name="ThreadId" value="${threadid}" as="number" />

  <!-- would like to add the correlationId to the nlog properties here -->

</target>

Using the ServiceStack interface, I don't see a way to do it this way, but instead would have to pseudo-replicate it by making each log statement contain the correlationId in the message. i.e. _log.Warn("CorrelationId:{0} Campaign => no trackingId found".Fmt(request.CorrelationId));

Is there away to get the correlationId to be a first class citizen/property so that Seq will let me query by it?

Update based off of @paaschpas answer

Given that if you use the xxxxFormat methods on the logger interface (very important), you can now use this and supply the parameters in ordinal position (sort of fragile) e.g.

if (_log.IsDebugEnabled)
    _log.DebugFormat("CorrelationId:{0} CallReceived request:{1}", msgId, request.Dump());

Which will give you this Seq filtered by corrId at the end of the day, and that my friends is good enough for my needs.

2

There are 2 answers

2
paaschpa On BEST ANSWER

Is there away to get the correlationId to be a first class citizen/property so that Seq will let me query by it?

According to this it states "you can't used named properties in your NLog messages for querying in Seq, the @0 and @1 placeholders can be used in queries to identify the parameters to {0} and {1} in format strings." So if you use your pseudo-replicate of _log.Warn("CorrelationId:{0} Campaign => no trackingId found".Fmt(request.CorrelationId)); or ServiceStack's log.WarnFormat("correlationid {0}", "correlationid"); you can query/filter using @0 == "correlationid"

Using the ServiceStack interface, I don't see a way to do it this way...

Since ServiceStack just calls NLog.LogManager.GetLogger(typeName) and NLog doesn't appear to offer any Interface into LogContext.PushProperty I think the only option is to query by parameters to {0}, {1}, {2}...etc.

0
Rolf Kristensen On

ServiceStack now has support for PushProperty for NLog (MDLC) + Log4net + Serilog:

using (log.PushProperty("Hello", "World"))
{
    log.InfoFormat("Message");
}

https://docs.servicestack.net/logging#logging-with-context

This feature has been available since ServiceStack v5.1.0

Also NLog 4.5 introduces structured logging that works together with the new NLog.Targets.Seq