-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial Analytics
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.
- 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).
- 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.
For local development:
docker run -d --rm -p 8123:8123 clickhouse/clickhouse-server:24.8In production, run ClickHouse on its own host/managed service - separate from the bot - and give it durable storage.
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.pyOn 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.
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.
-
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
TTLonargus_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.
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-
Analytics section is empty or 403: the token is missing - set
dashboard_auth_tokenand open with?token=. -
No rows appear: confirm both
enable_per_guild=trueand a validclickhouse_dsn; without both, the sink is aNullSink. - Connection errors: check the DSN host/credentials and that ClickHouse's HTTP port (8123) is reachable from the bot.
- History and ClickHouse - sink, schema, and queries.
- Dashboard - the Analytics section and auth.
-
Configuration -
enable_per_guild,clickhouse_dsn,dashboard_auth_token.