Skip to content

Tutorial Analytics

AstorisTheBrave edited this page Jun 20, 2026 · 1 revision

Tutorial: per-guild analytics with ClickHouse

A complete walkthrough for answering per-guild and per-user questions ("which commands does guild X use, and how fast?") that must never go to Prometheus because they are high cardinality (invariants 2 and 7). Argus routes them to a separate analytical path: a non-blocking event sink that batches into ClickHouse, with a dashboard Analytics section on top.

Reference (internals): History and ClickHouse. Do the Tutorial Single Bot first.

When to use this

  • You want per-guild command counts, top commands, and average durations.
  • You accept running a small OLAP store (ClickHouse) for it.

If you only need fleet-wide operational metrics, you do not need this - it is fully optional and off by default (zero overhead: the sink is a no-op NullSink).

Bare minimum requirements

  • A working Argus bot.
  • The ClickHouse extra:
pip install "argus-dpy[clickhouse]"
  • A reachable ClickHouse server.
  • A dashboard token - the analytics API fails closed without dashboard_auth_token, because per-guild data is sensitive.

Step 1: run ClickHouse

For local development:

docker run -d --rm -p 8123:8123 clickhouse/clickhouse-server:24.8

In production, run ClickHouse on its own host/managed service - separate from the bot - and give it durable storage.

Step 2: enable the analytical path

Three settings turn it on (kwargs or ARGUS_* env):

from discord.ext import commands
from argus import Argus

bot = commands.AutoShardedBot(command_prefix="!", intents=...)
Argus(
    bot,
    enable_per_guild=True,
    clickhouse_dsn="http://user:pass@clickhouse-host:8123",
    dashboard_auth_token="your-secret",   # required; the analytics API is gated
)

or:

ARGUS_ENABLE_PER_GUILD=true \
ARGUS_CLICKHOUSE_DSN=http://user:pass@clickhouse-host:8123 \
ARGUS_DASHBOARD_AUTH_TOKEN=your-secret \
DISCORD_TOKEN=... python bot.py

On first connect Argus creates the table itself:

CREATE TABLE IF NOT EXISTS argus_events (
  ts String, event LowCardinality(String), guild_id String,
  type LowCardinality(String), command String, duration_ms Float64
) ENGINE = MergeTree() ORDER BY (guild_id, ts)

Hooks emit one event per interaction / app command (with the precise duration_ms) to a bounded in-process queue; a background worker batches inserts. This path shares no labels or storage with Prometheus.

Step 3: read the analytics

Open the dashboard with your token and go to the Analytics section. It serves, per guild: interaction volume over time, top commands, per-command stats (count + average duration), and overall average duration - backed by /api/analytics/*, which is mounted only when analytics is enabled and returns 403 without the token.

Best practices

  • Always set dashboard_auth_token. Per-guild data is sensitive; the API fails closed by design. Open the dashboard via ?token= once and it is remembered.
  • The bot never blocks on ClickHouse. The sink is a bounded queue with drop-and-count on overflow (it increments a dropped counter rather than slowing the bot, invariant 3). A ClickHouse outage cannot stall your bot.
  • Run ClickHouse separately from the bot, with backups; one ClickHouse can serve a whole fleet (all processes write to it).
  • Manage growth with a TTL. Add a ClickHouse TTL on argus_events (e.g. drop rows older than 90 days) so the table stays bounded.
  • At high write volume, enable ClickHouse server-side async inserts in addition to the client-side batching Argus already does.
  • Keep it off if you do not need it - the default is zero overhead.

Testing against a real server

docker run -d --rm -p 8123:8123 clickhouse/clickhouse-server:24.8
pip install -e ".[clickhouse]" --group dev
CLICKHOUSE_DSN=http://localhost:8123 pytest -m integration -v

Troubleshooting

  • Analytics section is empty or 403: the token is missing - set dashboard_auth_token and open with ?token=.
  • No rows appear: confirm both enable_per_guild=true and a valid clickhouse_dsn; without both, the sink is a NullSink.
  • Connection errors: check the DSN host/credentials and that ClickHouse's HTTP port (8123) is reachable from the bot.

See also

Clone this wiki locally