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

Elastic Apm Symfony Bundle Laravel Package

myschoolmanagement/elastic-apm-symfony-bundle

A Symfony bundle that integrates Elastic APM with your application, providing distributed tracing, transaction and error monitoring, and performance insights. Track requests, identify bottlenecks, and diagnose failures with minimal setup and configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Check what you are actually installing first. This package is a Symfony bundle (myschoolmanagement/elastic-apm-symfony-bundle), not a Laravel package. Before adding it, inspect the README, composer.json, DependencyInjection/, and EventListener/ to confirm which Symfony/Laravel versions are supported and whether a Laravel adapter is expected. In a stock Laravel app you will usually need a small service provider or middleware bridge.
  • Install the underlying APM agent. The bundle is only a wrapper around the Elastic APM PHP agent. Confirm the extension is loaded with php -m | grep apm (or the agent is configured for your runtime). Without it, instrumentation silently does nothing.
  • Install the bundle/package:
    composer require myschoolmanagement/elastic-apm-symfony-bundle
    
  • Configure the essentials via environment variables:
    ELASTIC_APM_SERVICE_NAME=my-laravel-app
    ELASTIC_APM_SERVER_URL=http://apm-server:8200
    ELASTIC_APM_ENABLED=true
    ELASTIC_APM_ENVIRONMENT=local
    
    Publish or create the package config (config/elastic_apm.php or the bundle's equivalent) and register the bundle service provider in bootstrap/providers.php / config/app.php if you are bridging it manually.
  • First use case: load a single route, then verify in Kibana APM that an HTTP transaction appears with the expected service name, URL, and duration. Once that works, add one custom span around an external HTTP call or a slow query to confirm manual instrumentation.
  • Where to look when something is missing: the bundle's EventListener/ directory (especially anything now bound to kernel.finish_request), its DI configuration, and the agent's own log (ELASTIC_APM_LOG_LEVEL=debug).

Implementation Patterns

  • Automatic HTTP transactions. The bundle registers listeners on Symfony kernel events to start/end transactions around requests. In Laravel, confirm how those events are dispatched in your setup; if there is no Symfony HttpKernel bridge, implement equivalent start/end calls in a Laravel middleware.
  • Close transactions in terminable middleware. If you are wiring this into Laravel manually, the most reliable pattern is:
    • start the transaction in a middleware handle(),
    • attach user/request context there,
    • end the transaction in terminate() so it runs after the response is sent. This mirrors the intent of the 1.0.6 FINISH_REQUEST change without depending on Symfony's dispatcher.
  • Custom spans around slow work.
    $span = elastic_apm_begin_span('external-api', 'external.http');
    try {
        $response = Http::get('https://api.example.com/report');
    } finally {
        elastic_apm_end_span($span);
    }
    
    Use this for outbound HTTP, heavy file operations, and expensive domain logic that is not auto-instrumented.
  • User and custom context. In middleware, after authentication:
    elastic_apm_set_user_context(id: (string) $request->user()?->id);
    elastic_apm_set_custom_context([
        'tenant' => tenant()->id,
        'route'  => $request->route()?->getName(),
    ]);
    
    Keep values low-cardinality and non-sensitive.
  • Exception capture. Report exceptions from App\Exceptions\Handler::report() or a dedicated listener. This gives you APM errors even when your Laravel log handler is configured differently.
  • Queue jobs and console commands. HTTP kernel events do not fire for workers or Artisan commands. Wrap job handle() methods and command handle() methods in explicit transactions:
    $tx = elastic_apm_begin_transaction('job.process-order', 'job');
    try {
        // job work
    } finally {
        elastic_apm_end_transaction($tx);
    }
    
    Add labels such as job class, queue name, and attempt count.
  • Integration tips.
    • Keep ELASTIC_APM_ENABLED=false in local test suites unless you are actively debugging traces.
    • Use ELASTIC_APM_TRANSACTION_SAMPLE_RATE to control overhead in high-traffic apps.
    • Prefer environment-driven config and run php artisan config:cache after changes.
    • If you need custom behaviour, the bundle's event subscribers and DI compiler passes are the extension points; in Laravel, wrap those in a dedicated service provider rather than editing vendor code.

Gotchas and Tips

  • 1.0.6 moved listeners to kernel.finish_request. This is a reliability fix: transactions and listeners are now closed at the very end of the request lifecycle, which helps when exceptions or early responses previously prevented listeners from running. The practical impact is that transaction data may appear slightly later in APM, and any code that assumes a transaction has already ended before the response is sent may need adjustment.
  • kernel.finish_request is not a Laravel-native lifecycle event. Laravel's Illuminate\Foundation\Http\Kernel does not dispatch Symfony's kernel.finish_request by default. If you are not using a Symfony HttpKernel bridge, the 1.0.6 change will not automatically apply to your app. Use terminable middleware or an explicit shutdown hook to close transactions.
  • Queue workers and console commands are not covered. finish_request never fires in a long-running worker. Instrument jobs and commands manually; otherwise you will see HTTP traces but no queue or CLI traces.
  • Avoid exit, dd, and hard process termination in instrumented paths. These can bypass listener execution and drop the transaction. Let Laravel's response lifecycle complete normally.
  • Missing agent extension looks like a broken package. If no traces appear, first check php -m, ELASTIC_APM_ENABLED, and the agent log. The bundle cannot instrument anything without the underlying agent.
  • Sampling can look like missing spans. If transaction_sample_rate is below 1.0, some transactions are intentionally not sampled. Do not debug this as a package failure; set the rate to 1.0 temporarily in a staging environment.
  • Config caching surprises. After changing APM environment variables, run php artisan config:cache (or clear it) and restart PHP-FPM/workers. Long-running workers hold old config in memory.
  • Be careful with sensitive context. Do not put tokens, passwords, full request bodies, or PII into custom context or labels. Use URL ignore rules and redaction where available.
  • Long-running processes and Octane. Even if transactions are closed per request, the agent's internal state and queue can behave differently under Octane. Verify trace correlation and memory behaviour under load before rolling out broadly.
  • Version pin deliberately. 1.0.6 is a small listener-timing fix, not a feature release. If you are already on 1.0.5 and traces were being dropped on exceptional requests, this is worth upgrading; otherwise treat it as a low-risk patch and test in staging first.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle