perftools/xhgui-collector
Standalone XHProf data collector for storing profiles compatible with XHGUI (0.2–0.9). Supports PHP 5.3+, minimal dependencies, configurable storage/collection. Use via auto_prepend_file (web) or header for CLI. Being phased out; use perftools/php-profiler for new installs.
Install the Package
composer require perftools/xhgui-collector
Set Up Environment Variables
Configure MongoDB connection and profiling settings via .env:
XHGUI_MONGO_URI=mongodb://localhost:27017
XHGUI_MONGO_DB=xhprof
XHGUI_PROFILING_RATIO=50 # Profile 50% of requests
XHGUI_PROFILING=enabled
XHGUI_CONFIG_DIR=/path/to/config
Integrate with Laravel
Add the header to your bootstrap/app.php (or public/index.php for legacy apps):
require __DIR__.'/../../vendor/perftools/xhgui-collector/external/header.php';
Verify XHGUI Compatibility Ensure your XHGUI instance (v0.2.0–0.9.0) matches the compatibility table.
First Profiling Run Trigger a request or CLI command. Data will auto-save to MongoDB for XHGUI visualization.
Enable Profiling for a Specific Route Add middleware to toggle profiling dynamically:
// app/Http/Middleware/ProfileRequests.php
public function handle($request, Closure $next) {
if ($request->header('X-Profile')) {
putenv('XHGUI_PROFILING=enabled');
}
return $next($request);
}
Register in app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\ProfileRequests::class,
],
];
Test with Curl
curl -H "X-Profile: true" http://your-app.test/api/endpoint
Analyze in XHGUI
Open http://xhgui-host and filter by your app’s URL.
Use Laravel’s .env files to control profiling per environment:
# .env.staging
XHGUI_PROFILING_RATIO=10 # Profile 10% of staging requests
XHGUI_PROFILING=enabled
# .env.production
XHGUI_PROFILING_RATIO=1 # Rarely profile in prod
Disable profiling for non-critical paths:
// In a controller or service
if (!app()->environment('local')) {
putenv('XHGUI_PROFILING=disabled');
}
Override the default ID for structured analysis:
// Before triggering profiling
putenv('XHGUI_PROFILE_ID=feature-x-login-2024');
Extend the collector’s config via a service provider:
// app/Providers/ProfilerServiceProvider.php
public function boot() {
$this->app['config']->set('profiler.skip_built_in', true);
}
Profile only authenticated users:
// app/Http/Middleware/ProfileAuthUsers.php
public function handle($request, Closure $next) {
if (auth()->check()) {
putenv('XHGUI_PROFILING=enabled');
}
return $next($request);
}
Profile Artisan commands:
php -d auto_prepend_file=/vendor/perftools/xhgui-collector/external/header.php artisan migrate
Add to config/profiler.php:
'skip_built_in' => env('PROFILER_SKIP_BUILT_IN', true),
Now profiling data excludes strlen(), array_map(), etc.
Session Locking Issues
session()->save()) may block profiling data collection.XHGUI_SESSION_CLOSE=true in .env or manually close sessions before profiling:
session()->save();
session_write_close();
FastCGI Output Buffering
fastcgi_finish_request in header.php or set:
ini_set('output_buffering', 'off');
MongoDB Schema Mismatches
Environment Variable Overrides
.env variables may be ignored if header.php is included after Laravel’s bootstrapping.bootstrap/app.php:
// public/index.php (top of file)
require __DIR__.'/../vendor/perftools/xhgui-collector/external/header.php';
Profiling Ratio Misinterpretation
XHGUI_PROFILING_RATIO=50 profiles 50% of requests, not 50ms per request.XHGUI_PROFILING_RATIO=100 for deterministic profiling (every request).Verify Profiling is Active
Check for XHGUI_PROFILING in phpinfo() or log:
file_put_contents(
storage_path('logs/profiler-debug.log'),
print_r(getenv('XHGUI_PROFILING'), true)
);
Inspect MongoDB Data
Query the xhprof database to confirm data is stored:
mongo xhprof --eval 'db.profiles.find().limit(1).pretty()'
Check XHGUI Logs
Look for errors in xhgui/logs/ (e.g., connection issues to MongoDB).
Disable Caching Ensure OPcache is off during profiling to avoid skewed results:
php -d opcache.enable=0 artisan your:command
Custom Profile ID Logic
Override the default ID generation in header.php:
// Before require 'header.php'
define('XHGUI_PROFILE_ID', 'custom-' . uniqid());
Post-Processing Hooks Add logic after profiling data is collected:
// In a service provider
$this->app->afterResolving('profiler', function ($profiler) {
// Modify $profiler->data before storage
});
Alternative Storage Backends
Replace MongoDB with Redis or a custom saver by extending the collector’s Saver class:
// app/Extensions/XhguiRedisSaver.php
class XhguiRedisSaver extends \Xhgui\Collector\Saver\MongoSaver {
public function save($data) {
// Implement Redis logic
}
}
Dynamic Profiling Toggle
Use Laravel’s app() to enable/disable profiling:
if (app()->runningInConsole()) {
putenv('XHGUI_PROFILING=enabled');
}
XHGUI_CONFIG_DIR Priority
XHGUI_CONFIG_DIR/config.php over environment variables for advanced configs.replace_url Option
putenv('XHGUI_REPLACE_URL=http://old-host,http://new-host');
PDO Backend Support (v1.7.0+)
putenv('XHGUI_SAVER=pdo');
Upload Saver (v1.5.0+)
putenv('XHGUI_SAVER=upload');
putenv('XHGUI_UPLOAD
How can I help you explore Laravel packages today?