Blog Posts

Mule 4 – Designing for Operations with MDC

Designing for operations refers to the construct of how log messages are structured so that they can provide the information required for the operational support of the application.

In order to facilitate the following functions, log messages much provide tracking and correlation data to;

  • Search log messages for a given transaction
  • Filter log messages by a search parameter, i.e., application, client, or correlation identifiers
  • Provide alerting for error conditions
  • Create dashboards to visualize or tabulate error conditions, response times, and usage.

MDC

Mapped Diagnostic Context (MDC) provides a way to enrich log messages using the Log4J2 framework.  MDC allows custom diagnostic data in the format of key value pairs to provide the necessary tracking and correlation data.

Creating a Common Dependency

Use a common dependency to manage your cross-cutting concerns such as logging and error handling to be used across multiple applications in the enterprise.  In Mule, this is defined as a Mule Plugin.

<plugin>
	<groupId>org.mule.tools.maven</groupId>
	<artifactId>mule-maven-plugin</artifactId>
	<version>${mule.maven.plugin.version}</version>
	<extensions>true</extensions>
	<configuration>
		<classifier>mule-plugin</classifier>
	</configuration>
</plugin>

Mule Tracing Module

The name of the module that enables you to use the MDC logging is called the Mule Tracing Module.  To add this module from Anypoint Studio, search in the exchange for mdc or Mule Tracing Module.

Once selected it will import the following dependency in your Maven POM.

<dependency>
	<groupId>org.mule.modules</groupId>
	<artifactId>mule-tracing-module</artifactId>
	<version>1.0.0</version>
	<classifier>mule-plugin</classifier>
</dependency>

Common Logging

Create a new Mule Configuration File for your common logging.  Add a sub-flow that will contain your MDC variables.  Then, drag and drop your logging variables from the Tracing Module.

When you add an MDC variable, it must have a value, it cannot be null.  If you expect that the variable might not be populated, add a default. 

<tracing:set-logging-variable doc:name="Set Client ID" variableName="clientId" value="#[attributes.headers.'client_id' default 'NOT_REGISTERED']"/>

If the variable is something you just want to show for a period of time, for example to show the error type while logging an error, add the logging variable and remove it after you have performed the logging.

<tracing:set-logging-variable doc:name="Set Error Type" variableName="errorType" value="#[error.errorType.namespace ++ ':' ++ error.errorType.identifier]"/>
<logger level="ERROR" doc:name="Logger" message="#[error.description]"/>
<tracing:remove-logging-variable doc:name="Remove Error Type" variableName="errorType"/>

Deployment

In order to deploy this dependency to Anypoint Exchange, first navigate to Anypoint Platform > Access Management > Business Groups > {Business Group} > Settings and copy the Business Group ID.

Then update your Maven POM to add the Business Group ID in the Maven POM.

Set the artifact groupId as the Business Group ID.

<groupId>5355cf1b-d7c2-4837-a681-9ef65e68b0df</groupId>
<artifactId>common-services</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>mule-application</packaging>

Set the distribution management URL to set the organization as the Business Group ID.

<distributionManagement>
	<repository>
		<id>anypoint-exchange-v3</id>
		<name>Anypoint Exchange</name>
		<url>https://maven.anypoint.mulesoft.com/api/v3/organizations/5355cf1b-d7c2-4837-a681-9ef65e68b0df/maven</url>
		<layout>default</layout>
	</repository>
</distributionManagement>

To deploy the dependency to Anypoint Exchange, navigate to the Maven POM on the command line and run mvn deploy.

Include the Dependency

Maven Dependency

To add the dependency to the Maven POM, first navigate to Anypoint Exchange.

Select the dependency snippet and select copy.

Paste the dependency in the Maven POM.

Logging Include

To add the logging module to the application, create a global Mule Configuration file and add the file as an import.

<import doc:name="Import" file="mule-common-logging.xml" />

Set the Log Filters

To set the log filters simply add the flow reference for your sub-flow before the APIkit Router.

Add the Log4j2 Appenders

To add the MDC variables to the native logger in Mule, you must add the [%MDC] to the Log Appenders.

Console

<Appenders>
	<Console name="CONSOLE" target="SYSTEM_OUT">
		<PatternLayout pattern="%-5p %d [%t] [%MDC] %c: %m%n"/>
	</Console>
</Appenders>

Anypoint Monitoring

Use ${sys:domain} for CloudHub, use the application name for standalone or RTF.

<RollingFile name="FILE"
	fileName="/opt/mule/mule-CURRENT/logs/mule-${sys:domain}.log"
	filePattern="/opt/mule/mule-CURRENT/logs/mule-${sys:domain}-%i.log">
	<PatternLayout pattern="[%d{MM-dd HH:mm:ss.SSS}] %-5p %c{1} [%t]: [%MDC] %m%n" />
	<DefaultRolloverStrategy max="10" />
	<Policies>
		<SizeBasedTriggeringPolicy size="10 MB" />
	</Policies>
</RollingFile>

Runtime Manager logs do not currently support MDC but may change at a later time.

You can also send the MDC variables to a third-party log management system.  Check the appenders for each system on how to configure this.

Leave a Reply

Your email address will not be published. Required fields are marked *