MuleSoft Logging and Monitoring
Logging records what your application does at runtime. Monitoring aggregates those logs with metrics to give you a live view of application health. Together, they are your eyes into production. Without proper logging, diagnosing production issues is like trying to find a fault in the dark.
MuleSoft Logging Foundation
MuleSoft uses Log4j2 as its logging framework. Every Mule application generates log output. By default, logs go to the console and to a rolling log file in the logs/ folder of the Mule runtime directory. On CloudHub, logs stream to Anypoint Monitoring's Log Search.
Logger Component
The Logger component is the primary way to write messages to the application log. Add Loggers at key points in every flow — entry, exit, decision points, and error conditions.
Logger Configuration
Logger Properties: Level: INFO, DEBUG, WARN, or ERROR Message: any string or DataWeave expression Category: optional — creates a named logger for filtering Examples: Level: INFO Message: "Order received: #[payload.orderId] for customer #[payload.customerId]" Level: DEBUG Message: "Full payload: #[write(payload, 'application/json')]" Level: ERROR Message: "Failed to process order #[vars.orderId]: #[error.description]"
Log Levels
Log levels control what gets written to the log. Each level includes itself and all levels above it in severity.
Log Level Hierarchy
TRACE (most verbose — every tiny detail) ↓ DEBUG (developer diagnostics — variable values, flow paths) ↓ INFO (normal operations — request received, record processed) ↓ WARN (something unexpected but not critical — retry occurred) ↓ ERROR (something failed — database error, API timeout) ↓ FATAL (application cannot continue — most severe) Production: Set to INFO (DEBUG is too verbose, fills disk fast) Development: Set to DEBUG (see everything while building)
Structured Logging
Plain text logs are hard to search and filter. Structured logs use a consistent JSON format for every log line. Monitoring tools can index and query JSON logs efficiently. Add a standard set of fields to every log message.
Structured Log Format
Unstructured (hard to search):
"Order ORD-001 processed for Alice in 350ms"
Structured JSON (searchable, filterable):
{
"level": "INFO",
"timestamp": "2024-01-15T09:32:14.521Z",
"app": "orders-api",
"flow": "createOrderFlow",
"correlationId": "req-abc-123-xyz",
"event": "order_created",
"orderId": "ORD-001",
"customerId": "CUST-456",
"durationMs": 350
}
Logger Message (DataWeave expression):
output application/json
---
{
"event": "order_created",
"orderId": vars.orderId,
"customerId": payload.customerId,
"durationMs": (now() - vars.startTime).milliseconds,
"correlationId": vars.correlationId
}
Correlation IDs
A correlation ID is a unique identifier assigned to each request as it enters your system. Pass it through every log line, every subflow, and every outbound API call. When something fails, search all logs by correlation ID to see the complete journey of that single request across all systems.
Correlation ID Implementation
[HTTP Listener: POST /orders]
│
▼
[Set Variable: correlationId =
attributes.headers.'X-Correlation-Id' default uuid()]
│
▼
[Logger: INFO
{ "event": "request_received",
"correlationId": vars.correlationId,
"method": attributes.method,
"path": attributes.requestPath }]
│
▼
[Database: INSERT ...]
│
▼
[HTTP Request: POST to external API]
Headers:
X-Correlation-Id: #[vars.correlationId] ← propagate to downstream
│
▼
[Logger: INFO
{ "event": "order_created",
"correlationId": vars.correlationId,
"orderId": vars.newOrderId }]
Configuring Log Levels per Package
Set different log levels for different parts of your application by configuring the log4j2.xml file in src/main/resources/.
log4j2.xml:
<Configuration>
<Loggers>
<!-- Your application: DEBUG for detailed output -->
<Logger name="com.mycompany.orders" level="DEBUG"/>
<!-- Mule framework: INFO to reduce noise -->
<Logger name="org.mule" level="INFO"/>
<!-- Database connector: WARN to see only problems -->
<Logger name="com.mulesoft.db" level="WARN"/>
<!-- Root logger: default for everything else -->
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
Anypoint Monitoring Log Search
On CloudHub, all application logs stream to Anypoint Monitoring's Log Search in real time. Search logs using keywords, filter by application, log level, time range, and custom fields.
Log Search Query Examples
Search by correlation ID: correlationId:"req-abc-123-xyz" → Shows every log line from that specific request Search for all errors in the last hour: level:ERROR AND app:orders-api AND timestamp:[now-1h TO now] Search for slow requests: durationMs:>2000 AND app:orders-api → Shows all requests that took over 2 seconds Search for a specific customer's activity: customerId:"CUST-456" AND level:INFO
Performance Logging
Log request duration to identify slow operations. Record the start time at the beginning of the flow and compute elapsed time at the end.
[HTTP Listener]
│
[Set Variable: flowStartTime = now()]
│
... flow processing ...
│
[Logger: INFO
{ "event": "flow_complete",
"correlationId": vars.correlationId,
"durationMs": (now() - vars.flowStartTime).milliseconds,
"outcome": "success" }]
Masking Sensitive Data in Logs
Never log passwords, credit card numbers, or personal identification data. Mask sensitive fields before logging the payload.
DataWeave for masked logging:
%dw 2.0
output application/json
---
{
"name": payload.name,
"email": payload.email[0 to 2] ++ "***@***", // alice → ali***@***
"card": "**** **** **** " ++ payload.card[-4 to -1], // show last 4 only
"amount": payload.amount // non-sensitive, keep
}
