Integration anytime any place anywhere.

Using mapped diagnostic contexts for better logging

Adding the message-id to all the logging

Even in production, it can be very useful to have the message unique-id displayed on every log entry that appears in the log file. If the adapter has many workflows, and is processing a large number of messages; it can be hard to see the wood for the trees. Log4j2 supports mapped diagnostic contexts; and Interlok can interact with that via services or a logging-context-workflow-interceptor.

Since diagnostic contexts are thread based, it is probably better to use the service based contexts rather than the interceptor.

If you want to see the message-id in all the log entries; then what you want to do is to insert the current message-id as a context value against a specific key1; do your processing as normal; and then remove the context value afterwards:

<service-collection class="service-list">
    ... Now do stuff

Then in your log4j2.xml you just use the %X syntax to include your mapped diagnostic key as part of your logging:

<Console name="Console" target="SYSTEM_OUT">
    <Pattern>%d{ISO8601} %-5p [%t] [%c{1}.] [%X{myLoggingContext}] %m%n</Pattern>

Which leads to the output

DEBUG [ProductLookup] [c.a.c.ServiceList] [] Executing doService on [AddLoggingContext]
DEBUG [ProductLookup] [c.a.c.ServiceList] [8a13eb5a-c3b3-4557-882b-f024fc253c10] Executing doService on [GenerateUniqueMetadataValueService(GenerateUniqueMetadata)]
TRACE [ProductLookup] [c.a.c.s.m.GenerateUniqueMetadataValueService] [8a13eb5a-c3b3-4557-882b-f024fc253c10] Adding [515072ee-4620-48dd-9008-2fd143597aa1] to metadata key [a80c33d9-58c1-4c9b-a384-55c52b533eda]
DEBUG [ProductLookup] [c.a.c.ServiceList] [8a13eb5a-c3b3-4557-882b-f024fc253c10] Executing doService on [LogMessageService(LogProductRequest)]

Of course, you can get exceedingly fancy in log4j2 with routing based on the mapped diagnostic context. You could have a separate file for each message-id if you really wanted, though that may just leave you with hundreds of thousands of files on the filesystem…

<Routing name="Routing">
  <Routes pattern="$${ctx:myLoggingContext}">
    <Script name="RoutingInit" language="JavaScript"><![CDATA[
      if (logEvent.getContextMap().containsKey('myLoggingContext')) {
      } else {
      <RollingFile name="${ctx:myLoggingContext}" fileName="logs/${ctx:myLoggingContext}.log">
          <Pattern>%d{ISO8601} %-5p [%t] [%c.%M()] %m%n</Pattern>
          <OnStartupTriggeringPolicy />
          <SizeBasedTriggeringPolicy size="10 MB"/>
        <DefaultRolloverStrategy max="9" fileIndex="min"/>
    <Route ref="ROLLLING_FILE" key="STANDARD"/>
  1. In 3.7.3 add-logging-context-service will support $UNIQUE_ID$ directly; so you can skip the add-metadata-service.