On this page

Observability

chronos-go is a headless library, so it ships ways to see what it is doing: a Metrics hook for counters, an Inspector API for queues and tasks, and a chronos CLI built on top of the Inspector.

Recipe: metrics

Metrics is a single-method interface the server calls once per processed task; the zero/nil Metrics disables observation entirely:

type Metrics interface {
	ObserveTask(queue, kind string, outcome TaskOutcome, dur time.Duration)
}

TaskOutcome is one of OutcomeSuccess, OutcomeRetry, or OutcomeDeadLetter. The core stays dependency-free — a ready Prometheus implementation (plus a Grafana dashboard) lives in the separate contrib/prometheus module:

cd contrib/prometheus/deploy && docker compose up --build
# Grafana: http://localhost:3000  (dashboard "chronos-go")

Recipe: the Inspector API

NewInspector wraps a Redis client and gives you the same data programmatically — the foundation the CLI (and any future UI) is built on:

rdb := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
insp := chronos.NewInspector(rdb)
queues, _ := insp.Queues(context.Background())
for _, q := range queues {
	fmt.Printf("%s: pending=%d paused=%v\n", q.Queue, q.Pending, q.Paused)
}

Queues returns a *QueueInfo per queue with per-state counts (Pending, Active, Scheduled, Retry, Archived, Completed) and its Paused flag. ListTasks(ctx, qname, state, limit) lists up to limit tasks in one of "scheduled", "retry", "archived", "completed", returning *TaskInfo entries with retry counts, the last error, and (for chains/groups) ChainPending/GroupPending. GetTask(ctx, qname, taskID) fetches one task's full detail. PauseQueue/ResumeQueue/PausedQueues administer consumption.

Recipe: the chronos CLI

The CLI wraps the Inspector for the terminal:

chronos [--redis addr] [--db n] queue ls                       # standalone (default)
chronos --cluster --redis n1:7000,n2:7001 queue ls             # Redis Cluster
chronos [flags] queue pause  <queue>                            # stop consumption (~1s); unknown names are accepted and stay paused until resume
chronos [flags] queue resume <queue>
chronos [flags] task ls   <queue> <scheduled|retry|archived|completed>
chronos [flags] task run  <queue> <task-id>
chronos [flags] task rm   <queue> <task-id>

--standalone (the default) talks to a single Redis; --cluster takes comma-separated seed nodes via --redis and — since Redis Cluster has only database 0 — rejects --db. task ls default completed is how you inspect retained successes, and task run <queue> <id> re-runs a dead-lettered task (a chain link or group member included).

Gotcha: pausing only stops consumption

queue pause stops servers from consuming the queue within about a second — enqueueing, forwarding and recovery all keep running, so work piles up as pending rather than draining. It doesn't affect priority weighting between queues either; see Queues and priority for how queue weights and consumption interact.

Full signatures are on pkg.go.dev.