bootstrap: allow exporters to add routes - #430
Conversation
The bootstrap package builds its own mux, so an exporter that serves more than /metrics and the landing page cannot adopt it. postgres_exporter, for example, serves the multi-target /probe endpoint and the net/http/pprof handlers, and node_exporter-style adoption would silently drop both. Give Bootstrap a Handle/HandleFunc pair. Routes registered from the metrics handler factory are applied to the mux next to the metrics endpoint, which keeps them constructible from state that only exists after flags are parsed, such as the logger and the loaded config. Exporters that shipped --web.telemetry-path with an environment variable also cannot keep that behavior once bootstrap owns the flag, so allow the envar name to be configured. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
e9cdc36 to
1518a47
Compare
ArthurSens
left a comment
There was a problem hiding this comment.
I don't think we want to continue using env vars in exporters. It would be better to deprecate and remove this functionality from existing exporters rather than continue building on top of it
Per review feedback on prometheus#430, exporters should not gain new env-var-backed flags; existing env var support should be deprecated and removed rather than extended. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QwjFhjwbakiAgUbfnmfJLc
Remove the env var support in here. |
Per review feedback on prometheus#430, exporters should not gain new env-var-backed flags; existing env var support should be deprecated and removed rather than extended. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QwjFhjwbakiAgUbfnmfJLc Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
8ed863e to
58bf611
Compare
ArthurSens
left a comment
There was a problem hiding this comment.
What happens if someone adds a new route that conflicts with / or /metrics? Should we provide guardrails against that?
What ever we decide, it would also be nice to have a test that confirms the behavior we want
|
Could update your node/postgres PRs with a replace in go mod, just so we can see how these changes look like downstream before we merge? |
Good suggestion, I'll take it. |
Per review feedback on prometheus#430, exporters should not gain new env-var-backed flags; existing env var support should be deprecated and removed rather than extended. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
The metricsPathFlag helper only existed to branch on MetricsPathEnvar, which was dropped in a3566c1. With no branching left, the extraction added nothing. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
Handle/HandleFunc let callers register any pattern, including the metrics path or root, which the mux would otherwise reject with a raw ServeMux panic at startup. Validate against the protected set (--web.telemetry-path and /) in newServer and return a normal error instead. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
aed14d2 to
c5b079e
Compare
…a-routes fork Lets CI show how prometheus/exporter-toolkit#430 lands downstream before that PR merges. Drop this replace once prometheus-community#430 ships in a tagged release. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
exporter-toolkit's bootstrap.Config dropped MetricsPathEnvar (see prometheus/exporter-toolkit#430) rather than grow env-var-backed flag support further. Use --web.telemetry-path instead. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
|
Sorry for the back-and-forth here, but after thinking a bit more, it feels like we shouldn't reserve the bootstrap routes. I can imagine that tons of exporters already have something running at the Maybe we should allow overrides, and our test would focus on making sure the override takes precedence over the routes that bootstrap creates? |
|
Hey @nicolastakashi, not sure if you requested my review by mistake, but my last comment is still unaddressed 😅 |
…erved Per review on prometheus#430: reserving / blocks exporters that already serve something there (Prometheus itself redirects / to /query). A caller-registered route at / now takes precedence over the generated landing page. The metrics path stays reserved, since silently losing the scrape endpoint to a route collision is a much worse failure mode than losing the landing page. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
Picks up prometheus/exporter-toolkit#430's latest revision, which allows overriding the root route while keeping the metrics path reserved. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
…outes Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com> # Conflicts: # bootstrap/bootstrap_test.go
@ArthurSens PTAL 🙏🏽 |
…a-routes fork Lets CI show how prometheus/exporter-toolkit#430 lands downstream before that PR merges. Drop this replace once prometheus-community#430 ships in a tagged release. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
exporter-toolkit's bootstrap.Config dropped MetricsPathEnvar (see prometheus/exporter-toolkit#430) rather than grow env-var-backed flag support further. Use --web.telemetry-path instead. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
Picks up prometheus/exporter-toolkit#430's latest revision, which allows overriding the root route while keeping the metrics path reserved. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
prometheus/exporter-toolkit#430 shipped in v0.19.0, so the temporary replace directive pointing at the bootstrap-extra-routes fork is no longer needed. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
The entrypoint hand-rolls what exporter-toolkit/bootstrap now provides: the web.telemetry-path / web.listen-address flags, promslog flag wiring, version output, the landing page, and the ListenAndServe call. Keeping a private copy is how exporters drift apart in flags and startup behavior. Move exporter construction into a metrics handler factory, which runs after flags are parsed, and register the multi-target /probe endpoint and the net/http/pprof and expvar (/debug/) handlers as bootstrap routes so they keep working on the mux bootstrap owns. Two flags come with bootstrap and are wired to real behavior here: --web.max-requests limits in-flight scrapes, and --web.disable-exporter-metrics drops the Go and process collectors. exporter-toolkit is bumped to v0.19.0, which ships the route-registration support this depends on (prometheus/exporter-toolkit#430). PG_EXPORTER_WEB_TELEMETRY_PATH keeps working, but bootstrap dropped env-var support for --web.telemetry-path, so instead of relocating the metrics endpoint the handler is additionally served at the env var's path (with a deprecation warning) for a compatibility window. Fatal startup errors are logged through the configured logger once one exists, falling back to stderr only for pre-parse failures. --dumpmaps and runtime shutdown are handled from main rather than exiting from inside the bootstrap callback. Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
Problem
bootstrapbuilds the exporter's HTTP mux itself:Run()registers the metrics handler at--web.telemetry-pathand the landing page at/, and nothing else can be added to it.That is enough for
node_exporter, but it blocks exporters that serve more than those two endpoints.postgres_exporteris the immediate case:/probeendpoint, which is the documented way to scrape remote instances viaauth_modulesnet/http/pprofhandlersAdopting
bootstrapas it stands would silently 404 both, so the exporter cannot move onto the shared startup path without a user-visible regression. Any exporter with a second endpoint hits the same wall, which pushes them back to hand-rolledmain()blocks — the duplicationbootstrapexists to remove.A second constraint is when those handlers can be built.
postgres_exporter's probe handler needs the logger and the loaded config file, neither of which exists until flags are parsed, so a static list of routes onConfigis not sufficient.Follow-up
Consumed by prometheus-community/postgres_exporter#1368, which moves
postgres_exporterontobootstrapwhile keeping/probeand pprof working. That PR needs a release of this one before it builds.Note: an earlier revision of this PR also let exporters back
--web.telemetry-pathwith a custom env var, to preservepostgres_exporter'sPG_EXPORTER_WEB_TELEMETRY_PATH. Per @ArthurSens's review, that's dropped — new env-var-backed flags shouldn't be added, existing ones should be deprecated/removed instead. The follow-up postgres_exporter PR will need to handle that separately.