New to Kestra?
Use blueprints to kickstart your first workflows.
Drain a Solace PubSub+ dead-letter queue on a schedule, classify backlog status, and alert Slack when it breaches threshold.
A Solace dead-letter queue that quietly fills up is invisible until a downstream team notices messages went missing. plugin-solace has no dedicated queue-depth or backlog metric task, so this blueprint uses its native Consume task as the probe itself: it drains a bounded sample of messages from the dead-letter queue, counts how many came off within the sample window, and classifies the result as BACKLOGGED, HEALTHY, or PROBE_FAILED before deciding whether to page Slack.
drain_dlq_sample (io.kestra.plugin.solace.Consume) binds to dlq_queue_name as queue_type and pulls up to max_messages_per_drain messages within max_drain_duration, writing the deserialized batch to internal storage. allowFailure: true lets the flow continue instead of aborting if the broker is unreachable or the bind fails.classify_backlog_status (io.kestra.plugin.core.debug.Return) checks whether outputs.drain_dlq_sample.messagesCount is defined at all. If it is missing, the classification is PROBE_FAILED. If it is defined and at or above backlog_alert_threshold, the classification is BACKLOGGED; otherwise HEALTHY.route_by_backlog_status (io.kestra.plugin.core.flow.Switch) branches on that string. BACKLOGGED runs evaluate_alert_toggle (io.kestra.plugin.core.flow.If), which pages Slack via dispatch_backlog_alert only when send_slack_alert is true, logging a suppressed-alert line otherwise. HEALTHY logs a clean audit line. PROBE_FAILED pages Slack directly since the backlog state is now unknown. The defaults branch logs a fallback line that is unreachable under normal operation.log_audit_summary records a status line on every run regardless of branch, so execution history reads as a continuous backlog trend.errors block pages Slack separately if the sentinel flow itself fails outright.solace_dlq_schedule trigger polls every 6 hours with explicit input overrides, shipped disabled: true until pointed at a real broker and queue.status output (BACKLOGGED / HEALTHY / PROBE_FAILED) other flows can gate on.outputs.drain_dlq_sample.uri) containing the drained message batch for manual inspection.A one-off CLI drain or a custom cron script proves the queue depth for one instant and then the evidence is gone. This flow keeps every drain in Kestra's execution history, turns the result into a typed status output other flows can depend on, stores the drained batch in internal storage for inspection, and gives you an If/Switch branch to grow into real remediation (reprocessing, ticketing) without rewriting the probe itself.
queue_type.SOLACE_USERNAME, SOLACE_PASSWORD, and SLACK_WEBHOOK secrets.dlq_queue_name and queue_type at a real dead-letter queue on your broker (see Pitfalls before pointing this at a live production queue).status reads HEALTHY or BACKLOGGED as expected for your current queue depth.solace_dlq_schedule.outputs.drain_dlq_sample.uri to summarize failure reasons by message property instead of just counting.status into a KV store to alert only on state transitions instead of every run.Loop task to monitor multiple services from one flow.io.kestra.plugin.solace.Produce task to republish selectively reprocessed messages back onto their source topic after manual review.SOLACE_USERNAME: Broker username with consume permission on the dead-letter queue.SOLACE_PASSWORD: Broker password for that user.SLACK_WEBHOOK: Slack incoming webhook used for the backlog, probe-failure, and flow-failure alerts.SECRET_SOLACE_USERNAME, SECRET_SOLACE_PASSWORD, and SECRET_SLACK_WEBHOOK as base64, for example echo -n "<your-value>" | base64.solace_host (STRING, default localhost:55555): broker hostname and port.solace_vpn (STRING, default default): Solace Message VPN name.dlq_queue_name (STRING, default audit.dlq.queue): dead-letter queue to drain.queue_type (SELECT, one of DURABLE_EXCLUSIVE, DURABLE_NON_EXCLUSIVE, NON_DURABLE_EXCLUSIVE, default DURABLE_NON_EXCLUSIVE): queue access type as provisioned on the broker.message_deserializer (SELECT, one of STRING, BINARY, ION, JSON, default STRING): deserializer applied to drained messages.max_messages_per_drain (INT, default 100): maximum messages pulled per audit pass.max_drain_duration (DURATION, default PT10S): maximum polling time per audit pass.backlog_alert_threshold (INT, default 25): drained count at or above which the queue is classified BACKLOGGED.send_slack_alert (STRING, default "true"): when "true", page Slack on a BACKLOGGED classification; when "false", only log it.{{ outputs.drain_dlq_sample.messagesCount }}: number of messages drained in this pass.{{ outputs.drain_dlq_sample.uri }}: internal storage URI (kestra://) containing the drained message batch.{{ outputs.classify_backlog_status.value }}: classification string, one of BACKLOGGED, HEALTHY, PROBE_FAILED.{{ outputs.status }}: flow-level alias of the same classification.dlq_queue_name only at a dedicated dead-letter or quarantine queue, never a live production work queue.messagesCount is a bounded point-in-time sample limited by both max_messages_per_drain and max_drain_duration; a fast upstream failure can refill the queue between runs and mask sustained backlog.queue_type must match how the queue was actually provisioned on the broker; a mismatch causes a bind failure, which this flow classifies as PROBE_FAILED rather than HEALTHY.vpn must already exist on the broker; only a freshly initialized broker has a Message VPN literally named default.To start a local Solace PubSub+ Standard broker container for testing, execute:
docker run -d --name kestra-solace -p 8180:8080 -p 55555:55555 --shm-size=1g --env username_admin_globalaccesslevel=admin --env username_admin_password=admin --ulimit nofile=2448:1048576 solace/solace-pubsub-standard
If Kestra is running inside a Docker network, connect the broker container to Kestra's network:
docker network connect YOUR_KESTRA_NETWORK kestra-solace
(Run docker network ls to verify your active Kestra network name.)
