MuleSoft

MuleSoft Mastery: From Zero to Hero | Ch.13

Observability for MuleSoft across the three pillars: Anypoint Monitoring dashboards and alerts, custom business metrics via the Custom Metrics connector (custom-metrics:send), log forwarding to Splunk, ELK and Azure…

MuleSoft Mastery: From Zero to Hero | Ch.13
Chapter 13 · MuleSoft from Zero to Hero

Building an integration is half the job; keeping it healthy is the other half. Metrics tell you something’s wrong, logs tell you what, and traces tell you where — across Anypoint Monitoring, Splunk, ELK, Azure, and any OpenTelemetry backend.

SeriesMuleSoft Zero → Hero Chapter13 of 14 PublishedMay 22, 2026 Read~30 min Metrics Logs Traces OpenTelemetry

You’ve secured your integrations in Chapter 12; now you have to operate them. When an order pipeline starts failing at 2 a.m., you need three things fast: a signal that something broke, the log line that explains it, and a trace that shows exactly which hop in a chain of services went dark. That’s the three pillars of observability — metrics, logs, and traces — and MuleSoft gives you a built-in stack plus open paths to every major platform.

Companion source code

The companion repo carries the observability building blocks: a Custom Metrics flow using custom-metrics:send, async Log4j2 appenders for Splunk / ELK / Azure with MDC correlation, an OpenTelemetry Collector config that fans out to multiple backends, and the payment-gateway troubleshooting walkthrough.

github.com/nestaconnect/mulesoft-from-zero-to-hero

By the end of this chapter you will:

  • Use Anypoint Monitoring dashboards and alerts, and enable distributed tracing
  • Send business metrics with the Custom Metrics connector — the correct custom-metrics:send operation
  • Forward logs to Splunk, ELK, and Azure with asynchronous Log4j2 appenders
  • Correlate everything with MDC — correlationId, traceId, spanId
  • Export OpenTelemetry traces (and logs) via the Direct Telemetry Stream and an OTel Collector
  • Diagnose a real incident by triangulating across all three pillars

01 · Three Pillars — Metrics, Logs & Traces

Observability isn’t one tool — it’s three complementary signals. Each answers a different question, and you need all three to move from “something’s wrong” to “here’s the fix” without guessing.

THE THREE PILLARS 📊 METRICS numbers over time throughput · errors “is it healthy?” 📝 LOGS discrete events messages · errors “what happened?” 🔗 TRACES spans across services end-to-end path “where did it break?” DASHBOARDS & ALERTS correlate all three
Metrics surface that error rates spiked; logs reveal the connection-refused message behind it; traces show which downstream hop timed out. Tie them together with a shared correlation ID and you stop guessing.

02 · Anypoint Monitoring — Built-in Dashboards & Alerts

For apps on CloudHub 2.0 and Runtime Fabric, Anypoint Monitoring collects metrics, logs, and traces automatically — reachable via Runtime Manager → your app → Monitoring. Out of the box you get an Application panel (throughput, error rates, response times, JVM heap/GC/threads) and an API panel (requests by method, response codes, latency percentiles).

2.1 · Alerts that page you

Alerts fire when a metric crosses a threshold for a sustained window. Create them under Alerts → Create Alert in Runtime Manager. A well-tuned alert names a resource, a metric, a condition, a duration (to avoid flapping), and a notification channel.

FieldExample
Resourcecustomer-api (Production)
Metricapp_inbound_error_rate
Condition> 5%
Duration5 minutes (sustained, not a blip)
NotifyEmail · Slack · PagerDuty
Enabling distributed tracing

At deploy time, open your app’s Settings in Runtime Manager and turn on Enable tracing. Mule then generates OpenTelemetry spans, propagates W3C Trace Context headers (traceparent, tracestate), and surfaces traces in Anypoint Monitoring — and, as you’ll see in §5, can stream them to any external backend.

03 · Custom Metrics — Tracking Business KPIs

Platform metrics tell you the runtime is healthy; custom metrics tell you the business is healthy — orders per minute, payment success rate, processing time by region. These come from the Custom Metrics connector, which sends data to Anypoint Monitoring. It requires the Anypoint Monitoring Agent and a supported runtime.

It’s custom-metrics:send — not metrics:increment

A persistent piece of misinformation online uses an invented metrics:increment operation. The real connector exposes a single Send Custom Metric operation — <custom-metrics:send> — that takes a map of dimensions (low-cardinality labels) and a map of facts (numeric values). Use the correct dependency and operation, or your metrics silently never arrive.

XML — pom.xml dependency
<dependency>
  <groupId>com.mule.modules</groupId>
  <artifactId>mule-custom-metrics-extension</artifactId>
  <version>2.3.2</version>
  <classifier>mule-plugin</classifier>
</dependency>
XML — send a business metric (dimensions + numeric facts)
<custom-metrics:send config-ref="Custom_Metrics"
                     metricName="order.processing">
  <!-- dimensions: LOW cardinality labels you slice by -->
  <custom-metrics:dimensions>#[{
    status:       "success",
    region:       payload.region,
    customerTier: payload.tier
  }]</custom-metrics:dimensions>
  <!-- facts: NUMERIC values only -->
  <custom-metrics:facts>#[{
    count:            1,
    orderValue:       payload.totalAmount,
    processingTimeMs: now() - vars.startTime
  }]</custom-metrics:facts>
</custom-metrics:send>
Three rules that keep custom metrics usable

Low-cardinality dimensions only. Never use customerId, sessionId, or a timestamp as a dimension — each unique value is a new time series, and you’ll blow up storage and cost. Use region, tier, productCategory instead. Facts must be numeric. And avoid reserved keywords (e.g. SELECT, WHERE, GROUP) as dimension names.

04 · Logs Everywhere — Splunk, ELK & Azure via Log4j2

Mule logs through Log4j2, so forwarding to an external platform is a matter of adding the right appender to src/main/resources/log4j2.xml. Two non-negotiables: appenders must be asynchronous (a slow log backend must never block your message thread), and secrets must come from placeholders, never hardcoded.

PlatformLibrary (pom.xml)Transport
Splunksplunk-library-javaloggingHTTP Event Collector (HEC)
ELKlogstash-log4j2-encoder + FilebeatJSON → Logstash / Filebeat module
Azureapplicationinsights-logging-log4j2Application Insights
XML — log4j2.xml: async Splunk HEC appender, secret via placeholder
<Configuration>
  <Appenders>
    <SplunkHttp name="splunk"
        url="https://http-inputs.splunk.com:443"
        token="${sys:splunk.token}"          <!-- never hardcode -->
        index="mule" source="mule-app">
      <PatternLayout pattern="%d %p [%X{correlationId}] %c - %m%n"/>
    </SplunkHttp>
    <!-- wrap ANY appender to make it non-blocking -->
    <Async name="asyncSplunk">
      <AppenderRef ref="splunk"/>
    </Async>
  </Appenders>
  <Loggers>
    <AsyncRoot level="INFO">
      <AppenderRef ref="asyncSplunk"/>
    </AsyncRoot>
  </Loggers>
</Configuration>
MDC is what makes logs searchable by transaction

Mule automatically populates the Mapped Diagnostic Context with correlationId, and — when tracing is on — traceId and spanId. Reference them in your pattern with %X{correlationId}. Now every log line for one transaction shares an ID you can pivot on, and that same traceId links the log straight to its distributed trace. For ELK specifically, the Mule Filebeat module ships pre-built Kibana dashboards once you point it at the Mule event logs.

05 · OpenTelemetry — Vendor-Neutral Distributed Tracing

OpenTelemetry (OTel) is the open standard for telemetry, and Mule runtime speaks it natively. With the Direct Telemetry Stream (Mule 4.11.0+), the runtime exports traces and logs in OTLP format to any compatible backend — Jaeger, Datadog, Dynatrace, Splunk, Azure. You enable it in the deployment settings alongside “Enable tracing.”

OTLP → COLLECTOR → ANYWHERE MULE RUNTIME 4.11+ · traces+logs OTEL COLLECTOR batch · transform retry · fan-out Splunk Datadog Azure Monitor Jaeger (tracing) OTLP The collector decouples Mule from your backend — switch vendors without touching the app. (Note: OTel metrics are still emerging — JVM metrics arrive in 4.12 Edge.)
Mule streams OTLP to a single OpenTelemetry Collector, which batches, transforms, and fans out to every backend you use. Swapping Datadog for Dynatrace becomes a collector config change, not an app redeploy.

When you run the community OpenTelemetry module (or the SDK in autoconfigure mode), you point the exporter at your collector through standard OTel properties — set as system properties or environment variables:

Properties — OTLP exporter (OpenTelemetry SDK autoconfigure)
# export traces and logs over OTLP to the collector
otel.traces.exporter=otlp
otel.logs.exporter=otlp
otel.exporter.otlp.endpoint=http://otel-collector:4318
otel.exporter.otlp.protocol=http/protobuf
otel.service.name=customer-api
otel.resource.attributes=environment=production,region=us-east-1

# sample to control volume in production
otel.traces.sampler=parentbased_traceidratio
otel.traces.sampler.arg=0.1   # 10% of traces
Two accuracy notes the draft blurred

First, native OpenTelemetry support — the Direct Telemetry Stream — covers traces and logs from Mule 4.11.0+; metrics over OTel are not yet there (JVM metrics begin arriving with the 4.12 Edge runtime). Keep using Anypoint Monitoring / custom metrics for metrics today. Second, when you use the Direct Telemetry Stream, Anypoint Monitoring’s own OpenTelemetry exporter features aren’t available — they’re alternative paths, not stacked. Context propagation across HTTP also needs the HTTP Connector 1.8+.

5.1 · Correlating with Azure Application Insights

Azure keys distributed traces off the W3C traceparent header, mapping it to operation_Id. With tracing enabled, Mule’s HTTP Listener and Requester propagate traceparent automatically — so the fix when correlation breaks is almost always a component (or proxy) overwriting or stripping that header. Verify nothing in the chain rewrites traceparent, and the same operation_Id will line up across every span.

06 · Case Study — Diagnosing Payment-Gateway Failures

An e-commerce platform hits intermittent order failures. The on-call engineer uses all three pillars in sequence — and finds the root cause in minutes, not hours.

TRIANGULATING THE ROOT CAUSE ⚠ ALERT error rate > 10% ① METRICS spike in EU region HTTP:CONNECTIVITY ② LOGS · Splunk “connection refused” eu-west-1 gateway ③ TRACE · Jaeger payment span: 10s times out → no DB ROOT LB firewall A shared correlationId / traceId carries the engineer from metric → log → trace without ever guessing.
The alert fires; the dashboard localizes failures to the EU region with HTTP:CONNECTIVITY; Splunk shows “connection refused” to the eu-west-1 gateway; the Jaeger trace shows the payment span timing out at 10s with no downstream DB span. Root cause: a load-balancer firewall change dropped the app’s new auto-scaled IP range.
SPL — the Splunk search that localized the failures
index=main sourcetype=mule-app errorType="HTTP:CONNECTIVITY"
| timechart count by region
Why the three pillars paid off

The alert caught it before customers complained. The region dimension on the custom metric localized the blast radius instantly. The correlated logs and trace — sharing one ID — pinpointed the exact failing hop, so nobody wasted time suspecting the database. The fix (restore the firewall rule) took minutes; the team then added a circuit breaker around the gateway and an alert on its reachability.

07 · Best Practices — Observability Rules That Hold Up

PracticeWhy it mattersHow
Custom metrics for KPIsRuntime health ≠ business healthcustom-metrics:send with numeric facts
Low-cardinality dimensionsIDs explode series count and costUse region/tier, never customerId
Always async loggingA slow sink must not block the flow<Async> / <AsyncRoot> appenders
Sample traces in prod100% tracing is expensive at volumeParent-based ratio sampler (e.g. 10%)
Propagate trace contextBroken traceparent = broken correlationDon’t strip/override the header anywhere
Use an OTel CollectorDecouples Mule from the backend vendorFan out from one collector; swap freely

08 · Recap — What You Now Know

01 · THREE PILLARS 📊

Metrics, logs, traces

Each answers a different question; together they take you from “something broke” to “here’s the fix.”

  • Metrics → is it healthy?
  • Logs → what happened?
  • Traces → where did it break?
  • Correlate via a shared ID
02 · ANYPOINT MONITORING 📈

Built-in, then alert

Automatic dashboards for app and API panels; threshold alerts that page you; one toggle to enable tracing.

  • App + API panels OOTB
  • Alert: metric · condition · duration
  • Enable tracing in Settings
  • W3C trace context emitted
03 · CUSTOM METRICS 🎯

Business KPIs, the right way

custom-metrics:send with low-cardinality dimensions and numeric facts — not the mythical metrics:increment.

  • mule-custom-metrics-extension
  • dimensions + numeric facts
  • no IDs as dimensions
  • needs the Monitoring Agent
04 · LOGS 📝

Forward, async, masked

Log4j2 async appenders to Splunk/ELK/Azure; MDC ties every line to a transaction via correlationId.

  • Always <Async> appenders
  • Secrets via ${sys:...}
  • %X{correlationId} in pattern
  • Filebeat module for ELK
05 · OPENTELEMETRY 🔭

Vendor-neutral tracing

Direct Telemetry Stream (4.11+) exports traces & logs via OTLP; a collector fans out to any backend.

  • Traces + logs native at 4.11+
  • OTel metrics still emerging
  • Collector decouples the backend
  • Don’t strip traceparent
06 · TRIAGE 🔍

Three pillars, one incident

Alert → metric → log → trace, carried by a shared ID, pinpoints the failing hop in minutes.

  • Dimensions localize the blast radius
  • Logs explain the error
  • Traces find the exact hop
  • Fix, then add a circuit breaker
Get the source code

The companion repo carries the observability stack: the custom-metrics:send flow, async Log4j2 appenders for Splunk / ELK / Azure with MDC correlation, an OpenTelemetry Collector config that fans out to multiple backends, and the payment-gateway triage walkthrough. Wire it into a sandbox and trip a failure to watch the pillars light up.

github.com/nestaconnect/mulesoft-from-zero-to-hero
Up next · Chapter 14

API Governance & Custom Policy Development — Standards, Conformance & the PDK

Continue reading →