Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Apm Bundle Laravel Package

ozznest/apm-bundle

ozznest/apm-bundle integrates application performance monitoring into PHP apps, helping track requests, database queries, errors, and timing metrics. Configure instrumentation quickly and gain visibility into bottlenecks and runtime health.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the fit before writing code. ozznest/apm-bundle is a Symfony bundle (sf-apm-bundle), not a Laravel package. There is no ApmServiceProvider, no auto-discovery, and no config/apm.php. If you are in a Laravel codebase you have three options: (1) skip it, (2) copy the bundle's service definitions and listeners into a small Laravel package of your own, or (3) use the underlying APM client/agent directly and wire it with a service provider plus middleware. For a greenfield Laravel app, option 3 is almost always less work than porting a dormant Symfony bundle.

Minimal steps to evaluate it:

  1. composer require ozznest/apm-bundle in a scratch Symfony app (or a throwaway Laravel app if you intend to port it).
  2. Read composer.json first: check the php constraint, the symfony/* constraints, and the autoload PSR-4 namespace. A 2022-01-04 release will typically cap at Symfony 5.x/6.0 and PHP 8.0/8.1, which tells you immediately whether it will install on a modern stack.
  3. Register the bundle in config/bundles.php (Symfony) and look at DependencyInjection/Configuration.php for the full config tree — endpoint/DSN, service name, environment, enabled flag, sampling. That file, not the README, is the source of truth for options.
  4. Skim EventListener/, EventSubscriber/, and Resources/config/services.yaml to see what is auto-instrumented (kernel request/response, Doctrine, HTTP client, console) versus what you must instrument manually.
  5. First use case: get one HTTP request to produce one transaction with one child span, and verify it lands in your APM backend. Do not instrument jobs, queries, or third-party calls until that round trip is confirmed. A monitoring bundle that silently drops data is worse than no monitoring.

Budget an hour for step 2 alone. With 0 stars and 0 dependents, there is no community knowledge base to lean on; you are reading source.

Implementation Patterns

Transaction per request, spans per operation. The bundle's natural unit is the request lifecycle: a listener opens a transaction on kernel.request, closes it on kernel.terminate. In Laravel, mirror this with a middleware that starts a transaction in handle() and flushes in a terminable middleware or a terminate() method. Name transactions after the route pattern (GET /orders/{order}), never the resolved URI — IDs in transaction names destroy dashboard aggregation and inflate cardinality.

Inject the tracer, don't reach for globals. If the bundle exposes a client/tracer service, resolve it via constructor injection and bind it as a singleton in Laravel's container. Wrapping it in your own thin Apm interface pays off twice: it makes the bundle swappable for OpenTelemetry or Sentry Performance later, and it lets you no-op the implementation in tests without touching call sites.

Instrument at the boundaries, not everywhere. Useful default coverage:

  • HTTP controllers (transaction root)
  • Outbound HTTP calls (span: method + host + route, not full query string)
  • Database queries (span: normalized SQL with bindings stripped, plus row count)
  • Queue jobs and console commands (transaction per job; tag with job class and queue)
  • Cache hits/misses (span or counter)

If the bundle does not auto-wrap the Laravel HTTP client or Eloquent, add a small decorator rather than sprinkling startSpan calls through business logic.

Gate by environment and sample in production. Wire enabled to an env var (APM_ENABLED=false locally and in CI) and set a sample rate below 1.0 in high-traffic production. Disabling locally also removes the transport's latency and connection-error noise from your dev logs.

Tag releases. Attach the git SHA or release version as a transaction label so regressions can be correlated with deploys. This is usually a one-line config value or a beforeSend-style hook.

Wrap jobs and commands explicitly. Long-running queue workers are where naive APM integrations break: memory grows if transactions are never flushed, and a crashed worker loses the in-flight transaction. Wrap handle() in a try/finally that always ends the transaction.

Gotchas and Tips

It is effectively unmaintained. Last release 2022-01-04, 0 stars, 0 dependents. Expect no PHP 8.3/8.4 compatibility fixes, no Symfony 7 support, and no security patches in transitive dependencies. If you adopt it, pin the version, fork it into your VCS, and own the maintenance. Treat "will it install on our stack" as the first gate, not an afterthought.

The Laravel/Symfony impedance mismatch is the biggest cost. Bundle registration, the DI compiler pass, and the Configuration tree have no Laravel equivalents. You will be translating YAML service definitions into a service provider. Before doing that, check whether the bundle is a thin wrapper around an APM client — if so, depend on the client directly and delete the bundle from the equation.

Silent data loss is the default failure mode. Transport errors are typically swallowed or logged at debug level. When dashboards are empty, check in this order: enabled flag, DSN/endpoint reachability (curl the intake URL from the app host), sample rate, then transport logs. Add a startup log line stating whether APM is enabled and where it is sending.

Flush on terminate, not on destruct. PHP request shutdown order is not guaranteed to run your transport flush before the process exits. If the integration lacks an explicit flush-on-terminate hook, data will be intermittent under load — which is far harder to debug than a total outage.

Watch overhead and memory in workers. Query and HTTP instrumentation adds measurable latency; benchmark p50/p99 before and after on a representative endpoint. In queue workers and Octane-style long-running processes, verify transactions are closed and buffers bounded, otherwise you have introduced a slow memory leak into your most critical process.

Keep naming low-cardinality. Strip IDs, user IDs, and raw SQL literals from transaction and span names. A single careless "span: SELECT * FROM orders WHERE id = {$id}" will multiply your metric series by the size of the table.

Use the extension points rather than forking. Custom event subscribers and service decoration (overriding the client service in your container) usually cover extra instrumentation without patching vendor code. If you must fork, keep the diff to a single compatibility shim (PHP/Symfony constraints) so future merges stay trivial.

Have an exit plan. Given the maintenance profile, compare against OpenTelemetry PHP, Elastic APM's PHP agent, Sentry Performance, or Laravel Telescope/Scout before committing. Abstract behind your own interface on day one so the migration is a container binding change, not a refactor.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core