Documentation menu
Symfony Integration
The Perfbase Symfony bundle provides automatic profiling for main HTTP requests via kernel events and console commands via Symfony Console events. Supports Symfony 5.4, 6.x, and 7.x on PHP 7.4 through 8.5.
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 your application consumes a published Symfony Flex recipe for Perfbase, the bundle and starter config can be registered for you. The package repository includes recipe source, but apps should register the bundle manually unless their Flex setup already has a published Perfbase recipe available.
// config/bundles.php
return [
// ...
Perfbase\Symfony\PerfbaseBundle::class => ['all' => true],
];Configuration
Create a starter config with your API key and enable profiling:
# config/packages/perfbase.yaml
perfbase:
enabled: true
api_key: '%env(PERFBASE_API_KEY)%'
sample_rate: 0.1
app_version: '%env(default::PERFBASE_APP_VERSION)%'Add the environment values:
PERFBASE_API_KEY=your-project-api-key
PERFBASE_APP_VERSION=1.0.0All 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%. |
profile_http_status_codes | int[] | 200..299, 500..599 | HTTP response status codes that should be submitted. |
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.http | string[] | ['*'] | HTTP allow-list filters. |
exclude.http | string[] | [] | HTTP deny-list filters. |
include.console | string[] | ['*'] | Console allow-list filters. |
exclude.console | string[] | [] | Console deny-list filters. |
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 uses the stable span name http. The route template is recorded in the action attribute when available (e.g., GET /api/users/{id} rather than 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
Symfony console commands are profiled automatically via console event listeners. The subscriber handles ConsoleEvents::COMMAND, ConsoleEvents::ERROR, and ConsoleEvents::TERMINATE.
Each command uses the stable span name cli. The command name is recorded in the action attribute, and 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 HTTP requests and console commands 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 unit of work is not sampled, no extension trace span is started.
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 client provider and request the SDK client:
use Perfbase\Symfony\Support\PerfbaseClientProvider;
class ImportService
{
public function __construct(private PerfbaseClientProvider $perfbase) {}
public function run(): void
{
$client = $this->perfbase->getClient();
if (!$client) {
return;
}
$client->startTraceSpan('import_products');
// ... do work ...
$client->stopTraceSpan('import_products');
$client->submitTrace();
}
}See the PHP SDK docs for the full API reference.