You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Taskmill provides built-in observability through two complementary systems:
Always-on internal counters — cheap AtomicU64 counters maintained regardless of feature flags, exposed via Scheduler::metrics_snapshot().
metrics crate integration (optional) — when the metrics Cargo feature is enabled, the scheduler emits counters, gauges, and histograms via the standard metrics facade. Consumers choose their exporter (Prometheus, StatsD, Datadog, etc.).
[dependencies]
taskmill = { version = "0.6", features = ["metrics"] }
metrics-exporter-prometheus = "0.16"
// Install a Prometheus exporter (or any metrics recorder).let builder = metrics_exporter_prometheus::PrometheusBuilder::new();
builder.install().expect("failed to install Prometheus recorder");// Build the scheduler — metrics are automatically emitted.let scheduler = Scheduler::builder().store_path("tasks.db").domain(Domain::<MyApp>::new().task(MyExecutor)).metrics_prefix("myapp")// → myapp_taskmill_*.metrics_label("service","ingest")// global label on every metric.build().await?;
MetricsSnapshot
Scheduler::metrics_snapshot() returns a MetricsSnapshot struct with:
Counters (cumulative since scheduler creation)
Field
Description
submitted
Total tasks accepted into the queue
dispatched
Total tasks that entered Running state
completed
Total successful completions
failed
Total failures (retryable + permanent)
failed_retryable
Subset of failed that were retryable
retried
Total retry requeue attempts
dead_lettered
Tasks that exhausted retries
superseded
Tasks replaced by newer submissions with the same dedup key
rate(taskmill_tasks_dead_lettered_total[5m]) > 0 for 5m
Critical
High retry ratio
retry ratio > 0.1 for 15m
Warning
Sustained backpressure
taskmill_pressure > 0.9 for 10m
Warning
Queue wait SLO breach
p95 queue wait > SLO for 5m
Warning
Builder API
Scheduler::builder()// Prefix all metric names: "myapp_taskmill_*".metrics_prefix("myapp")// Add global labels to every metric.metrics_label("service","ingest").metrics_label("env","production")// Suppress specific metrics (use unprefixed name).disable_metric("task_duration_seconds").build().await?;
Design Principles
Zero-cost when unused — no overhead when no metrics recorder is installed. Internal atomic counters cost a few cache lines.
Standard facade — uses the metrics crate so consumers choose their exporter.
Source-level instrumentation — metrics emitted where the event happens, not from a channel subscriber.
Bounded label cardinality — only type, module, group, and reason appear as labels. Never task_id, key, or user-provided tags.
No allocations on the hot path — label values are borrowed &str or small stack strings.