JEP-0013 Phase 3 - exporter MetricsStream - #1062
Conversation
Add the MetricsStream protocol and Go hub so Prometheus can scrape merged exporter OpenMetrics from telemetry without an exporter client yet. Generated Python stubs are included for proto consistency. Co-authored-by: Cursor <cursoragent@cursor.com>
Stop silently dropping unparseable exporter snapshots. Log the exporter and error, and increment jumpstarter_metrics_parse_errors_total so reverse-scrape omissions are visible on the same /metrics response. Co-authored-by: Cursor <cursoragent@cursor.com>
…e 3) Open a long-lived MetricsStream after GetServiceEndpoints so the telemetry hub can pull generate_latest() snapshots without replacing local /metrics.
…1058 jumpstarter-dev#1058 stopped sending jumpstarter.dev/name on Register, so identity=self.name was "unknown" and the hub rejected the stream. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning Review limit reachedNext included review available in 55 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (18)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| if await self._apply_status(message, tg): | ||
| break | ||
|
|
||
| def _session_labels(self) -> dict[str, str]: |
There was a problem hiding this comment.
@RoddieKieley questions to @cursoragent:
Questions to answer:
- Is fix: add missing exporter name in session #1059 included in our jep-0013-phase3-exporter-metricsstream branch for pull request JEP-0013 Phase 3 - exporter MetricsStream #1062?
- If it is not, does fix: add missing exporter name in session #1059 impact our implementation and thus are there required changes once we rebase on the latest main which contains fix: add missing exporter name in session #1059?
Analysis from @cursoragent:
tl;dr
#1059 is not in this branch (we’re still on #1058). _session_labels was a local workaround so Session.name wasn’t "unknown" after Register stopped sending jumpstarter.dev/name. After we rebase onto main, Session uses exporter_name= from #1059, so this helper isn’t needed for metrics/logs. We’ll drop it and keep identity=exporter_name for MetricsStream, which #1059 doesn’t cover.
In detail:
Details
#1059 is not on jep-0013-phase3-exporter-metricsstream. This PR still sits on #1058 (600a2fd2). Current main is #1059 (f1b7f240).
_session_labels() copies labels: dict[str, str] and injects jumpstarter.dev/name for local Session only, not Register.
| This PR (C) | #1059 (on main) |
|
|---|---|---|
| Problem after #1058 | Metadata.name is "unknown" (labels.get("jumpstarter.dev/name", "unknown")) |
Same "unknown" on Session metrics/logs |
| MetricsStream Register | identity=self.exporter_name (hub rejects "unknown") |
Not touched |
Local active_sessions / log exporter= |
Inject name into Session labels so self.name works |
New Session.exporter_name, passed as exporter_name=self.exporter_name; Session uses that field, not self.name |
They overlap on “don’t show exporter=unknown locally.” They do not overlap on MetricsStream identity.
On rebase onto main:
- Keep
identity=self.exporter_name. fix: add missing exporter name in session #1059 does not fix Register. Without this, MetricsStream still fails the hub identity check. - Keep fix: add missing exporter name in session #1059’s
exporter_name=self.exporter_nameon everySession(...). This branch’s Session sites arelabels=self._session_labels()and do not passexporter_name=. After rebase,session.pyusesself.exporter_name(default"unknown"). If we keep_session_labelsand dropexporter_name=, local metrics go back to"unknown". _session_labelsis not required for the fix: add missing exporter name in session #1059 metrics/log fix. After rebase, Session no longer readsself.nameforadjust_active_sessions/set_log_context.
Residual effect if we keep _session_labels: GetReport still returns session.labels, so clients would see jumpstarter.dev/name on the lease session without putting that label back on Register. #1059 does not restore that. Optional, not needed for MetricsStream.
Plan: drop _session_labels and use labels=self.labels plus exporter_name=self.exporter_name, matching #1059. Keep identity=self.exporter_name. Do not put jumpstarter.dev/name on Register.
Summary
JEP-0013 Phase 3 PR C**: the exporter MetricsStream spoke. After existing
GetServiceEndpoints/ PushLogs setup, the exporter opens a long-livedMetricsStreamand answers scrapes with the sameget_registry().generate_latest()bytes as localGET /metrics.Depends on PR A: #1060
Independent of PR B (#1061) at the protocol layer. In-cluster reverse-scrape still needs B’s metrics port
:8080. Do not merge until A is onmain, then rebase. Related PRs D–E will be linked here as they are opened.:0lab scrape.MetricsRegisterwithidentity=exporter_name(JWT exporter name), notMetadata.name.Lab /
#1058: #1058 stopped sendingjumpstarter.dev/nameon Register, soidentity=self.namebecame"unknown"and the hub (A) correctly rejected the stream. This PR registers withself.exporter_name._session_labels()still injectsjumpstarter.dev/nameonly into localSession//metricsso series are notexporter="unknown", without putting that label back on Register.Lab / exemplars: after driver ops,
generate_latest()includes OpenMetrics exemplars (# {lease_id=…}). The hub from A omits that snapshot and incrementsjumpstarter_metrics_parse_errors_total. This PR does not strip or re-encode exemplars.DEMO
The lab walkthrough for the stacked Phase 3 work (A+B+C+D+E plus lab-only Route) is on the fork demo branch, not this PR:
DEMO.md notes that MetricsStream must register with
identity=exporter_nameafter#1058. See MetricsStream during the lease for the DD-3 exemplar limitation (A), which is visible only after this spoke is connected.How this PR fits the series
flowchart TB subgraph hub ["In-cluster — PRs A and B"] Tel["telemetry MetricsStream + GET /metrics :8080"] end subgraph edge ["This PR"] Exp["exporter MetricsStreamClient"] Local["local HTTP /metrics :0"] end Reg["Phase 2 MetricsRegistry"] --> Exp Reg --> Local Exp <--> Teljep-0013-phase3-metricsstreamjep-0013-phase3-operator-imagejep-0013-phase3-exporter-metricsstreamjep-0013-phase3-loki-pushjep-0013-phase3-client-pushlogsUnique work vs PR A:
b84f9524(client) +841250fa(identity after#1058). Python-only besides the stubs already in A. If GitHub shows A's commits, that is stacking againstmain; review those two commits only.Out of scope
Session.exporter_namefor local counters). Complementary to_session_labels()here; on rebase onto currentmain, keep bothidentity=exporter_nameand passexporter_name=intoSession(...).