PHPackages                             swoole-eloquent/profiler - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Debugging &amp; Profiling](/categories/debugging)
4. /
5. swoole-eloquent/profiler

ActiveLibrary[Debugging &amp; Profiling](/categories/debugging)

swoole-eloquent/profiler
========================

Performance profiler for swoole-eloquent library with coroutine-aware metrics tracking

00PHP

Since Nov 5Pushed 6mo agoCompare

[ Source](https://github.com/larchphp/swoole-eloquent-profiler)[ Packagist](https://packagist.org/packages/swoole-eloquent/profiler)[ RSS](/packages/swoole-eloquent-profiler/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Swoole-Eloquent Profiler
========================

[](#swoole-eloquent-profiler)

A high-performance, coroutine-aware profiler for the swoole-eloquent library. Track query execution time, connection pool metrics, transaction lifecycles, and more with minimal overhead.

Features
--------

[](#features)

- **Coroutine-Aware**: Properly isolates profiling data between concurrent coroutines
- **Query Profiling**: Track SQL queries with execution time, bindings, and success/failure status
- **Pool Metrics**: Monitor connection pool utilization, wait times, and exhaustion
- **Transaction Tracking**: Profile transaction duration and query count
- **Request Aggregation**: Aggregate metrics per HTTP request or coroutine
- **Multiple Output Formats**: CLI, JSON, and HTML reports
- **Laravel Integration**: First-class support with service provider and middleware
- **Zero Configuration**: Works out of the box with sensible defaults
- **Minimal Overhead**: Non-blocking design with efficient storage

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- Swoole extension 5.0 or higher
- Laravel 10.x or 11.x (for Laravel integration)

Installation
------------

[](#installation)

```
composer require swoole-eloquent/profiler
```

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

```
use SwooleEloquent\Connection\SwoolePostgresConnection;
use SwooleEloquent\Connection\SwoolePostgresPool;
use SwooleProfiler\Decorators\ProfiledConnection;
use SwooleProfiler\Decorators\ProfiledPool;
use SwooleProfiler\Profiler;
use SwooleProfiler\Reporters\CliReporter;

// Create your pool and connection
$pool = new SwoolePostgresPool($config, 10);
$connection = new SwoolePostgresConnection($pool, 'pgsql');

// Wrap with profiler decorators
$profiledPool = new ProfiledPool($pool);
$profiledConnection = new ProfiledConnection($connection);

// Use as normal
go(function () use ($profiledConnection) {
    $results = $profiledConnection->select('SELECT * FROM users');

    // Get metrics
    $profiler = Profiler::getInstance();
    $reporter = new CliReporter($profiler);
    echo $reporter->report();
});
```

### Laravel Integration

[](#laravel-integration)

The profiler automatically registers via package discovery.

#### Configuration

[](#configuration)

Publish the configuration file (optional):

```
php artisan vendor:publish --tag=profiler-config
```

Configure via `.env`:

```
PROFILER_ENABLED=true
PROFILER_SLOW_QUERY_THRESHOLD=100.0
PROFILER_AUTO_PROFILE_REQUESTS=true
PROFILER_ADD_HEADERS=true
```

#### Usage in Controllers

[](#usage-in-controllers)

```
use SwooleProfiler\Laravel\Facades\Profiler;

class UserController extends Controller
{
    public function index()
    {
        // Queries are automatically profiled
        $users = User::async()->where('active', true)->get();

        // Get current request metrics
        $profile = Profiler::getCurrentRequest();

        return response()->json([
            'users' => $users,
            'queries' => $profile?->getQueryCount(),
            'duration' => $profile?->getTotalQueryTime(),
        ]);
    }

    public function profilerReport()
    {
        return response()->json(Profiler::getMetrics());
    }
}
```

Architecture
------------

[](#architecture)

The profiler uses a decorator pattern to wrap connections and pools without modifying the original swoole-eloquent code:

```
┌─────────────────────────────────────────┐
│          Your Application               │
└─────────────────┬───────────────────────┘
                  │
          ┌───────▼────────┐
          │ ProfiledConnection │
          └───────┬────────┘
                  │ (decorates)
          ┌───────▼────────┐
          │ SwooleConnection │
          └───────┬────────┘
                  │
          ┌───────▼────────┐
          │  ProfiledPool   │
          └───────┬────────┘
                  │ (decorates)
          ┌───────▼────────┐
          │   SwoolePool    │
          └─────────────────┘

```

Components
----------

[](#components)

### Data Classes

[](#data-classes)

- **QueryProfile**: Stores information about a single query execution
- **PoolProfile**: Captures connection pool state at a point in time
- **TransactionProfile**: Tracks transaction lifecycle
- **RequestProfile**: Aggregates metrics for an entire request/coroutine

### Storage

[](#storage)

- **ProfilerStorage**: Coroutine-aware storage using `CoroutineContext`
- **MetricsAggregator**: Calculates statistics and aggregates data

### Decorators

[](#decorators)

- **ProfiledConnection**: Wraps database connections to intercept queries
- **ProfiledPool**: Wraps connection pools to track metrics

### Reporters

[](#reporters)

- **CliReporter**: Console output with formatted tables
- **JsonReporter**: JSON format for APIs and monitoring tools
- **HtmlReporter**: Web-based dashboard

Usage Examples
--------------

[](#usage-examples)

### Profiling a Single Request

[](#profiling-a-single-request)

```
$profiler = Profiler::getInstance();

// Start profiling
$profiler->startRequest('/api/users', 'GET');

// Execute queries
$users = $connection->select('SELECT * FROM users WHERE active = ?', [true]);

// End profiling
$profile = $profiler->endRequest();

echo "Queries: " . $profile->getQueryCount() . "\n";
echo "Duration: " . $profile->getTotalQueryTime() . " ms\n";
```

### Getting Slow Queries

[](#getting-slow-queries)

```
$profiler = Profiler::getInstance();

// Set threshold (default: 100ms)
$profiler->setSlowQueryThreshold(50.0);

// Get slow queries
$slowQueries = $profiler->getSlowQueries();

foreach ($slowQueries as $query) {
    echo sprintf(
        "[%.2f ms] %s\n",
        $query->duration,
        $query->sql
    );
}
```

### Transaction Profiling

[](#transaction-profiling)

```
$profiler = Profiler::getInstance();

$connection->beginTransaction();
// Transaction is automatically tracked

$connection->insert('INSERT INTO users (name) VALUES (?)', ['John']);
$connection->update('UPDATE users SET active = ? WHERE id = ?', [true, 1]);

$connection->commit();
// Transaction end is recorded

// Get transaction metrics
$metrics = $profiler->getMetrics();
print_r($metrics['transactions']);
```

### Multiple Output Formats

[](#multiple-output-formats)

```
use SwooleProfiler\Reporters\CliReporter;
use SwooleProfiler\Reporters\JsonReporter;
use SwooleProfiler\Reporters\HtmlReporter;

$profiler = Profiler::getInstance();

// CLI output
$cliReporter = new CliReporter($profiler);
echo $cliReporter->report();

// JSON output
$jsonReporter = new JsonReporter($profiler);
file_put_contents('profiler.json', $jsonReporter->report());

// HTML output
$htmlReporter = new HtmlReporter($profiler);
file_put_contents('profiler.html', $htmlReporter->report());
```

### HTTP Server Integration

[](#http-server-integration)

```
use Swoole\Http\Server;
use SwooleProfiler\Profiler;

$server = new Server('0.0.0.0', 9501);

$server->on('Request', function ($request, $response) {
    $profiler = Profiler::getInstance();

    // Start profiling
    $profiler->startRequest($request->server['request_uri']);

    // Handle request
    $users = $connection->select('SELECT * FROM users');

    // End profiling
    $profile = $profiler->endRequest();

    // Add headers
    $response->header('X-Query-Count', (string)$profile->getQueryCount());
    $response->header('X-Query-Time', sprintf('%.2f', $profile->getTotalQueryTime()));

    $response->end(json_encode(['users' => $users]));
});

$server->start();
```

Metrics Reference
-----------------

[](#metrics-reference)

### Summary Metrics

[](#summary-metrics)

- `total_queries`: Total number of queries executed
- `successful_queries`: Number of successful queries
- `failed_queries`: Number of failed queries
- `total_requests`: Number of profiled requests
- `total_query_time`: Total time spent executing queries (ms)
- `total_pool_wait_time`: Total time spent waiting for connections (ms)

### Query Metrics

[](#query-metrics)

- `avg_duration`: Average query execution time
- `min_duration`: Fastest query time
- `max_duration`: Slowest query time
- `queries_by_type`: Breakdown by query type (SELECT, INSERT, UPDATE, DELETE)

### Pool Metrics

[](#pool-metrics)

- `avg_utilization`: Average pool utilization percentage
- `max_utilization`: Peak pool utilization
- `exhaustion_count`: Number of times pool was exhausted

### Transaction Metrics

[](#transaction-metrics)

- `total`: Total transactions
- `committed`: Successfully committed transactions
- `rolled_back`: Rolled back transactions
- `avg_duration`: Average transaction duration
- `avg_queries_per_transaction`: Average queries per transaction

Configuration
-------------

[](#configuration-1)

### Via Config File (Laravel)

[](#via-config-file-laravel)

```
// config/profiler.php
return [
    'enabled' => true,
    'slow_query_threshold' => 100.0,
    'auto_profile_requests' => true,
    'auto_register_middleware' => false,
    'listen_query_events' => false,
    'add_headers' => true,
    'add_to_response' => false,
    'storage' => [
        'max_queries' => 1000,
        'max_requests' => 100,
    ],
];
```

### Via Code

[](#via-code)

```
$profiler = Profiler::getInstance();

// Enable/disable
$profiler->enable();
$profiler->disable();

// Set slow query threshold
$profiler->setSlowQueryThreshold(50.0);

// Clear data
$profiler->clear();
```

Performance Considerations
--------------------------

[](#performance-considerations)

The profiler is designed for minimal overhead:

- Uses native `microtime(true)` for timing
- Leverages `CoroutineContext` for efficient per-coroutine storage
- Non-blocking operations throughout
- Minimal memory footprint (~2KB per request)

Typical overhead: **&lt; 1% in production environments**

Best Practices
--------------

[](#best-practices)

1. **Enable only in development/staging**: Disable in production or use sampling
2. **Set appropriate thresholds**: Tune slow query threshold based on your needs
3. **Clear data periodically**: Use `$profiler->clear()` to prevent memory growth
4. **Use appropriate reporters**: CLI for development, JSON for monitoring tools
5. **Monitor pool metrics**: Watch for exhaustion warnings

Troubleshooting
---------------

[](#troubleshooting)

### High Pool Wait Times

[](#high-pool-wait-times)

Increase connection pool size or optimize query execution time.

```
// Increase pool size
$pool = new SwoolePostgresPool($config, 20); // Increased from 10
```

### Memory Growth

[](#memory-growth)

Clear profiling data periodically:

```
// Clear after each batch of requests
if ($profiler->getStorage()->getTotalRequestCount() > 100) {
    $profiler->clear();
}
```

### Missing Queries

[](#missing-queries)

Ensure you're using the profiled decorators:

```
// ✗ Wrong
$connection = new SwoolePostgresConnection($pool, 'pgsql');

// ✓ Correct
$baseConnection = new SwoolePostgresConnection($pool, 'pgsql');
$connection = new ProfiledConnection($baseConnection);
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

License
-------

[](#license)

MIT License

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance50

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity14

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1af48afd394c2e93bdef239df0c4fe69690c242e6acca2d16c33648670d68bb6?d=identicon)[larchiephp](/maintainers/larchiephp)

---

Top Contributors

[![larchphp](https://avatars.githubusercontent.com/u/80367064?v=4)](https://github.com/larchphp "larchphp (17 commits)")

### Embed Badge

![Health badge](/badges/swoole-eloquent-profiler/health.svg)

```
[![Health](https://phpackages.com/badges/swoole-eloquent-profiler/health.svg)](https://phpackages.com/packages/swoole-eloquent-profiler)
```

###  Alternatives

[symfony/stopwatch

Provides a way to profile code

2.8k387.2M914](/packages/symfony-stopwatch)[fruitcake/laravel-debugbar

PHP Debugbar integration for Laravel

19.1k662.9k28](/packages/fruitcake-laravel-debugbar)[spatie/ignition

A beautiful error page for PHP applications.

510147.6M69](/packages/spatie-ignition)[jokkedk/webgrind

Webgrind is a Xdebug profiling web frontend in PHP5. It implements a subset of the features of kcachegrind and installs in seconds and works on all platforms. For quick'n'dirty optimizations it does the job.

3.3k193.0k](/packages/jokkedk-webgrind)[koriym/printo

An object graph visualizer.

1421.8M2](/packages/koriym-printo)[soloterm/dumps

A Laravel command to intercept dumps from your Laravel application.

125285.7k3](/packages/soloterm-dumps)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
