Documentation menu
Symfony Integration
The Perfbase Symfony bundle provides automatic profiling for HTTP requests and console commands via kernel event subscribers. Supports Symfony 5.4, 6.x, and 7.x.
Installation
Install the Perfbase PHP extension first. This is what does the actual profiling:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"Then install the Symfony bundle:
composer require perfbase/symfonyIf using Symfony Flex, the bundle is registered automatically and a default config file is created at config/packages/perfbase.yaml.
Without Flex, register the bundle manually:
// config/bundles.php
return [
// ...
Perfbase\Symfony\PerfbaseBundle::class => ['all' => true],
];Configuration
The Flex recipe creates a starter config. Update it with your API key and enable profiling:
# config/packages/perfbase.yaml
perfbase:
enabled: true
api_key: '%env(PERFBASE_API_KEY)%'
sample_rate: 0.1All options
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Master on/off switch. When true, api_key is required. |
api_key | string | '' | Your project API key. Required when enabled. |
api_url | string | https://ingress.perfbase.cloud | Ingestion endpoint. Must be a valid URL. |
sample_rate | float | 0.1 | Fraction of requests to profile (0.0–1.0). 0.1 = 10%. |
timeout | int | 10 | HTTP timeout in seconds for trace submission. |
proxy | string|null | null | Optional proxy URL (http, https, socks5, socks5h). |
flags | int | DefaultFlags | SDK feature flags bitmask. See Feature flags. |
app_version | string | '' | Your application version, recorded on every trace. |
debug | bool | false | When true, profiling errors are thrown instead of silently logged. |
log_errors | bool | true | Log profiling errors via error_log(). |
Include and exclude filters
Control which routes and commands are profiled:
perfbase:
include:
http: ['*'] # All routes (default)
console: ['*'] # All commands (default)
exclude:
http: ['/health', '/_profiler/*']
console: ['cache:clear']Pattern types
- Glob patterns:
api/*,/admin/users/*(matched viafnmatch()) - Regex patterns:
/^GET \/api\//(delimited by forward slashes) - Catch-all:
*or.*matches everything
What’s matched against HTTP filters
Patterns are tested against multiple representations of the request, so you can filter by any of:
- Request path:
/api/users/42 - Method + path:
GET /api/users/42 - Route template:
/api/users/{id} - Method + route template:
GET /api/users/{id} - Route name:
app_user_show - Controller:
App\Controller\UserController::show
HTTP profiling
HTTP requests are profiled automatically via a kernel event subscriber, with no middleware to register. The subscriber hooks into four kernel events:
kernel.request: creates a profiling lifecycle and starts the trace span.kernel.response: records the HTTP status code.kernel.exception: records the exception message, and the status code for HTTP exceptions.kernel.terminate: stops the span and submits the trace. Runs after the response is sent, so submission never delays the response.
Sub-requests are automatically skipped. Only the main request is profiled.
Each request gets a span named http.{METHOD}.{path} using the route template when available (e.g., http.GET./api/users/{id} rather than http.GET./api/users/42).
Automatic attributes
| Attribute | Source |
|---|---|
hostname | gethostname() |
environment | kernel.environment |
app_version | Config value |
php_version | PHP version |
source | http |
action | e.g., GET /api/users/{id} |
http_method | Request method |
http_url | Scheme + host + path (no query string) |
http_status_code | Response status code |
user_ip | Client IP address |
user_agent | User agent string |
user_id | From Security token storage, if available |
Console command profiling
Artisan commands are profiled automatically via console event listeners. The subscriber handles ConsoleEvents::COMMAND, ConsoleEvents::ERROR, and ConsoleEvents::TERMINATE.
Each command gets a span named console.{command} (e.g., console.app:import-data). The exit code and any exceptions are recorded as attributes.
Use the exclude filter to skip noisy or long-running commands:
perfbase:
exclude:
console: ['messenger:consume', 'cache:*', 'server:*']Messenger profiling
Symfony Messenger worker profiling is not yet supported. Individual messages dispatched during an HTTP request or console command are captured as part of that request’s trace.
Sample rate
The sample rate controls what fraction of requests are profiled:
perfbase:
sample_rate: 1.0 # Profile everything (development)
sample_rate: 0.1 # 10% of requests (production)
sample_rate: 0.01 # 1% of requests (high-traffic)When a request isn’t sampled, no profiling overhead is incurred.
Error handling
Profiling never crashes your application. The bundle uses a fail-open error handling strategy:
debug: true: profiling errors are thrown as exceptions. Use this during development to catch configuration issues.debug: false(default): errors are caught silently. Iflog_errors: true(default), they are logged viaerror_log().
Every event handler is wrapped in try/catch, so a profiling bug can never disrupt your application.
Using the SDK directly
For manual profiling beyond what the automatic subscribers capture, inject the SDK client:
use Perfbase\SDK\Perfbase;
class ImportService
{
public function __construct(private Perfbase $perfbase) {}
public function run(): void
{
$this->perfbase->startTraceSpan('import-products');
// ... do work ...
$this->perfbase->stopTraceSpan('import-products');
$this->perfbase->submitTrace();
}
}The bundle registers Perfbase\SDK\Perfbase as a singleton service, so it can be autowired in any service. See the PHP SDK docs for the full API reference.