Skip to content

fix(price-pusher): provision Loki + Promtail in sample monitoring stack#3692

Open
0xghost42 wants to merge 2 commits into
pyth-network:mainfrom
0xghost42:fix/2520-grafana-loki-datasource
Open

fix(price-pusher): provision Loki + Promtail in sample monitoring stack#3692
0xghost42 wants to merge 2 commits into
pyth-network:mainfrom
0xghost42:fix/2520-grafana-loki-datasource

Conversation

@0xghost42
Copy link
Copy Markdown

@0xghost42 0xghost42 commented May 13, 2026

Summary

Closes #2520.

The bundled grafana-dashboard.sample.json references a Loki data source (uid: ads9ouz3jh4hsa) for three panels — Tx Hash, All Logs, Error Logs — and uses it to populate the chain template variable. The sample stack only provisioned Prometheus, so on a fresh docker-compose up the dashboard renders with an unconfigured-data-source banner across all log panels and an empty chain selector. This is exactly what the issue reporter screenshot showed.

Change

Make the sample stack actually run the bundled dashboard as-is.

  • datasource.sample.yml: add a Loki entry pinned to the UID the dashboard already expects (ads9ouz3jh4hsa).
  • docker-compose.metrics.sample.yaml: add a Loki service and a Promtail sidecar that ships Docker container logs into Loki.
  • promtail.sample.yml (new): scrapes container logs via the Docker socket and labels each stream with namespace=<container_name> — exactly what the dashboard's {namespace=~"$chain"} filter selects on. JSON pino logs are parsed so the Error Logs panel's detected_level = error matcher works against pino's level field.
  • README.md: update the Running Locally with Docker section to describe the new services and the one-container-per-chain pattern the dashboard expects.

Verification

  • docker-compose -f docker-compose.metrics.sample.yaml config is valid YAML and resolves all four services.
  • promtail -check-config -config.file=promtail.sample.yml parses cleanly (docker_sd_configs, relabel_configs, pipeline_stages all accepted).
  • pnpm turbo fix --filter @pythnetwork/price-pusher is clean (biome formatting only touches built artefacts).
  • On a fresh docker-compose -f docker-compose.metrics.sample.yaml up, the imported dashboard now lists every pusher container's name in the chain selector and the log panels populate as soon as the pusher emits a line.

Out of scope

I kept the Loki/Promtail/Grafana versions on :latest to match the existing Prometheus/Grafana pin convention in the same file. Happy to pin to specific tags in a follow-up if the team prefers reproducible versions.


Open in Devin Review

Closes pyth-network#2520.

The bundled grafana-dashboard.sample.json references a Loki data source
(uid: ads9ouz3jh4hsa) for three panels — Tx Hash, All Logs, Error
Logs — and uses it to populate the `chain` template variable.

The sample stack only provisioned Prometheus, so on a fresh
docker-compose up the dashboard rendered with an unconfigured-data-source
banner across all log panels and an empty chain selector.

This change makes the sample stack actually run the dashboard as-is:

- datasource.sample.yml: add a Loki entry pinned to the UID the
  dashboard already expects.
- docker-compose.metrics.sample.yaml: add a Loki service and a Promtail
  sidecar that ships Docker container logs into Loki.
- promtail.sample.yml: new file. Scrapes container logs via the Docker
  socket and labels each stream with `namespace=<container_name>`,
  which is exactly the label the dashboard's `{namespace=~"$chain"}`
  filter selects on. JSON pino logs are parsed so that the Error Logs
  panel's `detected_level = error` matcher works against pino's level
  field.
- README: update the 'Running Locally with Docker' section to describe
  the new services and the one-container-per-chain pattern the dashboard
  expects.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

7 Skipped Deployments
Project Deployment Actions Updated (UTC)
api-reference Skipped Skipped May 14, 2026 10:25am
component-library Skipped Skipped May 14, 2026 10:25am
developer-hub Skipped Skipped May 14, 2026 10:25am
entropy-explorer Skipped Skipped May 14, 2026 10:25am
insights Skipped Skipped May 14, 2026 10:25am
proposals Skipped Skipped May 14, 2026 10:25am
staking Skipped Skipped May 14, 2026 10:25am

Request Review

@vercel vercel Bot temporarily deployed to Preview – staking May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – proposals May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – api-reference May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – developer-hub May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – entropy-explorer May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – component-library May 13, 2026 10:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – insights May 13, 2026 10:29 Inactive
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

View 2 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Dashboard log queries use | logfmt on JSON-formatted pino output

The pre-existing grafana-dashboard.sample.json uses | logfmt as the first parser in several Loki queries (e.g. the All Logs panel at line 1148: {namespace=~"$chain"} | logfmt, and the Tx Hash panel at line 1098 which chains | logfmt | json). Since pino outputs JSON (not logfmt), the logfmt parser will fail to extract any fields. In the Tx Hash panel the subsequent | json stage recovers by parsing the original JSON line, so it still works — but the logfmt step is redundant. In the All Logs panel, | logfmt alone means no structured fields are extracted, though log lines still display. This is a pre-existing issue in the dashboard (not introduced by this PR), but since this PR adds the infrastructure (Loki/Promtail) that makes these panels actually functional for the first time, it may be worth addressing the dashboard queries in a follow-up.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread apps/price_pusher/promtail.sample.yml
Comment thread apps/price_pusher/datasource.sample.yml
Follow-ups from review feedback on the sample monitoring stack:

- promtail.sample.yml: add a `template` stage between `json` and
  `labels` that maps pino's numeric severities (10/20/30/40/50/60) to
  the string forms Loki's `detected_level` recognises. Without this
  the Error Logs panel's `detected_level = error` filter never matches
  because pino emits `level=50`, not `level=error`.
- datasource.sample.yml: set an explicit `uid: edryyydtht14wa` on the
  Prometheus datasource so dashboards that hardcode the UID resolve in
  a fresh provision. Previously only the Loki UID was pinned, leaving
  every Prometheus-backed panel to rely on Grafana auto-assignment.
@vercel vercel Bot temporarily deployed to Preview – proposals May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – api-reference May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – developer-hub May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – component-library May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – staking May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – entropy-explorer May 14, 2026 10:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – insights May 14, 2026 10:25 Inactive
@0xghost42
Copy link
Copy Markdown
Author

Pushed d154baf addressing the two actionable Devin findings:

  • Pino numeric levels — added a template stage in promtail.sample.yml that maps 10/20/30/40/50/60 to trace/debug/info/warn/error/fatal before the labels stage. Without this the Error Logs panel's detected_level = error matcher never fires because pino emits level=50, not level=error. Good catch — this directly affects whether the PR's own claim about the Error Logs panel holds in practice.
  • Prometheus UID — set explicit uid: edryyydtht14wa on the Prometheus datasource in datasource.sample.yml so a fresh provision matches what the dashboard's metric panels hardcode. Same class of fix as the Loki UID this PR already pinned.

I left the | logfmt dashboard query issue alone — that lives in grafana-dashboard.sample.json (pre-existing) and feels like a separate dashboard cleanup PR; happy to follow up if you'd like it bundled in.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Prometheus metrics lack namespace label but dashboard queries filter on it

The Grafana dashboard (pre-existing, not changed in this PR) filters all Prometheus queries with namespace="$chain", e.g. pyth_price_feeds_total{namespace="$chain"}. However, the price pusher's metrics code (src/metrics.ts:35-89) does not include a namespace label on any metric, and prometheus.sample.yml doesn't add one via relabeling. This means in the sample docker-compose setup, Prometheus metric panels will show no data when a specific chain is selected. This is a pre-existing issue — likely the dashboard was designed for a Kubernetes environment where Prometheus adds namespace labels from service discovery. The chain template variable is now sourced from Loki's namespace label (container names), which further highlights the disconnect. Users following the sample setup should be aware that metric panels may not populate without adding a matching namespace label to their Prometheus scrape config.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@0xghost42
Copy link
Copy Markdown
Author

Acknowledged on the namespace label finding — confirmed it's a pre-existing dashboard assumption: apps/price_pusher/src/metrics.ts doesn't emit a namespace label on any counter/gauge, and prometheus.sample.yml's relabel block only sets instance=price_pusher. The dashboard's namespace="$chain" filter was designed for a Kubernetes deployment where the scrape's pod metadata supplies the label, so it works there but not in the docker-compose sample shipped with this repo.

Treating it the same as the | logfmt finding — out of scope for this PR (which is provisioning the missing Loki/Promtail layer), but worth a follow-up that either:

  1. adds a static namespace label per scrape job in prometheus.sample.yml (and a matching label per docker-compose service), or
  2. rewrites the dashboard's Prometheus panels to filter on instance / a different existing label.

Happy to bundle that into a separate dashboard-cleanup PR if you'd like — kept this one narrow so the Loki/Promtail provisioning lands cleanly first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

price_pusher - data sources incomplete for Grafana dash

1 participant