monitoring: expose GoatCounter statistics to Grafana via a textfile exporter #300

Öppen
öppnade 2026-08-01 09:02:26 +00:00 av supernaut · 0 kommentarer
Ägare

A Grafana dashboard for GoatCounter statistics is not possible today — no datasource can reach the
data, and no GoatCounter signal reaches either existing datasource. This issue is the enabling work.

Why it does not work now

  • GoatCounter runs on the monitoring VM with -db=sqlite+/data/goatcounter.sqlite3, inside a rootless
    podman named volume. Not network-reachable, not mounted into the Grafana container.
  • Datasources are VictoriaMetrics and Loki only. No SQL, no JSON/REST datasource.
  • A metric-name sweep for goat|gc_|analytic|pageview|visitor returns nothing relevant; GoatCounter
    2.7 exposes no /metrics and there is no scrape job for it. The only signal in the TSDB is
    probe_success{instance="https://stats.gitborg.se"} — liveness, zero analytics.
  • Loki has no GoatCounter logs: the Alloy agent is attached only to the gitborg play, so the
    monitoring VM ships none of its own container logs. Even if it did, stdout is request noise, not
    pageview aggregates.
  • Neither yesoreyeram-infinity-datasource nor frser-sqlite-datasource is installed.

A gitborg-user timer on the monitoring VM curls the GoatCounter API (/api/v0/stats/total,
/api/v0/stats/hits) with a token from vault, and writes node_exporter textfile metrics such as
gitborg_goatcounter_pageviews_total, _visitors_total and _pageviews_by_path{path=…}. The existing
local node scrape picks them up with no new datasource, no new plugin and no new inbound exposure.

This is the pattern the repo already uses for backup, reconciler, renovate and token-audit metrics,
so it needs no new concepts, and it gets alerting via vmalert for free. Limitation: only the aggregates
modelled up front; no ad-hoc referrer or browser exploration.

Then add a code-defined bitborg-analytics.json dashboard alongside the others.

Alternatives considered and rejected

  • Infinity datasource against the API — richest option, but installing a marketplace plugin
    conflicts with the deliberate no-phone-home posture (GF_PLUGINS_PREINSTALL_DISABLED=true,
    GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES=false, principle 1 / ADR 0020). Would need the plugin
    vendored and installed from a local URL.
  • SQLite datasource against the live file — same plugin objection, plus a concurrent-reader risk on
    a live SQLite database and dashboards coupled to GoatCounter's internal schema.
  • Migrate GoatCounter to PostgreSQL — most idiomatic for Grafana, but the database is on the
    services host and ADR 0020 §2 deliberately opens nothing new inbound there.

Bonus if the exporter lands: attaching Alloy to the monitoring VM in the same change also closes the
"monitoring host ships none of its own logs" gap.

A Grafana dashboard for GoatCounter statistics is **not possible today** — no datasource can reach the data, and no GoatCounter signal reaches either existing datasource. This issue is the enabling work. ## Why it does not work now - GoatCounter runs on the monitoring VM with `-db=sqlite+/data/goatcounter.sqlite3`, inside a rootless podman named volume. Not network-reachable, not mounted into the Grafana container. - Datasources are VictoriaMetrics and Loki only. No SQL, no JSON/REST datasource. - A metric-name sweep for `goat|gc_|analytic|pageview|visitor` returns nothing relevant; GoatCounter 2.7 exposes no `/metrics` and there is no scrape job for it. The only signal in the TSDB is `probe_success{instance="https://stats.gitborg.se"}` — liveness, zero analytics. - Loki has no GoatCounter logs: the Alloy agent is attached only to the `gitborg` play, so the monitoring VM ships none of its own container logs. Even if it did, stdout is request noise, not pageview aggregates. - Neither `yesoreyeram-infinity-datasource` nor `frser-sqlite-datasource` is installed. ## Recommended path — textfile exporter A `gitborg`-user timer on the monitoring VM curls the GoatCounter API (`/api/v0/stats/total`, `/api/v0/stats/hits`) with a token from vault, and writes node_exporter textfile metrics such as `gitborg_goatcounter_pageviews_total`, `_visitors_total` and `_pageviews_by_path{path=…}`. The existing local `node` scrape picks them up with no new datasource, no new plugin and no new inbound exposure. This is **the pattern the repo already uses** for backup, reconciler, renovate and token-audit metrics, so it needs no new concepts, and it gets alerting via vmalert for free. Limitation: only the aggregates modelled up front; no ad-hoc referrer or browser exploration. Then add a code-defined `bitborg-analytics.json` dashboard alongside the others. ## Alternatives considered and rejected - **Infinity datasource against the API** — richest option, but installing a marketplace plugin conflicts with the deliberate no-phone-home posture (`GF_PLUGINS_PREINSTALL_DISABLED=true`, `GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES=false`, principle 1 / ADR 0020). Would need the plugin vendored and installed from a local URL. - **SQLite datasource against the live file** — same plugin objection, plus a concurrent-reader risk on a live SQLite database and dashboards coupled to GoatCounter's internal schema. - **Migrate GoatCounter to PostgreSQL** — most idiomatic for Grafana, but the database is on the services host and ADR 0020 §2 deliberately opens nothing new inbound there. Bonus if the exporter lands: attaching Alloy to the monitoring VM in the same change also closes the "monitoring host ships none of its own logs" gap.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra#300
Ingen beskrivning angiven.