perfbase / cakephp
CakePHP integration for the Perfbase APM platform.
Requires
- php: >=8.1 <8.6
- ext-json: *
- cakephp/cakephp: ^4.4 || ^5.0
- perfbase/php-sdk: ^1.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9
README
Perfbase for CakePHP
CakePHP integration for Perfbase.
This package is a thin adapter over perfbase/php-sdk. It wires CakePHP HTTP requests and command lifecycles into the shared SDK and leaves transport, payload construction, extension handling, and submission to perfbase/php-sdk.
What it profiles
- HTTP requests on CakePHP
4.4+and5.x - CakePHP 5 console commands through command lifecycle events
- CakePHP 4 console commands when they extend
ProfiledCommand - Manual custom spans through the shared SDK client if your application resolves and uses it directly
Out of scope in v1:
- Queue profiling
- Custom buffering, retry, or transport logic
Requirements
- PHP
7.4to8.5 - CakePHP
^4.4 || ^5.0 ext-jsonperfbase/php-sdk ^1.0- The native Perfbase PHP extension in the host runtime if you want traces to be collected
The package fails open when the extension is unavailable. Your CakePHP application keeps running, but no Perfbase trace data is collected until the extension is installed and loaded.
Installation
Install the package from Packagist:
composer require perfbase/cakephp:^1.0
Install the Perfbase PHP extension if it is not already available:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"
Restart PHP-FPM, RoadRunner workers, Swoole workers, or your web server after installing the extension.
Load the plugin in your application:
use Cake\Http\BaseApplication; use Perfbase\CakePHP\PerfbasePlugin; class Application extends BaseApplication { public function bootstrap(): void { parent::bootstrap(); $this->addPlugin(PerfbasePlugin::class); } }
Once the plugin is loaded:
- HTTP profiling is enabled automatically through plugin middleware
- CakePHP 5 command profiling is enabled automatically through command events
- CakePHP 4 command profiling is available by extending
ProfiledCommand
CakePHP 4 does not get automatic command profiling. That path is CakePHP 5 only.
Quick start
Create config/perfbase.php in your application:
<?php use Perfbase\SDK\FeatureFlags; return [ 'Perfbase' => [ 'enabled' => true, 'api_key' => env('PERFBASE_API_KEY'), 'sample_rate' => 0.1, 'flags' => FeatureFlags::DefaultFlags, 'environment' => env('APP_ENV', 'production'), 'app_version' => env('APP_VERSION', ''), ], ];
Set your API key in the environment:
export PERFBASE_API_KEY=your-api-key-here
Start with a sample rate like 0.1 or lower in production, then tune based on traffic and overhead.
Configuration model
The plugin ships defaults in config/perfbase.php.
Configuration is resolved in this order:
- Package defaults
- Application
config/perfbase.phpif present - Existing
Configure::write('Perfbase', ...)values
That means explicit runtime configuration wins over file-based configuration.
Supported configuration
return [ 'Perfbase' => [ 'enabled' => false, 'debug' => false, 'log_errors' => true, 'api_key' => null, 'api_url' => 'https://ingress.perfbase.cloud', 'sample_rate' => 0.1, 'timeout' => 10, 'proxy' => null, 'flags' => \Perfbase\SDK\FeatureFlags::DefaultFlags, 'environment' => 'production', 'app_version' => '', 'include' => [ 'http' => ['*'], 'console' => ['*'], ], 'exclude' => [ 'http' => [], 'console' => [], ], ], ];
Core settings
| Setting | Default | Purpose |
|---|---|---|
enabled |
false |
Global on/off switch |
debug |
false |
Re-throw profiling failures instead of failing open |
log_errors |
true |
Log profiling failures when debug is off |
api_key |
null |
Perfbase API key |
api_url |
https://ingress.perfbase.cloud |
Receiver base URL |
sample_rate |
0.1 |
Sampling rate from 0.0 to 1.0 |
timeout |
10 |
Submission timeout in seconds |
proxy |
null |
Optional outbound proxy |
flags |
FeatureFlags::DefaultFlags |
Perfbase extension feature flags |
environment |
production |
Trace environment tag |
app_version |
'' |
Application version tag |
Runtime config
If you want to override settings programmatically, do it before the plugin uses the config:
use Cake\Core\Configure; Configure::write('Perfbase', [ 'enabled' => true, 'api_key' => env('PERFBASE_API_KEY'), 'sample_rate' => 1.0, ]);
Feature flags
The plugin passes feature flags straight through to the Perfbase extension via the shared SDK.
Examples:
use Perfbase\SDK\FeatureFlags; 'flags' => FeatureFlags::DefaultFlags; 'flags' => FeatureFlags::AllFlags; 'flags' => FeatureFlags::TrackCpuTime | FeatureFlags::TrackPdo;
Common flags:
UseCoarseClockTrackCpuTimeTrackMemoryAllocationTrackPdoTrackHttpTrackCachesTrackMongodbTrackElasticsearchTrackQueuesTrackAwsSdkTrackFileOperationsTrackFileCompilationTrackFileDefinitionsTrackExceptions
Filters
The package supports include and exclude filters for http and console contexts.
return [ 'Perfbase' => [ 'include' => [ 'http' => ['GET /users/*', 'POST /checkout'], 'console' => ['migrations:*', 'cache clear*'], ], 'exclude' => [ 'http' => ['GET /health*', '/metrics'], 'console' => ['debug:*'], ], ], ];
Supported pattern styles:
*or.*to match all- glob patterns such as
GET /admin/* - regular expressions such as
/^POST \/checkout/
The HTTP lifecycle matches against normalized identifiers, not just the raw URL. It prefers route-derived action names and falls back to stable controller/action or path identifiers when needed.
How it behaves
HTTP requests
HTTP profiling is provided by PerfbaseMiddleware. The middleware guarantees lifecycle cleanup with try/finally and attaches response or exception data before submission.
Recorded attributes include:
source=httpactionhttp_methodhttp_urlhttp_status_codeuser_ipuser_agentuser_idwhen the requestidentityattribute exposes a scalar identifierenvironmentapp_versionhostnamephp_version
Span names follow the format http.{METHOD}.{identifier}.
http_url is recorded without the query string. This is deliberate so tokens, emails, and other sensitive query parameters are not shipped as trace metadata.
CakePHP 5 console commands
CakePHP 5 command profiling is automatic once the plugin is loaded. The plugin registers Cake5ConsoleListener with the global event manager and tracks active command lifecycles by command object hash so repeated or nested commands do not collide.
Recorded attributes include:
source=consoleactionexit_codeexceptionwhen presentenvironmentapp_versionhostnamephp_version
Span names follow the format console.{command-name}.
CakePHP 4 console commands
CakePHP 4 does not expose the same global command lifecycle events as CakePHP 5. Command profiling is therefore opt-in. Extend ProfiledCommand:
namespace App\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Perfbase\CakePHP\Command\ProfiledCommand; class ExampleCommand extends ProfiledCommand { public function execute(Arguments $args, ConsoleIo $io) { $io->out('Perfbase command profiling is active.'); return static::CODE_SUCCESS; } }
Failure behavior
This package is designed to fail open:
- if the extension is unavailable, profiling is skipped
- if Perfbase submission fails, the host application continues
- if
debugistrue, profiling exceptions are rethrown to make failures visible during development
The adapter does not implement its own buffering or retry layer. Submission is delegated to the shared SDK.
Example production setup
For a low-overhead production baseline:
<?php use Perfbase\SDK\FeatureFlags; return [ 'Perfbase' => [ 'enabled' => true, 'api_key' => env('PERFBASE_API_KEY'), 'sample_rate' => 0.02, 'timeout' => 5, 'flags' => FeatureFlags::UseCoarseClock | FeatureFlags::TrackCpuTime | FeatureFlags::TrackPdo, 'environment' => env('APP_ENV', 'production'), 'app_version' => env('APP_VERSION', ''), 'exclude' => [ 'http' => ['GET /health*', '/metrics'], ], ], ];
That gives you a useful production trace stream with conservative overhead.
Troubleshooting
The extension is unavailable
Check that the extension is loaded:
php -m | grep perfbase
php --ini
If needed, reinstall it:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"
Restart any long-lived PHP workers afterwards.
No traces are appearing
Check these first:
- the plugin is loaded
- profiling is enabled
- the API key is present
- the extension is loaded
- the current request or command is allowed by your filters
- the sample rate is not set too low
Overhead is higher than expected
To reduce overhead:
- lower
sample_rate - use
UseCoarseClock - disable feature flags you do not need
- narrow include filters or widen excludes
Development
Useful commands:
composer install
composer run phpstan
composer run test
composer run lint
The package currently has full PHPUnit coverage and a clean PHPStan pass against the checked-in source.
Documentation
Full documentation is available at perfbase.com/docs.
- Docs: perfbase.com/docs
- Issues: github.com/perfbaseorg/cakephp/issues
- Support: support@perfbase.com
License
Apache-2.0. See LICENSE.txt.