Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Metrics

cronoq reports three views of the same state:

  • Prometheus text at /metrics (cronoq-server).
  • OpenTelemetry instruments and tracing spans (the cronoq crate's default otel feature).
  • Snapshots (Scheduler::snapshot(), await sched.snapshot(), GET /v1/snapshot, Admin.Snapshot), described in Metrics and quality signals.

Window-based values cover the engine's sliding metrics window, kept in 12 buckets. The window is the last 60 seconds by default; the Rust crate sets it with CoreConfig::metrics_window (through Builder::configure), and cronoq-server and the Python package always use 60 seconds.

Prometheus (cronoq-server)

Served at GET /metrics on server.http_addr (requires the metrics or admin role) and, without authentication, on server.metrics_addr when it is set. Content type text/plain; version=0.0.4; charset=utf-8. Values are computed from a snapshot at scrape time. A standby server answers 503: scrape every instance, and the leader's series are the live ones.

Label values are escaped per the exposition format (\\, \", \n).

Per pool (label pool)

MetricTypeDescription
cronoq_pool_workersgaugeCurrent capacity: the slots of connected workers.
cronoq_pool_desired_workersgaugeAutoscaler target capacity. Feed it to KEDA or an HPA.
cronoq_pool_busy_workersgaugeSlots running an attempt.
cronoq_pool_held_workersgaugeSlots held idle for an upcoming fixed-start task.
cronoq_pool_workers_connectedgaugeConnected worker streams.
cronoq_pool_pendinggaugeTasks waiting to run, by priority (extra label class: critical, high, normal, low).
cronoq_pool_reservationsgaugeFixed-start reservations not yet started.
cronoq_pool_priority_adherencegaugeWindowed fraction of dispatches with no strictly higher class waiting (0–1).
cronoq_pool_fixed_start_hit_rategaugeWindowed fraction of fixed starts that began within tolerance (0–1).
cronoq_pool_utilizationgaugeWindowed busy slot-seconds ÷ capacity slot-seconds (0–1).
cronoq_pool_schedule_efficiencygaugeWindowed completed work seconds ÷ capacity slot-seconds (0–1).
cronoq_pool_wait_secondsgaugeWindowed time from submission to first start, by quantile (0.5, 0.9, 0.99).
cronoq_pool_cost_totalcounterWorker cost since the leader started (cost_per_worker_second × worker-seconds).
cronoq_pool_dispatched_windowgaugeAttempts dispatched within the current metrics window (default 60 s). It is a windowed count that can go down; for a lifetime rate use rate(cronoq_attempts_dispatched_total[5m]).

Server-wide

MetricTypeLabelsDescription
cronoq_workers_connectedgaugeConnected worker streams, all pools.
cronoq_live_tasksgaugeTasks not yet finished.
cronoq_running_tasksgaugeAttempts running.
cronoq_pending_tasksgaugeTasks waiting to run.
cronoq_tasks_totalcounterstatusTasks that reached succeeded, failed, dead_lettered, cancelled, skipped, missed or shed.
cronoq_tasks_submitted_totalcounterTasks admitted.
cronoq_attempts_dispatched_totalcounterAttempts dispatched.
cronoq_retries_totalcounterRetries scheduled.
cronoq_timeouts_totalcounterAttempts that hit their timeout.
cronoq_lease_expiries_totalcounterLeases that expired without a heartbeat.
cronoq_stale_completions_totalcounterCompletions and failures reported for leases that were no longer valid (late, duplicate, or from a previous leader); ignored.

Counters start at zero when a server becomes leader; rate() and increase() handle the reset on failover.

Example alerts

groups:
  - name: cronoq
    rules:
      - alert: CronoqQueueWaitHigh
        expr: cronoq_pool_wait_seconds{quantile="0.99"} > 30
        for: 10m
      - alert: CronoqUnderProvisioned
        expr: cronoq_pool_desired_workers > cronoq_pool_workers
        for: 15m
      - alert: CronoqFixedStartsMissed
        expr: cronoq_pool_fixed_start_hit_rate < 0.99
        for: 15m
      - alert: CronoqDeadLetters
        expr: increase(cronoq_tasks_total{status="dead_lettered"}[10m]) > 0
      - alert: CronoqNoWorkers
        expr: sum by (pool) (cronoq_pool_pending) > 0 and on (pool) cronoq_pool_workers_connected == 0
        for: 5m

OpenTelemetry (cronoq crate)

With the otel feature (on by default), the runtime records into the global meter provider under the meter name cronoq, so it reports into whatever pipeline the application installed. Without a provider the instruments are no-ops.

InstrumentKindAttributesDescription
cronoq.tasks.submittedcounterpoolTasks admitted.
cronoq.tasks.finishedcounterpool, statusTasks reaching a terminal status.
cronoq.attemptscounterpool, kind, outcome (ok / error)Finished attempts.
cronoq.attempt.durationhistogram (s)pool, kind, outcomeAttempt run time.
cronoq.pool.workersobservable gaugepoolCurrent capacity.
cronoq.pool.desired_workersobservable gaugepoolAutoscaler target.
cronoq.pool.busy_workersobservable gaugepoolBusy slots.
cronoq.pool.held_workersobservable gaugepoolHeld slots.
cronoq.pool.pendingobservable gaugepool, classPending tasks by class.
cronoq.pool.costobservable gaugepoolCost since start.

Observable gauges read values the runtime refreshes once per second.

Traces

Each attempt runs inside a tracing span named cronoq.task with the fields task.id, task.pool, task.kind and task.attempt. When a task is submitted inside a span and an OpenTelemetry text-map propagator is installed, the submitter's W3C trace context is stored in the task's traceparent tag; with tracing-opentelemetry installed, each attempt's span becomes a child of the submitting trace, across retries. Executors can read it with ctx.traceparent() to propagate it further.

Snapshot

All snapshot fields are described in Metrics and quality signals and, for the server's JSON form, in the HTTP reference.