Skip to content
System types · Built-in All levels

Apache Camel

The built-in Apache Camel service type — camel-micrometer setup, starter checks that split by route, the dotted-versus-underscored metric-name fork between the OTLP and Prometheus export paths, and tuning notes.

SLSluicio team 6 min read Updated Sep 2026

Apache Camel is an integration framework, which makes it the archetype of the shape this product is built around: one JVM hosting many routes, each of which is an integration as far as anyone watching is concerned. So the interesting question is never “is the Camel application healthy” but “which of its routes broke”, and every starter check below answers the second one.

Key: camel · applied automatically to services emitting camel.- or camel_-prefixed metrics.

Two independent pieces, and they are worth having both.

Metrics come from camel-micrometer. Add the component and enable the route policy and message-history factories so the per-route meters are produced:

CamelContext configuration
MicrometerRoutePolicyFactory policyFactory = new MicrometerRoutePolicyFactory();
policyFactory.setMeterRegistry(meterRegistry);
context.addRoutePolicyFactory(policyFactory);
context.setMessageHistoryFactory(new MicrometerMessageHistoryFactory());

Traces come from camel-opentelemetry, which emits a span per exchange. Two of the starter checks read traces rather than metrics, because a trace names the endpoint and the step that failed and a counter cannot.

The pipeline that carries both to a cell - the resource processor that names the service, the exporter, verification - is in Monitoring with the OpenTelemetry Collector.

Metrics whose names start with camel. or camel_.

Micrometer keeps its dotted meter names when exporting over OTLP, and rewrites them for Prometheus: dots become underscores and counters gain a _total suffix. The same meter therefore arrives as either

camel.exchanges.failed (OTLP)
camel_exchanges_failed_total (Prometheus scrape)

Sluicio stores metric names exactly as they arrive and matches them exactly, so one set of checks cannot serve both paths. The starter checks are written for the dotted form. Detection covers the underscored prefix anyway, deliberately: a Prometheus-scraped Camel is still Camel and should be recognised as one, and retuning five metric names is a better position than having your runtime go unrecognised.

If that is your path, edit each applied check’s metric name after applying:

Starter check usesPrometheus equivalent
camel.exchanges.failedcamel_exchanges_failed_total
camel.exchanges.failures.handledcamel_exchanges_failures_handled_total
camel.exchanges.inflightcamel_exchanges_inflight
camel.routes.runningcamel_routes_running
camel.exchanges.external.redeliveriescamel_exchanges_external_redeliveries_total

The two trace checks are unaffected - they read spans, not meter names.

CheckConditionSeverityWhy it matters
Route failingcamel.exchanges.failed rising, split by routeIdWarningExchanges failed without an error handler catching them.
Route dead-letteringcamel.exchanges.failures.handled rising by more than 10, split by routeIdWarningFailures are being caught - which is a silent failure if nobody reads the dead-letter queue.
Route backlogcamel.exchanges.inflight > 100, split by routeIdWarningExchanges piling up in flight: the route is wedged, or intake is outrunning it.
Routes stoppedcamel.routes.running < 1CriticalThe context has no running routes at all.
Broker redelivering to a routecamel.exchanges.external.redeliveries rising, split by routeIdWarningAn external broker keeps redelivering - the consumer rejects, and the message ends in a DLQ rather than as a visible error.
Exchange faileda failed exchange trace in 15 minutesWarningNames the endpoint and the step, which the counter cannot. Needs camel-opentelemetry.
Slow exchangesp95 exchange duration > 30s over 15 minutesWarningNeeds camel-opentelemetry.

Five of the seven split by routeId, so a firing alert enumerates the routes that breached rather than telling you the JVM is unwell.

  • Routes stopped needs your route count. As shipped it fires only when every route has stopped, which is the context going down. Set the threshold to the number of routes the context runs and losing one fires instead - at the cost of firing during a deliberate route stop or a rolling restart.
  • Route dead-lettering is the one to think hardest about. If dead-lettering is your designed path for poison messages, this check is noise and should be disabled or raised a long way. If it is not, a route quietly handling failures is one of the most expensive things to discover late.
  • Route backlog is per route, so tune it per route. 100 in flight is a wedged route for a synchronous HTTP consumer and an ordinary morning for a route built with a hundred concurrent consumers. The check splits by route, so each one can carry its own threshold once you separate them.
  • Slow exchanges deserves separating too. A file poll and an HTTP call do not belong to the same latency threshold; 30 seconds is a placeholder that will be wrong for both.
  • The trace checks cover what the metrics cannot, and vice versa. The counters keep working when the tracing pipeline is the thing that broke, and the traces name the endpoint when it did not. Keeping both is deliberate overlap, not duplication.