excimetry / excimetry
Excimetry PHP package. Bridge between ext-eximer and open telemetry
Requires
- php: ^8.2
- ext-excimer: *
- google/protobuf: ^4.31
- guzzlehttp/guzzle: ^7.9
- symfony/console: ^6.4 || ^7.0
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-03-01 00:47:51 UTC
README
Excimetry
Excimetry is a PHP profiling library that provides a bridge between the ext-excimer extension and various profiling tools and platforms. It offers a simple and flexible way to profile PHP applications and export the results to various formats and backends.
Features
- Simple Configuration: Easy setup with sensible defaults
- Flexible Profiling: Control when and how profiling happens
- Multiple Export Formats:
- Collapsed format (for flamegraph tools)
- Speedscope JSON (for interactive flame graphs)
- OpenTelemetry OTLP (for integration with observability platforms)
- Multiple Backends:
- Local file storage
- HTTP/GRPC export to OpenTelemetry Collector
- Pyroscope integration
- OpenTelemetry Integration: Connect profiles with traces and metrics
- Command-line Tools: Profile PHP scripts from the command line
Requirements
- PHP 8.2 or higher
- ext-excimer extension
Installation
Installing the ext-excimer Extension
Before installing Excimetry, you need to install the ext-excimer extension. Here's how to do it:
Using PECL
pecl install excimer
Then add the following line to your php.ini file:
extension=excimer.so
From Source
git clone https://github.com/wikimedia/php-excimer.git
cd php-excimer
phpize
./configure
make
make install
Then add the following line to your php.ini file:
extension=excimer.so
Installing Excimetry
Once you have the ext-excimer extension installed, you can install Excimetry using Composer:
composer require excimetry/excimetry
To use the command-line tool globally:
composer global require excimetry/excimetry
Basic Usage
Here's a simple example of how to use Excimetry to profile a PHP application:
use Excimetry\Profiler\ExcimerProfiler; use Excimetry\Exporter\SpeedscopeExporter; use Excimetry\Backend\FileBackend; // Create a profiler with custom options $profiler = new ExcimerProfiler([ 'period' => 0.01, // 10ms sampling period 'mode' => 'wall', // Wall time profiling (also supports 'cpu') ]); // Start profiling $profiler->start(); // Your code to profile here // ... // Stop profiling $profiler->stop(); // Get the profile $log = $profiler->getLog(); // Export to speedscope format and save to a file $exporter = new SpeedscopeExporter('My Profile'); $backend = new FileBackend($exporter, 'profiles'); $backend->send($log);
Speedscope Export
Speedscope is an interactive flamegraph visualization tool that works in the browser. Excimetry can export profiles in the Speedscope JSON format, which can then be loaded into the Speedscope web app.
use Excimetry\Profiler\ExcimerProfiler; use Excimetry\Exporter\SpeedscopeExporter; use Excimetry\Backend\FileBackend; // Create a profiler $profiler = new ExcimerProfiler(); // Start profiling $profiler->start(); // Your code to profile here // ... // Stop profiling $profiler->stop(); // Get the profile $log = $profiler->getLog(); // Export to speedscope format with a custom profile name $exporter = new SpeedscopeExporter('My Custom Profile'); $backend = new FileBackend($exporter, 'profiles'); // Send the profile to the backend $backend->send($log); // The profile will be saved to a file in the 'profiles' directory // You can then load this file into https://www.speedscope.app/
Command-line Profiling
Excimetry includes a command-line tool for profiling PHP scripts. This is useful for profiling scripts that run from the command line, such as cron jobs or CLI applications.
# Basic usage excimetry-profile path/to/script.php # With custom options excimetry-profile --period=0.01 --mode=wall --format=speedscope --output=profiles path/to/script.php # Pass arguments to the script excimetry-profile path/to/script.php arg1 arg2 arg3
Options:
--period=<seconds>: Sampling period in seconds (default: 0.01)--mode=<mode>: Profiling mode: wall or cpu (default: wall)--format=<format>: Output format: speedscope or collapsed (default: speedscope)--output=<dir>: Output directory (default: profiles)--help: Display help message
OpenTelemetry Integration
OpenTelemetry is an observability framework for cloud-native software. Excimetry can send profiles to an OpenTelemetry Collector, which can then forward them to various backends.
use Excimetry\OpenTelemetry\OpenTelemetryIntegration; // Create an integration with the OpenTelemetry Collector $integration = OpenTelemetryIntegration::create( 'http://localhost:4318', // OpenTelemetry Collector URL 'my-service' // Service name ); // Start profiling $integration->start(); // Your code to profile here // ... // Stop profiling and send to OpenTelemetry $integration->stop(); // You can also add trace and span IDs to connect profiles with traces $integration->addTraceId('trace-id'); $integration->addSpanId('span-id'); // Add custom metadata $integration->addMetadata('version', '1.0.0'); $integration->addMetadata('environment', 'production'); // Access the underlying profiler and backend $profiler = $integration->getProfiler(); $backend = $integration->getBackend();
Pyroscope Integration
Pyroscope is a continuous profiling platform that helps you find performance issues in your code. Excimetry can send profiles directly to a Pyroscope server.
use Excimetry\Profiler\ExcimerProfiler; use Excimetry\Exporter\CollapsedExporter; use Excimetry\Backend\PyroscopeBackend; // Create a profiler $profiler = new ExcimerProfiler(); // Start profiling $profiler->start(); // Your code to profile here // ... // Stop profiling $profiler->stop(); // Get the profile $log = $profiler->getLog(); // Send to Pyroscope $exporter = new CollapsedExporter(); $backend = new PyroscopeBackend( serverUrl: 'http://localhost:4040', appName: 'my-application', labels: ['env' => 'production'], exporter: $exporter, ); // Send the profile to Pyroscope $backend->send($log); // You can also set the backend to send asynchronously $backend->setAsync(true); $backend->send($log); // Returns immediately, sends in background // Add custom labels $backend->addLabel('version', '1.0.0'); $backend->addLabel('region', 'us-west');
Advanced Usage
Custom Metadata
$profiler = new ExcimerProfiler(); $profiler->addMetadata('version', '1.0.0'); $profiler->addMetadata('environment', 'production');
Async Export
$backend = new HttpBackend($exporter, 'http://example.com/profiles'); $backend->setAsync(true); $backend->send($log); // Returns immediately, sends in background
Retry Configuration
$backend = new HttpBackend($exporter, 'http://example.com/profiles'); $backend->setRetryConfig(5, 1000); // 5 retries, 1 second delay $backend->send($log);
Troubleshooting
Common Issues
ext-excimer Not Found
If you get an error like "Class 'Excimer' not found", it means the ext-excimer extension is not installed or not enabled. Make sure you have installed the extension and added it to your php.ini file.
Permission Issues
If you're having trouble saving profiles to a directory, make sure the directory exists and is writable by the PHP process.
Memory Issues
Profiling can use a significant amount of memory, especially for long-running processes. If you're experiencing memory issues, try increasing the memory limit in your php.ini file or reducing the sampling frequency.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

