l3tum/prometheus-metrics-bundle
A Symfony bundle that exposes Prometheus metrics from your PHP application. Collect counters, gauges and histograms, serve them on a scrape endpoint, and let Prometheus monitor your app's health and performance with minimal setup.
Architecture fit. Unchanged. Release 1.9.0 does not alter the package's fundamental shape: it remains a Symfony bundle, resolved and booted by Symfony's Kernel and Bundle interface. There is still no ServiceProvider, no Laravel-consumable config publishing, no route file. Laravel cannot composer require this and use it as-is. The underlying promphp/prometheus_client_php remains the usable surface.
What 1.9.0 does change is the amount of glue we would be reproducing if we bypass the package. "Added status and uri to collected metrics" implies the bundle ships an HTTP-layer collector that auto-populates response status and request URI on every request. If we bypass the bundle — still the recommendation — that labeling logic becomes ours to write, typically as middleware. Call it an additional half-day, not a change in direction.
Integration feasibility. Still not feasible without a fork. The same two paths hold, with one adjustment: forking is now marginally more defensible than before, because the upstream is demonstrably not dead. That is a change in degree, not in kind — we would still be maintaining a Symfony-shaped fork inside a Laravel estate to preserve ~200 lines of configuration glue.
Technical risk.
uri label by default. If that is the literal request path (/orders/8842/edit), every order ID becomes a distinct time series. This converts a "discipline we must enforce" into "a default we must actively disable or normalize." Same risk category, materially higher likelihood.status/uri, new samples carry them, and rate()/sum by results will step-change at the upgrade boundary. Low blast radius for us (we have no existing deployment), but a real hazard for anyone already on the line./metrics leaks route names and timing distributions. Note the 1.9.0 uri label increases the disclosure surface if it emits raw paths — path segments can carry identifiers that route templates would not.Key questions. Several are new or sharpened by this release:
uri label emit the route template (/orders/{id}/edit) or the resolved path (/orders/8842/edit)? This single answer determines whether 1.9.0 is a convenience or a footgun. Everything else about the release is secondary.status/uri collection opt-in or default-on, and is there a config allowlist/denylist for URI patterns?uri label on process-wide gauges would be a design error worth reporting upstream.Stack fit. Unchanged in conclusion: do not integrate this package into Laravel. Use promphp/prometheus_client_php plus a thin internal service provider. The package remains useful as a reference for configuration shape, and 1.9.0 modestly increases that reference value — it now demonstrates a working HTTP-instrumentation pattern, which we would otherwise have to design.
If a Symfony 4/5 service exists in the estate, the calculus inverts as before, and the position improves slightly: the bundle is not abandoned, so pinning is a lower-risk bet than it was six months of assessment ago. Still vendor and pin, still plan a fork on the next major Symfony upgrade.
Migration path. Sequence for a Laravel service is largely intact — add the client library, bind a MetricsRegistry singleton with a config-selected storage adapter, expose /metrics via RenderTextFormat, port metric names and label conventions verbatim, retire the bundle reference — with two insertions:
$request->route()->uri()), never $request->path(). Write it correctly once; retrofitting means re-instrumenting under a new metric name and losing history.status as free and uri as conditional. Status codes are a bounded set and belong on HTTP metrics unconditionally. URI is only safe templated, and even then only for routes we have reviewed.No data migration exists either way: Prometheus is append-only and historical samples live in the TSDB, not the app. The 1.9.0 label addition does not create migration work — it creates a dashboard discontinuity for anyone already emitting, which we are not.
Compatibility. PHP version remains the practical constraint, and this is where 1.9.0 is genuinely informative and genuinely unresolved. A 2021-vintage bundle expects PHP 7.2–8.0; if 1.9.0 modernized the floor, that is a meaningful improvement for the Symfony-service scenario and irrelevant for the Laravel scenario. If it did not, a 2025 release on PHP 7-era constraints is its own warning. Verify against our actual runtime; do not infer from a version number. The exposition protocol (Prometheus text format 0.0.4) remains stable and is not a risk — only the PHP code is.
Sequencing.
uri question and read the 1.9.0 diff. Before adopting any of its patterns, know whether the release is safe-by-default or a trap. This gates steps 3 and 5./metrics with access control — network policy or auth — reviewed by security, not bolted on.Estimate: unchanged at 1–2 days integration, 2–3 days platform bring-up, plus ~half a day for the HTTP collector we now write ourselves instead of inheriting.
Maintenance. Revise the prior "effectively zero upstream maintenance." The package is not frozen — 1.9.0 proves someone is committing. But a single release after a long gap does not constitute a support commitment: no cadence, no security policy, still a single maintainer. The honest characterization is low-activity, not dead. If we fork, the fork is less likely to immediately diverge and more likely to be rebaseable — a real if modest improvement. If we bypass, the maintenance burden stays where it was: the healthier underlying client plus ~200 lines of our own provider glue, now plus a small middleware.
Support. Unchanged. No vendor, no SLA, no triage expectation; internal support is whoever wrote the provider. Compensating factor holds: Prometheus instrumentation conventions are public and stable, so correctness is reason-able without package-specific knowledge. The 1.9.0 changelog is a one-liner and is not a documentation substitute.
Scaling. The three dimensions hold, with the first now having a live example:
Failure modes.
| Failure | Symptom | Mitigation |
|---|---|---|
Raw uri label (new in 1.9.0) |
Series count scales with distinct URLs; Prometheus OOM, slow scrapes | Use route templates only; configure allowlist/denylist; alert on prometheus_tsdb_head_series |
| In-memory adapter in FPM | Metrics near-zero or wildly inconsistent | Mandate Redis/APCu; reject PRs using the in-memory default |
| Label addition on upgrade | Dashboards split at deploy boundary; rate() steps |
Additive labels only; annotate deploys; re-baseline dashboards deliberately |
| Redis unavailable | /metrics 500s or empty; app latency if unguarded |
Fail-open on the metrics path; instrumentation must never break the request |
/metrics publicly reachable |
Information disclosure — now including raw path segments | Network policy + auth; test from an external vantage point |
| Scrape timeout | Gaps in graphs, stale alerts | Keep the handler cheap — no DB queries inside collectors |
| Stale package on PHP upgrade | Fatal errors at boot (Symfony path only) | Vendor and pin; test upgrades in isolation; confirm 1.9.0's actual floor |
| Unlabeled histograms | No usable latency percentiles retroactively | Define buckets up front — immutable per series name |
Two rows now deserve emphasis. Histogram buckets remain a one-way door and a design-review item. The uri label is the newer one-way door: once raw paths are emitted, the series exist, the TSDB holds them, and the fix is a rename plus lost history. Decide the normalization rule before the first scrape, not after the first OOM.
Ramp-up. Unchanged for integration; moderate for the team. Instrumentation is a handful of lines; good instrumentation requires knowing counters from gauges from histograms, why rate() needs a counter, and why averages mislead. The 1.9.0 feature adds one concrete teaching item — "never label with a request path" — which is worth 10 minutes in the internal session and a line in the written standard. Package documentation explains configuration, not modeling.
Recommendation. Unchanged, with a revised rationale. Do not adopt l3tum/prometheus-metrics-bundle into a Laravel codebase — 1.9.0 adds a feature, not a Laravel ServiceProvider, so the architectural blocker is untouched. The release does mean we should stop describing the package as abandoned and start describing it as low-activity, which slightly improves the fork option and slightly weakens the case for bypassing it on maintenance grounds alone. The bypass still wins on the decisive criterion: framework fit. Use the underlying client directly with a thin internal provider and middleware, take 1.9.0 as a reference design for HTTP labeling — while treating its default uri behavior as a cautionary example rather than a template — and invest the saved effort in the platform pieces: adapter choice, scrape infrastructure, cardinality governance, and endpoint security. Those remain where the risk and the value sit.
How can I help you explore Laravel packages today?