New to Kestra?
Use blueprints to kickstart your first workflows.
Fire on live JMS queue messages, alert Slack on stale message age past your SLA, and log the result for messaging platform teams.
A JMS consumer that is quietly falling behind does not page anyone; messages pile up on the queue and the only visible symptom is a growing backlog nobody notices until it is big enough to show up on a broker dashboard. This blueprint fires on every message as it lands, reads the broker's own JMS timestamp, and treats a message older than your SLA as a governance event the moment it is observed, not after it has already been redelivered past a poison-message threshold into the dead-letter queue.
This blueprint was created by Mohit Jeswani.
live_queue_watch (io.kestra.plugin.jms.RealtimeTrigger) listens on the live production
queue and starts one execution per message, using CLIENT_ACKNOWLEDGE for at-least-once
delivery.evaluate (io.kestra.plugin.core.output.OutputValues) subtracts the message's own JMS
timestamp (set by the broker when the message was sent) from the current time to get
age_seconds, then compares it against max_age_seconds.route (io.kestra.plugin.core.flow.If):summary logs the age and severity for every message, closing the governance cycle.errors alerts Slack if the flow itself fails, for example a broker connection drop.RealtimeTrigger used as a
standing per-message SLA gate, distinct from this repo's existing JMS blueprint, which
scans the dead-letter queue on a schedule rather than watching the live queue in real time.The broker stamps a timestamp on every message; it does not compare that timestamp against
an SLA you declare or notify a Slack channel when a message is slow. Kestra keeps
max_age_seconds as a flow input, turns a stale message into a Slack page naming the exact
message id and age, and keeps a full execution history of every message observed.
jms-libs folder on
the worker or referenced via providerJarPaths.A local ActiveMQ Artemis broker can be run via the official apache/activemq-artemis
Docker image for a fully local end-to-end test, no managed broker required.
SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
max_age_seconds |
300 |
Message age, in seconds, above which the Slack alert fires |
{{ trigger.messageId }} / .timestamp / .data / .headers: the observed message, as
RealtimeTrigger reports it.{{ outputs.evaluate.values.age_seconds }} / .severity: how long the message sat before
observation, and OK or STALE_MESSAGE.connectionFactoryConfig and destination are trigger-level configuration, not flow
inputs; a realtime trigger has no per-execution input overrides the way a Schedule
trigger does, so pointing this at a different broker or queue means editing the trigger
block directly.age_seconds depends on the producer's and broker's clocks being reasonably in sync with
the Kestra worker; significant clock skew on either side shows up as a false stale reading
or a false compliant one.SLACK_WEBHOOK_URL secret.connectionFactoryConfig/destination on
live_queue_watch to point at it.compliant logs its age.max_age_seconds below a real
message's age) to confirm alert fires.messageSelector to scope this sentinel to a specific message type or priority
instead of every message on the queue.age_seconds into a KV entry or external metric over a rolling window to chart
consumer lag trend, not just flag individual slow messages.STALE_MESSAGE alerts to the on-call channel for the consumer service that reads this
queue, since a growing age usually means that specific consumer is falling behind.