New to Kestra?
Use blueprints to kickstart your first workflows.
Audit Dremio sys.reflections for failed or slow accelerator refreshes and alert Slack before query acceleration goes stale.
A Dremio accelerator reflection that fails to refresh degrades silently -
accelerated queries keep running, just against increasingly stale data,
with no obvious client-side error. A reflection that refreshes too
slowly erodes the same guarantee more gradually. This blueprint reads
Dremio's own sys.reflections system table to catch both failure modes,
classifies the result into a four-state risk level, and alerts on
anything but a clean bill of health.
schedule_every_30_minutes (io.kestra.plugin.core.trigger.Schedule) runs every 30 minutes, explicitly passing dremio_url and max_refresh_duration_ms through its own inputs: block so the flow is self-contained when the trigger fires. Shipped disabled so a manual run can be verified first.probe_reflection_health (io.kestra.plugin.jdbc.dremio.Query, fetchType: FETCH_ONE) runs a single aggregate SQL statement against sys.reflections, returning row.total_reflections, row.failed_count (reflections with status = 'FAILED'), and row.slow_count (reflections with last_refresh_duration_millis over the threshold), both guarded with coalesce against SUM returning NULL on an empty match set.evaluate_reflections_exist (io.kestra.plugin.core.flow.If) branches on whether total_reflections > 0.else (NO_REFLECTIONS): log_no_reflections reports that no reflections are configured at all.then (reflections exist): nested evaluate_failures (io.kestra.plugin.core.flow.If) branches on failed_count > 0.then (FAILED): list_failed_reflections fetches the failed rows (reflection_name, dataset_name, num_failures, last_failure_message), then alert_failed_reflections reports them to Slack.else: nested evaluate_slow_refresh (io.kestra.plugin.core.flow.If) branches on slow_count > 0.then (SLOW_REFRESH): list_slow_reflections fetches the over-threshold rows, then alert_slow_refresh reports them to Slack at a lower severity than FAILED.else (HEALTHY): log_reflections_healthy records a clean check.log_audit_complete always runs last, printing total_reflections, failed_count, and slow_count regardless of which branch fired.errors block alerts Slack separately if the flow itself fails outright - an unreachable coordinator or bad credentials must not read as NO_REFLECTIONS or HEALTHY.sys.reflections table, not inferred from query latency or an external agent.last_failure_message or last_refresh_duration_millis per affected reflection, instead of requiring a manual SELECT * FROM sys.reflections.sys.reflections by hand during an incident.Query driving both an aggregate system-table probe and a detail fetch, not just a plain data extract.sys.reflections queried by hand answers one moment in time; it does not decide a cadence, classify the result into a four-state risk level, or notify anyone. Kestra supplies the schedule, the HEALTHY/SLOW_REFRESH/FAILED/NO_REFLECTIONS classification as a first-class branch, and an execution history that shows exactly when a reflection degraded and what Dremio's own error message said at the time.
dremio_url).sys.reflections (available to any user who can run SQL against the coordinator).Local testing:
docker pull dremio/dremio-oss:latest
docker run -d --name dremio-oss -p 9047:9047 -p 31010:31010 -p 32010:32010 dremio/dremio-oss:latest
docker network connect YOUR_KESTRA_NETWORK dremio-oss
Run docker network ls first to find the active Kestra network name. Port 9047 serves the Dremio web UI (used once, to create the initial admin user and configure a source/reflection) and 31010 is the JDBC client port used by dremio_url; neither collides with Kestra's own UI on port 8080.
DREMIO_USERNAME / DREMIO_PASSWORD: credentials used by every io.kestra.plugin.jdbc.dremio.Query task in this flow.SLACK_WEBHOOK_URL: Slack incoming webhook used by alert_failed_reflections, alert_slow_refresh, and the errors block.SECRET_, base64-encoded - for example SECRET_DREMIO_PASSWORD=$(echo -n '<your-local-password>' | base64) - and read back in flows with {{ secret('NAME') }}.| Input | Type | Default | Purpose |
|---|---|---|---|
dremio_url |
STRING | jdbc:dremio:direct=localhost:31010 |
JDBC URL of the Dremio coordinator |
max_refresh_duration_ms |
INT | 60000 |
Duration threshold before reflection counts as SLOW_REFRESH |
outputs.probe_reflection_health.row.total_reflections / failed_count / slow_count: the aggregate counts from every run.outputs.list_failed_reflections.rows / outputs.list_slow_reflections.rows: only populated on the branch that fired, each row carrying the sys.reflections detail columns fetched for that branch.http://localhost:9047 once to create the initial admin user, add a source, and create at least one reflection on a dataset.DREMIO_USERNAME, DREMIO_PASSWORD, and SLACK_WEBHOOK_URL secrets.log_reflections_healthy or log_no_reflections fires depending on whether a reflection exists yet.alert_failed_reflections fires with the real last_failure_message.schedule_every_30_minutes once you trust the check.dataset_name with io.kestra.plugin.core.flow.Loop to post one alert per affected dataset instead of a single combined message.considered_count / matched_count / accelerated_count over time (via a Kestra KV store) to detect a reflection that is healthy but no longer being used by any query planner decision.sys.reflections is scoped to the Dremio project/cluster you connect to. On Dremio Cloud, dremio_url and credentials differ from the self-hosted software example above - see the plugin's own documented Cloud connection string.io.kestra.plugin.jdbc.dremio.Query task used for any other Dremio read.io.kestra.plugin.jdbc.dremio.Query supports only a single SQL statement per task. That is why the aggregate probe and each detail fetch are separate tasks rather than one combined query.SUM over zero matching rows returns NULL, not 0, in standard SQL. failed_count and slow_count are wrapped in coalesce(..., 0) specifically to avoid a NULL > 0 comparison in the If conditions.sys.reflections column names are taken verbatim from Dremio's own SYS.REFLECTIONS documentation, and the io.kestra.plugin.jdbc.dremio.Query properties and outputs are taken from the plugin's own source on main - but no Docker container or Kestra engine was run to execute this flow end to end.