Laravel integration for Perfbase.
This package is a thin adapter over perfbase/php-sdk. It wires Laravel request, console, and queue lifecycles into the SDK and leaves trace transport, submission, and extension handling to the shared SDK.
- HTTP requests when the Perfbase middleware is installed
- Artisan commands through Laravel console events
- Queue jobs through Laravel queue events
- Manual custom spans through the
Perfbasefacade or injected SDK client
- PHP
7.4to8.5 - Laravel
8.x,9.x,10.x,11.x,12.x, or13.x ext-jsonext-zlibext-perfbase
Install the package from Packagist:
composer require perfbase/laravel:^1.0Install the native Perfbase extension if it is not already available:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"Restart PHP-FPM, Octane workers, Horizon workers, or your web server after installing the extension.
Publish the config file:
php artisan vendor:publish --tag="perfbase-config"Add the minimum environment variables:
PERFBASE_ENABLED=true
PERFBASE_API_KEY=your_api_key_here
PERFBASE_SAMPLE_RATE=0.1HTTP profiling is enabled only when the middleware is present.
For Laravel 8 to 10, add it to app/Http/Kernel.php:
protected $middleware = [
// ...
\Perfbase\Laravel\Middleware\PerfbaseMiddleware::class,
];Or attach it to a middleware group:
protected $middlewareGroups = [
'web' => [
// ...
\Perfbase\Laravel\Middleware\PerfbaseMiddleware::class,
],
];For Laravel 11+, register it in bootstrap/app.php:
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
use Perfbase\Laravel\Middleware\PerfbaseMiddleware;
return Application::configure(dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->append(PerfbaseMiddleware::class);
})
->create();Console and queue profiling do not need middleware. They are wired through the package service provider.
Published config lives at config/perfbase.php.
return [
'enabled' => env('PERFBASE_ENABLED', false),
'debug' => env('PERFBASE_DEBUG', false),
'log_errors' => env('PERFBASE_LOG_ERRORS', true),
'api_key' => env('PERFBASE_API_KEY'),
'sample_rate' => env('PERFBASE_SAMPLE_RATE', 0.1),
'timeout' => env('PERFBASE_TIMEOUT', 5),
'proxy' => env('PERFBASE_PROXY'),
'flags' => env('PERFBASE_FLAGS', \Perfbase\SDK\FeatureFlags::DefaultFlags),
'include' => [
'http' => ['.*'],
'console' => ['.*'],
'queue' => ['.*'],
],
'exclude' => [
'http' => [],
'console' => ['queue:work'],
'queue' => [],
],
];| Variable | Default | Purpose |
|---|---|---|
PERFBASE_ENABLED |
false |
Global on/off switch |
PERFBASE_API_KEY |
null |
Perfbase API key |
PERFBASE_SAMPLE_RATE |
0.1 |
Sampling rate from 0.0 to 1.0 |
PERFBASE_DEBUG |
false |
Re-throw profiling exceptions |
PERFBASE_LOG_ERRORS |
true |
Log profiling failures when debug is off |
PERFBASE_TIMEOUT |
5 |
Trace submission timeout in seconds |
PERFBASE_PROXY |
null |
Optional outbound proxy |
PERFBASE_FLAGS |
FeatureFlags::DefaultFlags |
Perfbase extension feature flags |
use Perfbase\SDK\FeatureFlags;
'flags' => FeatureFlags::DefaultFlags;
'flags' => FeatureFlags::AllFlags;
'flags' => FeatureFlags::TrackCpuTime | FeatureFlags::TrackPdo;Common flags:
UseCoarseClockTrackCpuTimeTrackMemoryAllocationTrackPdoTrackHttpTrackCachesTrackMongodbTrackElasticsearchTrackQueuesTrackAwsSdkTrackFileOperationsTrackFileCompilationTrackFileDefinitionsTrackExceptions
Filters are split by context: http, console, and queue.
'include' => [
'http' => ['GET /api/*', 'POST /checkout'],
'console' => ['migrate*', 'app:*'],
'queue' => ['App\\Jobs\\Important*'],
],
'exclude' => [
'http' => ['GET /health*', '_debugbar/*'],
'console' => ['queue:work', 'horizon:*'],
'queue' => ['App\\Jobs\\NoisyDebugJob'],
],Supported filter styles:
- Wildcards like
GET /api/* - Regex patterns like
/^POST \/checkout/ - Command patterns like
queue:* - Job class patterns like
App\\Jobs\\* - Controller or action strings matched through Laravel's string matcher
PerfbaseMiddleware creates an HttpTraceLifecycle for the current request.
Recorded attributes include:
source=httpactionhttp_methodhttp_urlhttp_status_codeuser_ipuser_agentuser_idwhen availableenvironmentapp_versionhostnamephp_version
The service provider listens to Laravel console events and creates a ConsoleTraceLifecycle.
Recorded attributes include:
source=consoleactionexit_codeexceptionwhen presentenvironmentapp_versionhostnamephp_version
The service provider listens to queue worker events and creates a QueueTraceLifecycle.
Recorded attributes include:
source=queueactionqueueconnectionexceptionwhen presentenvironmentapp_versionhostnamephp_version
Use the facade when you want custom spans inside your own application code:
use Perfbase\Laravel\Facades\Perfbase;
Perfbase::startTraceSpan('custom-operation', [
'operation_type' => 'data_processing',
'record_count' => '1000',
]);
Perfbase::setAttribute('processing_method', 'batch');
Perfbase::setAttribute('memory_usage', (string) memory_get_usage());
try {
processLargeDataset();
Perfbase::setAttribute('status', 'success');
} catch (\Exception $e) {
Perfbase::setAttribute('status', 'error');
Perfbase::setAttribute('error_message', $e->getMessage());
throw $e;
} finally {
Perfbase::stopTraceSpan('custom-operation');
}
$result = Perfbase::submitTrace();
if (!$result->isSuccess()) {
logger()->warning('Perfbase trace submission failed', [
'status' => $result->getStatus(),
'message' => $result->getMessage(),
'status_code' => $result->getStatusCode(),
]);
}Note that Perfbase trace attributes are string values. Cast integers and booleans before passing them to setAttribute().
You can inject the SDK client directly:
use Perfbase\SDK\Perfbase;
class DataProcessingService
{
/** @var Perfbase */
private $perfbase;
public function __construct(Perfbase $perfbase)
{
$this->perfbase = $perfbase;
}
public function processData(array $data): array
{
$this->perfbase->startTraceSpan('data-processing', [
'record_count' => (string) count($data),
'data_type' => 'user_records',
]);
try {
$result = $this->performProcessing($data);
$this->perfbase->setAttribute('processed_count', (string) count($result));
return $result;
} finally {
$this->perfbase->stopTraceSpan('data-processing');
}
}
}If your authenticated user model implements Perfbase\Laravel\Interfaces\ProfiledUser, HTTP request profiling will respect shouldBeProfiled().
use Perfbase\Laravel\Interfaces\ProfiledUser;
class User extends Authenticatable implements ProfiledUser
{
public function shouldBeProfiled(): bool
{
return $this->isAdmin() || $this->isBetaTester();
}
}If the authenticated user does not implement ProfiledUser, the package falls back to normal request filtering rules.
| Method | Description |
|---|---|
startTraceSpan($name, $attributes = []) |
Start a named span |
stopTraceSpan($name) |
Stop a named span |
setAttribute($key, $value) |
Add a string attribute to the current trace |
setFlags($flags) |
Change extension feature flags |
submitTrace() |
Submit trace data and return a SubmitResult |
getTraceData($spanName = '') |
Get raw trace data |
reset() |
Clear the current trace session |
isExtensionAvailable() |
Check whether the native extension is loaded |
The package is designed to fail open in normal operation. When profiling cannot start or trace submission fails, your Laravel request, command, or job should continue running.
Use PERFBASE_DEBUG=true if you want profiling exceptions to surface during local development.
In application tests, it is often simplest to disable profiling:
<env name="PERFBASE_ENABLED" value="false"/>You can also mock the facade:
use Perfbase\Laravel\Facades\Perfbase;
public function test_something()
{
Perfbase::shouldReceive('startTraceSpan')->once();
Perfbase::shouldReceive('stopTraceSpan')->once();
// ...
}php -m | grep perfbase
php --ini
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"- Lower
PERFBASE_SAMPLE_RATE - Use
FeatureFlags::UseCoarseClock - Disable feature flags you do not need
- Narrow your
includefilters and expand yourexcludefilters
Full documentation is available at perfbase.com/docs.
- Docs: perfbase.com/docs
- Issues: github.com/perfbaseorg/laravel/issues
- Support: support@perfbase.com
Apache-2.0. See LICENSE.txt.