Technical article
Timer v1.0.1: scheduled routes that are diagnosable, not just running
Timer v1.0.1 keeps the lightweight Camel timer trigger and adds three production upgrades: servicelog service-level logging, a structured status payload with an explicit version field, and jsonResponseProcessor for stable UTF-8 output of Chinese text — so a scheduled route becomes diagnosable and publishable, not just alive.
v1.0.0 proved liveness; production needs more
The v1.0.0 sample established the baseline pattern: one route writes a fixed line every ten seconds via timer:independentTest?period=10000, and a second route emits a JSON status check every fifteen seconds. As long as those lines appear on schedule, the route thread and the CamelContext are alive — a simple liveness proof for inspection, cache refresh, batch, and heartbeat jobs.
Three gaps remained. Plain log: output mixes every service into one stream with no per-service level control; the status payload carried no version field, so diagnostics could not tell v1.0.0 from v1.0.1; and any route output consumed externally — dashboards, alerts, HTTP or storage chains — exposed UTF-8 encoding risk for Chinese text. v1.0.1 closes exactly these three gaps.
What v1.0.1 changes
Service-level logging
Routes log through servicelog:info and servicelog:debug, so each service gets isolated log behavior and independent level control — switch one service key to DEBUG for short-term troubleshooting. showBody=true and maxBodyLength=200 keep body output bounded.
Structured status fields
independent-status-check now emits a stable JSON payload — file, status, timestamp, plus an explicit version field — so dashboards and alert rules parse fields directly and diagnostics become version-aware.
jsonResponseProcessor
A <process ref="jsonResponseProcessor"/> step joins the route: a LightESB custom processor that improves response encoding behavior, especially for Chinese text output consumed by downstream chains.
Versioned evolution
The sample ships as timer/v1.0.0 and timer/v1.0.1 side by side, so scheduled routes iterate independently per service version directory — upgrade one version without touching the other.
Real route configuration and observed output
The v1.0.1 route replaces route-level log: calls with servicelog endpoints, including bounded body output:
<to uri="servicelog:info?message=Timer v1.0.1 status check started"/>
<to uri="servicelog:info?message=Independent context status check&showBody=true"/>
<to uri="servicelog:debug?message=Data processing route started"/>The status check sets a machine-readable body and passes it through the response processor:
<setBody>
<simple>{"file":"timer-test-routes.xml","status":"ACTIVE","timestamp":"${date:now:yyyy-MM-dd HH:mm:ss}","version":"v1.0.1"}</simple>
</setBody>
<process ref="jsonResponseProcessor"/>At runtime, logs/timer-test-routes.log under the service version directory shows the pattern: independent-status-check first records that the status check started, then emits the file/status/timestamp/version body, while timer-data-processing periodically outputs processId and timestamp — lines a health dashboard, an execution audit, or an incident replay can consume directly.
Migrating from v1.0.0
- Replace plain log: route-level diagnostics with servicelog: where service-level control is needed.
- Add version and the stable fields — status, timestamp, file — to every timer status payload.
- Insert jsonResponseProcessor where route output may be consumed externally and UTF-8 stability matters.
- Keep one standard <log> line during the transition for side-by-side validation.
Boundaries and tuning
Derive the period from the minimum latency the business can accept, not from habit: period=5000 suits quick verification, period=30000 fits a business heartbeat or light inspection, and period=1500000 covers low-frequency summaries — the 25-minute case in the sample. For delay, repeatCount and fixedRate, follow the official Camel Timer component reference.
Timer routes fit fixed-period jobs — inspection, synchronization, cleanup, aggregation — where second-level precision is acceptable and scheduling lives inside the route configuration. They do not fit strict-consistency timing, complex dependency orchestration with retry matrices, or tasks that must be managed by a unified external scheduler.