11.1 Logger Configuration, Categories & Thread/Context Diagnostics
Key Takeaways
- The Mule 4 `<logger>` component supports five distinct logging levels (INFO, DEBUG, WARN, ERROR, TRACE) and uses Apache Log4j 2 as its underlying asynchronous, lock-free logging engine.
- Logging full payloads in high-throughput production flows creates severe CPU overhead, garbage collection churn, and thread starvation; production loggers should log concise, structured business identifiers.
- Custom logger categories combined with `log4j2.xml` configurations allow granular log level filtering and dedicated file appenders without requiring code changes or application rebuilds.
- Every Mule event automatically generates and carries a unique `correlationId` that is propagated across API layers via HTTP headers to enable end-to-end distributed transaction tracing.
- Sensitive information such as PII, credit card numbers, and credentials must be masked before logging using DataWeave expressions or Log4j 2 RegexReplacement pattern layouts.
Logger Configuration, Categories & Thread/Context Diagnostics
Effective logging and diagnostic tracing are essential for operating reliable enterprise integration applications. In Mule 4, logging is built on top of Apache Log4j 2, providing high-performance, asynchronous logging capabilities. Properly configuring the <logger> component, defining custom logging categories, leveraging distributed correlation IDs, and masking sensitive data are critical skills for both day-to-day troubleshooting and the MuleSoft Certified Developer exam.
1. The <logger> Component & Core Configuration
The <logger> component outputs diagnostic messages to the application log stream during flow execution. It can output static text strings, dynamically evaluated DataWeave expressions, or a combination of both.
<!-- Standard Logger Component Example -->
<logger level='INFO'
doc:name='Log Order Processed'
doc:id='log-order-001'
category='com.mycompany.orders.processing'
message="#['Order ' ++ vars.orderId ++ ' processed successfully for customer: ' ++ payload.customerId]" />
Core Attributes of <logger>:
level: Specifies the severity threshold of the log message. Valid values areINFO(default),DEBUG,WARN,ERROR, andTRACE.message: The string or DataWeave expression to evaluate and write to the log. In Mule 4, all dynamic expressions must be enclosed inside#[...]brackets.category: Optional logging category (namespace) used to route log messages through specific Log4j 2 loggers and appenders. If omitted, it defaults to the message processor's internal Mule runtime class (org.mule.runtime.core.internal.processor.LoggerMessageProcessor).doc:name: The display name shown in the Anypoint Studio canvas graphical interface.
DataWeave Expression Syntax in Loggers:
Developers can construct dynamic log messages using either string concatenation or DataWeave string interpolation:
<!-- String Concatenation Syntax -->
<logger level='INFO' message="#['Processing order ID: ' ++ (vars.orderId default 'UNKNOWN')]" />
<!-- String Interpolation Syntax (Cleaner for multiple variables) -->
<logger level='INFO' message="#['Processing order ID: $(vars.orderId) | Items: $(sizeOf(payload.items default [])) | Status: $(payload.status)']" />
2. Log Levels & Filtering Mechanics
Log4j 2 evaluates log events against a strict hierarchical severity model. When a logger level is set in the runtime configuration, only log events at that level or higher are written to the output appenders.
+-------------------------------------------------------------------------+
| LOG4J 2 SEVERITY HIERARCHY |
| |
| TRACE ---> DEBUG ---> INFO ---> WARN ---> ERROR ---> FATAL |
| [Lowest] [Highest] |
| |
| Example: If Logger Category is configured at level='INFO': |
| - TRACE: Suppressed (Ignored) |
| - DEBUG: Suppressed (Ignored) |
| - INFO: Logged Output Written |
| - WARN: Logged Output Written |
| - ERROR: Logged Output Written |
| - FATAL: Logged Output Written |
+-------------------------------------------------------------------------+
| Log Level | Severity | Intended Operational Use Case | Production Recommended? |
|---|---|---|---|
| TRACE | Lowest | Detailed step-by-step wire-level data, socket transfers, and transport handshakes | No (Only temporary targeted debugging) |
| DEBUG | Low | Internal flow variables, routing branch decisions, and fine-grained state transitions | No (Suppressed in standard production) |
| INFO | Medium | Major milestone events: transaction start, external system response received, flow completed | Yes (Default production standard) |
| WARN | High | Handled non-fatal anomalies, transient connection retries, fallback routing triggered | Yes |
| ERROR | Very High | Unhandled exceptions, failed backend transactions, HTTP 500 error responses | Yes |
| FATAL | Highest | Critical runtime failures causing subsystem termination or unrecoverable state | Yes |
3. log4j2.xml Architecture & Custom Categories
Every Mule application contains a log4j2.xml configuration file located in src/main/resources. This file controls how log events are formatted, filtered, and routed to physical destinations (console, rolling files, cloud logging services).
<?xml version='1.0' encoding='utf-8'?>
<Configuration status='WARN'>
<Appenders>
<!-- Console Appender for Local Studio and Container Standard Out -->
<Console name='Console' target='SYSTEM_OUT'>
<PatternLayout pattern='%-5p %d [%t] [event: %X{correlationId}] %c: %m%n' />
</Console>
<!-- Rolling File Appender for Application Audit Logs -->
<RollingFile name='AuditFile'
fileName='${sys:mule.home}/logs/orders-audit.log'
filePattern='${sys:mule.home}/logs/orders-audit-%d{yyyy-MM-dd}-%i.log'>
<PatternLayout pattern='%d [%t] [event: %X{correlationId}] %-5p %c - %m%n' />
<Policies>
<SizeBasedTriggeringPolicy size='50 MB' />
<TimeBasedTriggeringPolicy interval='1' modulate='true' />
</Policies>
<DefaultRolloverStrategy max='10' />
</RollingFile>
</Appenders>
<Loggers>
<!-- Custom Category for Business Audit Events -->
<AsyncLogger name='com.mycompany.orders.audit' level='INFO' additivity='false'>
<AppenderRef ref='AuditFile' />
</AsyncLogger>
<!-- HTTP Wire Logging (Disabled in prod, enabled for debugging) -->
<AsyncLogger name='org.mule.service.http.impl.service.HttpMessageLogger' level='WARN' />
<!-- Root Logger -->
<AsyncRoot level='INFO'>
<AppenderRef ref='Console' />
</AsyncRoot>
</Loggers>
</Configuration>
Key Concepts in log4j2.xml:
- Asynchronous Loggers (
<AsyncLogger>): Mule 4 uses the LMAX Disruptor ring-buffer library for asynchronous logging. Log writing operations execute on separate background threads rather than blocking the active Mule worker threads (uberthread pool), maximizing throughput. - Custom Category Targeting: When a
<logger category='com.mycompany.orders.audit'>is invoked, Log4j 2 matches the category name against configured<AsyncLogger>elements. This allows routing specific business logs to dedicated files or third-party log forwarders (e.g., Splunk, Datadog). additivity='false': Prevents log messages captured by a specific<AsyncLogger>from propagating up to the parent or<AsyncRoot>logger, avoiding duplicate log entries in the console.
4. Performance Impacts & Anti-Patterns
In high-throughput Mule applications (e.g., handling 2,000+ transactions/second), excessive or poorly formatted logging is one of the most common causes of performance degradation, garbage collection pauses, and out-of-memory errors.
+---------------------------------------------------------------------------------+
| LOGGING ANTI-PATTERN VS BEST PRACTICE |
| |
| ANTI-PATTERN (High Overhead): |
| <logger level='INFO' message='#[payload]' /> |
| - Serializes entire in-memory object graphs (e.g., 50MB JSON/XML array) |
| - Consumes non-repeatable streaming payloads prematurely |
| - Causes heavy JVM heap allocation and excessive garbage collection |
| |
| BEST PRACTICE (Low Overhead, High Diagnostic Value): |
| <logger level='INFO' |
| message="#['Processed batch: ' ++ sizeOf(payload) ++ ' records | OrderId: ' ++ vars.orderId]" /> |
| - Logs only key operational metadata (IDs, counts, timestamps, status codes) |
| - Constant memory footprint (~100 bytes) |
| - Never consumes payload streams |
+---------------------------------------------------------------------------------+
Critical Production Logging Rules:
- Never Log Entire Large Payloads: Avoid
message='#[payload]'on collections, binary documents, or large XML/JSON structures. - Beware of Non-Repeatable Streams: If streaming is configured as non-repeatable, reading
#[payload]in a logger consumes the stream from memory, leaving an empty stream for downstream processors and causing runtime exceptions. - Use Appropriate Log Levels: Routine flow entry/exit breadcrumbs belong at
DEBUGlevel. Only business milestones and errors should be logged atINFOorERROR.
5. Contextual Diagnostic Logging & Correlation ID
In distributed API-led architectures, a single business transaction traverses multiple applications: Experience API $\rightarrow$ Process API $\rightarrow$ System API $\rightarrow$ Backend. Tracing failures across these microservices requires a shared transaction identifier.
+---------------------------------------------------------------------------------+
| DISTRIBUTED CORRELATION ID TRACING |
| |
| [Client Request] |
| | |
| v (Auto-generates correlationId: 'a1b2-c3d4-e5f6') |
| +-------------------------------------------------------------------------+ |
| | Experience API: [event: a1b2-c3d4-e5f6] Order submission received | |
| +-------------------------------------------------------------------------+ |
| | (HTTP Request propagates X-CORRELATION-ID header) |
| v |
| +-------------------------------------------------------------------------+ |
| | Process API: [event: a1b2-c3d4-e5f6] Validating customer credit | |
| +-------------------------------------------------------------------------+ |
| | (HTTP Request propagates X-CORRELATION-ID header) |
| v |
| +-------------------------------------------------------------------------+ |
| | System API: [event: a1b2-c3d4-e5f6] Database query executed | |
| +-------------------------------------------------------------------------+ |
+---------------------------------------------------------------------------------+
How Correlation ID Works in Mule 4:
- Automatic Initialization: When a Mule flow receives a message, Mule runtime assigns a unique UUID to the
correlationIdproperty of the Mule event. - Inbound Header Adoption: If the inbound HTTP request contains an
X-CORRELATION-IDheader, Mule runtime automatically adopts that value as the flow'scorrelationId. - Outbound Propagation: The Mule HTTP Request connector automatically forwards the active
correlationIddownstream in theX-CORRELATION-IDrequest header unless explicitly overridden. - Log Pattern Integration: In
log4j2.xml, the pattern layout%X{correlationId}extracts the correlation ID from the Mapped Diagnostic Context (MDC) and prepends it to every log line.
6. Masking Sensitive Data (PII, PCI-DSS & Credentials)
Industry regulations (such as PCI-DSS, HIPAA, and GDPR) strictly prohibit logging sensitive data in plain text, including Primary Account Numbers (PAN / credit cards), passwords, authorization tokens, and Social Security Numbers.
Masking Strategy 1: DataWeave Expression Sanitization
Mask sensitive fields directly within the logger's DataWeave expression:
<logger level='INFO'
message="#['Processing payment for customer: $(vars.customerId) | Card: ****-****-****-$(vars.accountNumber[-4 to -1])']" />
Masking Strategy 2: Log4j 2 Regex Replacement
Configure a global masking rule in log4j2.xml using the %replace pattern converter to sanitize credentials or card numbers automatically across all log output:
<PatternLayout pattern='%-5p %d [%t] [event: %X{correlationId}] %c: %replace{%m}{(?i)(password|secret|token)=([^",\s]+)}{$1=******}%n' />
7. Exam Watch: Logger & Diagnostic Scenarios
[!IMPORTANT] DataWeave in Logger Messages Dynamic values in the
messageattribute must always be enclosed in#[...]. When concatenating strings, ensure the entire expression is a valid DataWeave string expression, such asmessage="#['Processing ID: ' ++ vars.orderId]".
[!WARNING] Impact of
#[payload]in Production Logging#[payload]on high-volume APIs or streaming data sources causes out-of-memory errors and stream consumption issues. For exam scenarios asking how to optimize slow flows with high CPU/memory utilization, removing raw payload logging is frequently the correct solution.
[!TIP] Adjusting Log Levels at Runtime In CloudHub and Runtime Manager, log levels for specific packages or categories can be modified dynamically from the Runtime Manager console without redeploying the Mule application archive (
.jar).
An order fulfillment Mule application deployed to CloudHub experiences severe CPU spikes, elevated garbage collection pauses, and frequent out-of-memory errors during peak traffic periods. Inspection reveals a logger configured as <logger level='INFO' message='#[payload]' /> immediately following a database select that returns 10,000 order records. What is the most effective way to resolve this performance issue while preserving operational visibility?
A developer needs to direct all financial auditing log entries generated by a payment flow to a dedicated log file named audit.log, while ensuring these audit messages do not duplicate in the main application console log. How should the developer configure the Mule application?
An API-led ecosystem consists of an Orders Experience API calling an Order Fulfillment Process API, which subsequently invokes a Warehouse System API over HTTP. A transaction fails intermittently in the Warehouse System API. How can a support engineer correlate and trace the specific failed transaction end-to-end across the CloudHub logs of all three applications?
To comply with payment security standards (PCI-DSS), an application must ensure that customer credit card numbers are never written to log files in plain text. Which approach represents the standard MuleSoft best practice for sanitizing sensitive data in application logs?