Skip to content

Observability

Native Prometheus metrics, in-process traces, SQLite history series, and stall alerts — no sidecar collector required.

Updated View as Markdown

The SLA / health dashboard (per flow and per external system), /metrics without the telemetry feature, SIEM export and the monthly service report are in every build: see Health, SLA, SIEM export and service reports.

Metrics, traces and the history series need a binary built with the telemetry cargo feature (cargo build --release --features telemetry), which is not in the default feature set; without it /metrics is empty and /api/obs/{traces,series,alerts} do not exist. Alert delivery and pipeline-failure alerts work in every build (see Alerts). /metrics and /api/obs/* need the API bearer token. The connector serves Prometheus metrics and keeps in-process traces + a SQLite history series, all viewable in the editor’s Metrics panel (“Telemetry disabled” appears there on builds without the feature).

  • Metrics at /metrics: opex_connector_records_total, opex_connector_sink_total, opex_connector_push_duration_seconds, opex_connector_last_publish_ts, opex_connector_sink_stats{sink,stat} (per-sink published / dropped / backlog).
  • Traces: one span per record through source → transform → sink, queryable via /api/obs/traces.
  • History: sampled metric series in SQLite (/api/obs/series).
  • Alerts: pipeline failures (every build) and sink-stall / error detection (telemetry); delivered to webhook, Telegram, email, Microsoft Teams and WhatsApp. See Alerts.
  • Dashboards: the Metrics panel in the editor charts record rate, push and sink errors and per-sink idle time, and lists active alerts; point any external dashboard (Grafana, Datadog, etc.) at /metrics.

Alerts

telemetry.alerts configures where alerts go; any combination of channels may be set and every configured channel receives every alert (a failing channel never blocks the others).

telemetry:
  stall_threshold_secs: 300     # telemetry builds: sink silent this long -> alert
  sample_interval_secs: 15
  alerts:
    on_failure: true            # pipeline-failure alerts (default true; every build)
    window_secs: 300            # at most one alert per failing node per window (min 10)
    webhook_url: "https://hooks/ops"
    telegram: { bot_token: "${TG_TOKEN}", chat_id: "-100…" }
    email:
      smtp_host: smtp.example.com
      security: starttls        # starttls (587) | tls (465) | none (25)
      smtp_port: 587            # optional, defaults by security
      username: alerts@example.com
      password: "${SMTP_PASSWORD}"
      from: "Opex Flow <alerts@example.com>"
      to: [it-ops@example.com, integrations@example.com]
      subject_prefix: "[opex-flow]"   # optional
    teams:
      webhook_url: "${TEAMS_WEBHOOK_URL}"   # incoming webhook or Workflows URL
      format: card              # card (Adaptive Card, default) | text
    whatsapp:
      phone_number_id: "123456789012345"
      access_token: "${WHATSAPP_TOKEN}"
      to: ["6281234567890"]
      template: ops_alert       # an approved template
      language: en_US
      params: ["{title}", "{detail}"]   # fills {{1}}, {{2}} of the template body
Channel How it is sent
webhook_url POST {service, alerts:[{severity, kind, sink, message, value, title, time, error?, details?}]} JSON.
telegram Bot API sendMessage, plain text.
email SMTP through lettre with rustls (no OpenSSL). One plain-text message to all to addresses; subject [opex-flow] CRITICAL: Pipeline failure: <flow> / <node>. username and password go together; omit both for an open relay. security: none sends in clear text: trusted internal relays only.
teams One POST to the incoming-webhook / Workflows URL. card sends an Adaptive Card (type: message envelope, title, message, facts) which the Workflows “When a Teams webhook request is received” trigger and connector webhooks accept; text sends {"text": …} for legacy Office 365 connectors. The URL is a secret (anyone holding it can post).
whatsapp WhatsApp Cloud API (Meta) template message: POST {base_url}/{api_version}/{phone_number_id}/messages with Authorization: Bearer, one request per number. Business-initiated messages need an approved template; params are its body variables in order and may use {title}, {detail}, {severity}, {flow}, {node}, {error}, {count}, {invocation_id}, {time}. Newlines and runs of spaces are flattened and each value is cut at 1024 characters (Meta rules). base_url (default https://graph.facebook.com) and api_version (default v21.0) point at a compatible provider.

The config is checked at startup (--check-config too): bad addresses, URLs, phone numbers or template placeholders refuse to start rather than fail when an alert is needed.

Pipeline-failure alerts

When a record ends in failure, the connector sends an alert naming the flow, the failing node, the error and the invocation id (open it with GET /api/pipeline/trace/{invocation_id} when the invocation was sampled, or find the record in GET /api/pipeline/dead-letters). Reported are: a node that fails the record (Fail, e.g. a transform with on_error: fail, an invalid record dead-lettered at a sink), a transient failure that will be retried (sink down, HTTP 5xx), a node timeout, an exceeded step or invocation limit, a lane panic, and a push record the cloud permanently rejected (dead letter). A transform error also alerts when its on_error policy (passthrough, the default, or drop) absorbs it, because a broken mapping must not go unnoticed; the alert says what happened to the record.

Rate limit. One alert per failing node per window (window_secs, default 5 min):

  1. the first failure of a node alerts immediately, so an outage is known within seconds;
  2. further failures of that node are counted, not sent;
  3. when the window ends, one summary follows (“N more failure(s) in the last 5 min”, with the latest error) if any were counted; the next failure after a quiet window alerts at once.

Nodes are limited independently; across all nodes at most 30 alerts go out per minute (the rest are folded into their node’s next summary). So a flood of failures costs a handful of messages, and no failure waits longer than the window plus ~30 s to be reported.

POST /api/obs/test (bearer token, every build) sends a test alert to all configured channels and returns {ok, results:["teams: HTTP 202", …], channels:[{channel, ok, detail}]}. Secrets in URLs are never echoed in results or logs. The alert config is read at startup (POST /api/config/reload does not apply it): restart after changing a channel.

Stall and error alerts (telemetry builds)

The watcher raises stall (a sink silent past stall_threshold_secs), errors (push errors in the last 10 minutes) and pipeline (frames failed or dropped in the last 10 minutes) alerts, delivered through the same channels, re-notified every 20 minutes while active.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close