New to Kestra?
Use blueprints to kickstart your first workflows.
Audit Dremio Reflections and running jobs via sys.reflections and sys.jobs, alert Slack on failures, and cancel stuck jobs through the REST API.
A Dremio Reflection that stops refreshing does not fail loudly, queries that
used to hit the accelerated Reflection silently fall back to a full scan of
the raw dataset, and nobody notices until a dashboard that used to load in
two seconds takes two minutes. Likewise, a query job stuck in RUNNING for
hours quietly holds an engine slot that a real workload needs. This blueprint
queries Dremio's own sys.reflections and sys.jobs system tables on a
schedule, flags any Reflection that is FAILED, CAN_ACCELERATE_WITH_FAILURES,
or has accumulated failures, flags any job still RUNNING past a runtime
threshold, pages Slack the moment one is found or Dremio cannot be queried,
and can cancel the stuck jobs through Dremio's REST API, then re-query to
verify none remain RUNNING. plugin-jdbc-dremio ships only Query,
Queries, and Trigger, there is no SQL statement to cancel a job in
Dremio, so cancellation calls Dremio's own POST /api/v3/job/{id}/cancel
REST endpoint directly, the same pattern Dremio's own REST client uses.
probe_reflections (io.kestra.plugin.jdbc.dremio.Query) selects Reflections that are already FAILED, CAN_ACCELERATE_WITH_FAILURES, or at or above reflection_failure_threshold failures, read-only, with allowFailure: true.probe_stuck_jobs selects every job currently RUNNING; the runtime threshold is applied afterward, not in SQL, also read-only with allowFailure: true.findings (io.kestra.plugin.core.output.OutputValues) combines the failed Reflections with the jobs whose computed runtime exceeds stuck_job_after_minutes into one findings array, each entry tagged REFLECTION_FAILED or STUCK_JOB.classify_status (io.kestra.plugin.core.debug.Return) returns UNREACHABLE when either probe's rows field is not defined, AT_RISK when the findings array is non-empty, otherwise CLEAN.route_by_status (io.kestra.plugin.core.flow.Switch) branches on that string:alert_at_risk posts every finding to Slack. cancel_gate runs only when auto_cancel_stuck_jobs is true, dry_run is false, and at least one STUCK_JOB finding exists: cancel_loop (concurrencyLimit: 1) sends one REST cancel request per stuck job, reread_stuck_jobs re-queries sys.jobs for those job IDs, and verify_cancel fails the flow if any of them is still RUNNING. Failed Reflections are always report-only, there is no automated fix for a broken Reflection from this flow.alert_unreachable posts a separate Slack message.log_audit_status records a status line on every run regardless of branch.errors block alerts Slack separately if the flow itself fails outright.dremio_health_gate_schedule trigger polls every 15 minutes with explicit input overrides, shipped disabled: true and always in safe mode (auto_cancel_stuck_jobs: false, dry_run: true).status output (CLEAN / AT_RISK / UNREACHABLE) you can chart or gate other flows on.auto_cancel_stuck_jobs and dry_run.sys.reflections and sys.jobs used together for a Day 2 operations check, beyond a basic Query and transform.A one-off look at the Dremio UI's Jobs or Reflections tab proves the state for one moment. This flow keeps every audit in the execution history, turns the result into a typed output other flows can depend on, and gives you a branch to grow into real remediation, cancelling a stuck job, rebuilding a broken Reflection's dataset, or opening a ticket, without rewriting the audit itself.
sys.reflections has rows.docker run -d --name dremio -p 9047:9047 -p 31010:31010 -p 32010:32010 dremio/dremio-oss:latest, then connect it to your Kestra worker's Docker network so dremio_jdbc_url and dremio_rest_base_url resolve: docker network connect YOUR_KESTRA_NETWORK dremio (run docker network ls to find the real network name). The flow reaches Dremio on its container-internal ports over that network; the published host ports are only for browsing the Dremio UI from your own machine, after completing Dremio's first-run admin setup at http://localhost:9047.DREMIO_PASSWORD: password used by every Query task against Dremio's JDBC port.DREMIO_PAT: Dremio Personal Access Token, sent as a Bearer token to the job-cancel REST endpoint.SLACK_WEBHOOK_URL: Slack incoming webhook used for the at-risk alert, the unreachable alert, and the flow-failure alert.echo -n "<your-password>" | base64 exported as SECRET_DREMIO_PASSWORD, and likewise for SECRET_DREMIO_PAT and SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
dremio_jdbc_url |
jdbc:dremio:direct=dremio:31010 |
JDBC URL of the coordinator |
dremio_username |
dremio |
JDBC username |
dremio_rest_base_url |
http://dremio:9047 |
REST base URL, used only to cancel a job |
reflection_failure_threshold |
1 |
num_failures at or above which a Reflection is flagged |
stuck_job_after_minutes |
30 |
Runtime past which a RUNNING job is flagged |
auto_cancel_stuck_jobs |
false |
Allow the REST cancel call to run |
dry_run |
true |
Must be false for a cancel to apply |
DREMIO_PASSWORD, DREMIO_PAT, and SLACK_WEBHOOK_URL secrets.dremio_jdbc_url and dremio_rest_base_url at your coordinator.status.auto_cancel_stuck_jobs: true and dry_run: false while a long-running job is active to confirm it gets cancelled and verified.dremio_health_gate_schedule trigger, which always runs in safe mode.status (STRING): the classified outcome, {{ outputs.classify_status.value }}, also exposed as the flow-level output {{ outputs.status }}.{{ outputs.findings.values.items }}: a JSON array of every finding, each with kind, id, name, dataset, status, and detail.sys.jobs status values and the availability of sys.reflections columns can vary by Dremio version. Verify both against your own deployment before enabling the schedule.sys.reflections and sys.jobs requires a user with sufficient privileges; a restricted user may see an empty or partial result that reads as falsely CLEAN.CLEAN for that half of the check; configure at least one Reflection to exercise the AT_RISK branch.stuck_job_after_minutes is evaluated against submitted_epoch_millis, the time the job entered the system, not execution start; a job queued for a long time behind a busy engine before it starts running is not counted as stuck by this definition.CREATE TABLE AS or similar DDL/DML job that had already written partial results.Loop task to audit a multi-coordinator Dremio deployment from one flow.considered_count, matched_count, and accelerated_count from sys.reflections to alert on a Reflection nobody's queries actually use, a cost-cleanup candidate, not just an outright failure.cancel_failed to escalate to the dataset owner instead of only failing the flow.