Skip to content

feat(price-pusher): emit namespace label on all Prometheus metrics#3720

Open
0xghost42 wants to merge 2 commits into
pyth-network:mainfrom
0xghost42:feat/3692-metrics-namespace-label
Open

feat(price-pusher): emit namespace label on all Prometheus metrics#3720
0xghost42 wants to merge 2 commits into
pyth-network:mainfrom
0xghost42:feat/3692-metrics-namespace-label

Conversation

@0xghost42
Copy link
Copy Markdown

@0xghost42 0xghost42 commented May 19, 2026

Summary

Make the sample Grafana dashboard's namespace=\$chain filters actually match emitted series, which they don't today.

Background

apps/price_pusher/grafana-dashboard.sample.json queries every panel with namespace="\$chain", e.g.

pyth_price_feeds_total{namespace="\$chain"}
pyth_price_last_published_time{namespace="\$chain"}
pyth_price_update_attempts_total{namespace="\$chain", status="success"}

But apps/price_pusher/src/metrics.ts only set app="price_pusher" as the default registry label, and prometheus.sample.yml doesn't add namespace via relabeling either. The result: every panel in the sample dashboard came up empty on a fresh deployment.

Devin flagged this during the #3692 review and I acknowledged it there as pre-existing dashboard behavior worth fixing in a separate PR. This is that PR.

Wiring

  • new CLI option --metrics-namespace <name> in src/options.ts, defaulted per chain command (evm, sui, aptos, solana) so single-chain deployments work without any configuration
  • PricePusherMetrics constructor now takes a namespace: string parameter and sets it via registry.setDefaultLabels, so every existing metric series gains a namespace label without per-metric labelNames plumbing
  • each chain command (evm/sui/aptos/solana/command.ts) reads the new arg and passes through to the constructor

Operators running multiple deployments of the same chain (e.g. several EVM networks against one Grafana instance) can now set --metrics-namespace bsc-mainnet / --metrics-namespace polygon-mainnet to disambiguate. Single-deployment setups keep working unchanged — the dashboard's \$chain template var will just match the chain command name out of the box.

Bumps @pythnetwork/price-pusher to 10.5.0.

Coordination heads-up

#3689 and #3703 (both open) also bump to 10.5.0. Whichever of the three lands second/third will need a trivial rebase to 10.6.0 / 10.7.0.

Test plan

  • CLI --help exposes new --metrics-namespace option on each chain
  • Default (no --metrics-namespace): curl :9090/metrics shows pyth_*{...namespace="evm",...} (or sui/aptos/solana)
  • Override: --metrics-namespace bsc-mainnet yields namespace="bsc-mainnet" on every emitted series
  • Sample Grafana dashboard's \$chain=\$namespace panels populate end-to-end against a real pusher
  • Maintainer signoff on the per-chain default values (evm/sui/aptos/solana)

Refs #3692.


Open in Devin Review

@0xghost42 0xghost42 requested a review from a team as a code owner May 19, 2026 06:36
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 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 21, 2026 8:29am
component-library Skipped Skipped May 21, 2026 8:29am
developer-hub Skipped Skipped May 21, 2026 8:29am
entropy-explorer Skipped Skipped May 21, 2026 8:29am
insights Skipped Skipped May 21, 2026 8:29am
proposals Skipped Skipped May 21, 2026 8:29am
staking Skipped Skipped May 21, 2026 8:29am

Request Review

@vercel vercel Bot temporarily deployed to Preview – proposals May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – entropy-explorer May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – developer-hub May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – insights May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – api-reference May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – staking May 19, 2026 06:36 Inactive
@vercel vercel Bot temporarily deployed to Preview – component-library May 19, 2026 06:36 Inactive
devin-ai-integration[bot]

This comment was marked as resolved.

@vercel vercel Bot temporarily deployed to Preview – proposals May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – entropy-explorer May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – staking May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – developer-hub May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – api-reference May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – component-library May 20, 2026 07:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – insights May 20, 2026 07:24 Inactive
@0xghost42
Copy link
Copy Markdown
Author

Fair point — namespace is exactly the label Kubernetes Prometheus service discovery auto-applies to scraped pods, and with the default honor_labels: false the operator-side label gets renamed to exported_namespace and the dashboard filter silently breaks. With honor_labels: true the operator wins but loses the k8s namespace context entirely.

Pushed b37bd13 renaming everywhere to chain, which is what the dashboard's template variable was already named and avoids the collision:

  • CLI option --metrics-namespace -> --metrics-chain
  • PricePusherMetrics(logger, namespace) -> PricePusherMetrics(logger, chain) + inline comment noting why namespace was avoided
  • registry.setDefaultLabels({ app, namespace }) -> setDefaultLabels({ app, chain })
  • All four chain command files (evm/sui/aptos/solana/command.ts) updated
  • grafana-dashboard.sample.json: 14 panel queries (namespace="$chain" and {namespace=~"$chain"} Loki forms), the two legendFormat: {{namespace}} references, and the template variable's source-label query (label: 'namespace' -> label: 'chain')

Default behaviour unchanged for single-deployment operators — the CLI defaults the value to the chain command name (evm/sui/aptos/solana), so a fresh pusher still works against the sample dashboard out of the box without setting the flag.

0xghost42 added 2 commits May 21, 2026 13:58
The sample Grafana dashboard (`grafana-dashboard.sample.json`) filters
every Prometheus query by `namespace=$chain`:

  pyth_price_feeds_total{namespace="$chain"}
  pyth_price_last_published_time{namespace="$chain"}
  pyth_price_update_attempts_total{namespace="$chain", ...}
  ...

But `src/metrics.ts` only set `app="price_pusher"` as the default label
and never emitted a `namespace` label on any counter/gauge, and
`prometheus.sample.yml` did not add one via relabeling. With the
dashboard out of the box that filter matched zero series, so every
panel for a fresh deployment came up empty — flagged by Devin during
review of pyth-network#3692 and acknowledged there as pre-existing dashboard
behavior worth fixing in a separate PR. This is that PR.

Wiring:

  - new CLI option `--metrics-namespace <name>` in `src/options.ts`,
    defaulted per chain command (`evm`, `sui`, `aptos`, `solana`) so
    that single-chain deployments work without configuration
  - `PricePusherMetrics` constructor now takes a `namespace: string`
    parameter and sets it via `registry.setDefaultLabels`, so every
    existing metric series gains a `namespace` label without per-metric
    `labelNames` plumbing
  - each chain command (`evm/sui/aptos/solana/command.ts`) reads the
    new arg and passes through to the constructor

Operators running multiple deployments of the same chain (e.g. several
EVM networks against one Grafana instance) can now set
`--metrics-namespace bsc-mainnet` / `--metrics-namespace polygon-mainnet`
to disambiguate. Single-deployment setups keep working unchanged.

Bumps `@pythnetwork/price-pusher` to `10.5.0` (additive, no breaking
changes — old CLIs still work). Note: pyth-network#3689 and pyth-network#3703 also bump to
`10.5.0`, so whichever of the three lands second/third will need a
trivial rebase to `10.6.0` / `10.7.0`.

Refs pyth-network#3692.
Devin re-review on this PR pointed out that `namespace` is the label
Kubernetes Prometheus service discovery auto-applies to scraped pods
(it carries the pod's k8s namespace). With the default
`honor_labels: false` on the scrape config, my label would be renamed
to `exported_namespace` and the dashboard's `namespace=\$chain`
filter would silently break in any in-cluster deployment. With
`honor_labels: true` the operator wins but loses k8s namespace
context.

Renamed everywhere to `chain`, which is what the dashboard's template
variable was already called and avoids the collision entirely.

Renames applied:

  - CLI option `--metrics-namespace` -> `--metrics-chain` (option
    name + variable identifier + help text in
    `apps/price_pusher/src/options.ts`)
  - Constructor arg `PricePusherMetrics(logger, namespace)` ->
    `PricePusherMetrics(logger, chain)` (+ comment noting why the
    obvious name was avoided)
  - Default-label key in `registry.setDefaultLabels` from
    `namespace` to `chain`
  - Per-chain callsites in `apps/price_pusher/src/{evm,sui,aptos,solana}/command.ts`
    swap `options.metricsNamespace` / `metricsNamespace` to the new
    name
  - `apps/price_pusher/grafana-dashboard.sample.json` panel queries
    (`namespace=\"$chain\"` -> `chain=\"$chain\"`, Loki
    `{namespace=~...}` -> `{chain=~...}`, `legendFormat: {{namespace}}`
    -> `{{chain}}`) and the template variable's source label
    (`label: 'namespace'` -> `label: 'chain'` on the Loki query that
    populates `$chain`)

Same semantics, less ambiguous label. Refs pyth-network#3692.
@0xghost42 0xghost42 force-pushed the feat/3692-metrics-namespace-label branch from b37bd13 to 0ad092f Compare May 21, 2026 08:29
@vercel vercel Bot temporarily deployed to Preview – proposals May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – developer-hub May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – entropy-explorer May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – component-library May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – staking May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – insights May 21, 2026 08:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – api-reference May 21, 2026 08: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 2 new potential issues.

View 4 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.

🟡 Grafana table panel missing excludeByName entries for new chain default label columns

Adding chain as a default Prometheus label in apps/price_pusher/src/metrics.ts:38 means that table-format queries in the "Price Feeds List" panel will now produce chain, chain#B, and chain#C columns (one per query ref). The excludeByName block already excludes the analogous app/app#B/app#C columns from the pre-existing app default label, but does not exclude the new chain columns. As a result, the table will display extra unwanted columns showing the chain value in every row.

(Refers to lines 432-455)

Open in Devin Review

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

},
"editorMode": "code",
"expr": "{namespace=~\"$chain\"} | logfmt | json | msg =~ `.*(Price update successful|Transaction confirmed|Successfully updated price).*` | line_format `Tx Hash: {{.hash}}`",
"expr": "{chain=~\"$chain\"} | logfmt | json | msg =~ `.*(Price update successful|Transaction confirmed|Successfully updated price).*` | line_format `Tx Hash: {{.hash}}`",
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.

🚩 Loki stream selector assumes chain label exists on log streams

The Grafana dashboard Loki queries (e.g., {chain=~"$chain"} at lines 1080, 1130, 1167) and the template variable definition at line 1205 now query for a chain label on Loki log streams. This label is not set by the application code itself — it depends on how logs are shipped to Loki (e.g., via Promtail/Grafana Agent label configuration in Kubernetes). Previously the dashboard used namespace which is automatically applied by Kubernetes service discovery. The new chain label will need to be explicitly configured in the log pipeline (e.g., as a Promtail relabeling rule or a pod label). This is a deployment concern rather than a code bug, but operators upgrading should be aware they need to update their log shipping configuration to add a chain label.

Open in Devin Review

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

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.

1 participant