New to Kestra?
Use blueprints to kickstart your first workflows.
Poll Grafana Loki for new ERROR log lines with Kestra and alert Discord within a minute. Stateful deduplication means the same lines never refire.
Alert on log content without running a separate alert stack. This blueprint uses io.kestra.plugin.grafana.loki.Trigger to poll Loki every minute with the LogQL query {app="checkout"} |= "ERROR". When new matching lines appear, the trigger fires the flow with the fresh lines, their count, and the latest timestamp, and a Discord message goes out immediately. A state key remembers which lines were already seen, so a noisy error that keeps appearing in the lookback window never produces duplicate alerts.
error_burst trigger (io.kestra.plugin.grafana.loki.Trigger) polls Loki every minute (interval: PT1M) with a five minute lookback (since: 5m) and up to 500 records per poll.stateKey: error_burst_checkout stores the last seen position in Kestra's state store, so only genuinely new lines start an execution.alert_discord posts the new line count ({{ trigger.count }}) and the latest entry timestamp to Discord; the full matched lines stay on the execution as trigger outputs.errors block posts a distinct Discord alert if the notification itself fails, so alerting never degrades silently.disabled: true; enable it once the secrets are in place.Loki stores the logs, but turning a LogQL match into an action still needs polling, deduplication state, retries, and a delivery channel. Kestra's Loki trigger handles all four declaratively, and because the alert is a regular flow, the reaction can grow beyond a message: open a ticket, restart a service, or snapshot surrounding context, all in the same YAML.
app label (adjust the selector to your labels).authToken (bearer token) and tenantId (sent as the X-Scope-OrgID header).LOKI_URL: Loki base URL, e.g. http://loki.monitoring:3100.DISCORD_WEBHOOK_URL: Discord incoming webhook URL.LOKI_URL and DISCORD_WEBHOOK_URL secrets to your Kestra namespace.disabled: false on the error_burst trigger and watch the first alert arrive when a matching line lands.interval and the lookback with since.query and stateKey.