monkeyscloud / monkeyslegion-devtools
Enterprise-grade debugging, profiling, inspection, and diagnostics package for MonkeysLegion β zero-magic PHP 8.4+ observability.
Package info
github.com/MonkeysCloud/MonkeysLegion-DevTools
pkg:composer/monkeyscloud/monkeyslegion-devtools
Requires
- php: ^8.4
- monkeyscloud/monkeyslegion-cli: ^2.0
- monkeyscloud/monkeyslegion-mlc: ^3.2
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
Suggests
- monkeyscloud/monkeyslegion-auth: Auth guard and permission matrix inspection
- monkeyscloud/monkeyslegion-cache: Cache hit/miss profiling and hot-key analysis
- monkeyscloud/monkeyslegion-database: Query profiling and slow-query detection
- monkeyscloud/monkeyslegion-entity: Entity metadata inspection and schema drift detection
- monkeyscloud/monkeyslegion-events: Event timeline and listener profiling
- monkeyscloud/monkeyslegion-openapi: API coverage scoring and contract validation
- monkeyscloud/monkeyslegion-router: Route collector and route inspector support
- monkeyscloud/monkeyslegion-telemetry: OpenTelemetry export and trace correlation
- monkeyscloud/monkeyslegion-validation: Validation coverage reporting
README
π MonkeysLegion DevTools
Enterprise-grade debugging, profiling, and diagnostics for MonkeysLegion v2.
Inspect every request, route, query, cache operation, event, and exception β with a self-contained debug toolbar, intelligent anomaly detection, and zero runtime overhead when disabled.
Laravel has Telescope. Symfony has the Web Profiler.
MonkeysLegion has DevTools β and it's smarter than both.
β¨ Key Features
| Feature | Description |
|---|---|
| π Zero Overhead | Early-return when disabled β no reflection, no magic, no cost |
| πͺ PHP 8.4 Property Hooks | 26 computed properties replace traditional getters across the codebase |
| π N+1 Detection | Automatic duplicate query grouping with configurable thresholds |
| β‘ Cache Intelligence | Hit/miss ratios, hot key ranking, per-store breakdown |
| π‘ Event Storm Detection | Timeline visualization with storm alerts and slow listener tracking |
| π― Deterministic Sampling | Hash-based consistency for distributed trace coherence |
| π Redaction Pipeline | Recursive key-based masking β secrets never leak, even in dev |
| π‘οΈ Request Fingerprinting | xxh3-based grouping for automatic request clustering |
| π₯οΈ Debug Toolbar | Self-contained Tokyo Night UI β no external assets required |
| π§ͺ 184 Tests | 572 assertions across 22 test files β 90%+ coverage |
π¦ Installation
composer require monkeyscloud/monkeyslegion-devtools --dev
For production diagnostics (sampling + redacted output):
composer require monkeyscloud/monkeyslegion-devtools
Requirements
- PHP 8.4+ (property hooks, asymmetric visibility)
- PSR-7 HTTP Message (
psr/http-message ^2.0) - PSR-15 Middleware (
psr/http-server-middleware ^1.0)
π Quick Start
1. Boot & Register Middleware
use MonkeysLegion\DevTools\DevToolsServiceProvider; $devtools = new DevToolsServiceProvider(); $profiler = $devtools->boot([ 'enabled' => true, 'environment' => 'local', 'sample_rate' => 1.0, 'storage' => ['driver' => 'file', 'path' => 'var/devtools/profiles'], 'collectors' => [ 'request' => true, 'route' => true, 'middleware' => true, 'query' => true, 'cache' => true, 'event' => true, 'exception' => true, ], 'toolbar' => ['enabled' => true], ]); // Add to your PSR-15 pipeline $middleware = $devtools->createMiddleware();
2. Record Intelligence Data
// Query profiling β N+1 is detected automatically $queryCollector = $profiler->getCollector('query'); $queryCollector->recordQuery('SELECT * FROM users WHERE id = ?', durationMs: 2.3, connection: 'mysql'); // Cache tracking β hot keys are ranked automatically $cacheCollector = $profiler->getCollector('cache'); $cacheCollector->recordOperation('redis', 'user:42', 'get', hit: true, durationMs: 0.4); // Event timeline β storms are flagged automatically $eventCollector = $profiler->getCollector('event'); $eventCollector->recordDispatch('App\Event\OrderPlaced', [ ['name' => 'SendConfirmation', 'duration_ms' => 45.2], ['name' => 'UpdateInventory', 'duration_ms' => 12.1], ]);
3. Inspect via CLI
# System status php ml devtools:status # List recent profiled requests (color-coded by status) php ml devtools:requests --limit=20 # Inspect the latest request in detail php ml devtools:request latest # Inspect by partial ID php ml devtools:request c461 # Export a sanitized profile for sharing php ml devtools:export latest --output=profile.json # Clear all stored profiles php ml devtools:clear
4. Debug Toolbar
When toolbar.enabled is true, the toolbar auto-injects into HTML responses:
- Toggle: Click the π bar or press
Ctrl+Shift+D - 5 Panels: Overview, Queries, Cache, Events, Exceptions
- Severity Badges: Green / Yellow / Red per-panel status at a glance
- Self-Contained: Zero external CSS/JS β embedded Tokyo Night theme
The toolbar only injects into text/html responses and respects a configurable size limit.
βοΈ Configuration
Create config/devtools.mlc:
devtools {
enabled = ${DEVTOOLS_ENABLED:true}
environment = ${APP_ENV:local}
sample_rate = ${DEVTOOLS_SAMPLE_RATE:1.0}
storage {
driver = "file"
path = "var/devtools/profiles"
retention_days = 7
max_profiles = 1000
}
collectors {
request = true
route = true
middleware = true
query = true
cache = true
event = true
exception = true
}
redaction {
enabled = true
keys = ["password", "token", "secret", "api_key", "authorization", "cookie"]
}
thresholds {
slow_request_ms = 200
slow_query_ms = 100
n_plus_one_count = 5
}
toolbar {
enabled = true
max_payload_kb = 256
}
production {
sample_rate = 0.01
}
}
π¬ Collectors
Built-in Collectors (7)
| # | Collector | Icon | Priority | Key Features |
|---|---|---|---|---|
| 1 | Request | π | 1000 | Method, URI, headers, IP hashing, fingerprint, timing, memory |
| 2 | Middleware | π | 950 | Per-middleware timing, memory delta, bottleneck detection |
| 3 | Route | π | 900 | Pattern, controller, params, middleware stack, OpenAPI hints |
| 4 | Query | ποΈ | 800 | SQL timing, N+1 detection, duplicate grouping, source tracing |
| 5 | Cache | β‘ | 700 | Hit/miss ratio, hot key ranking, per-store breakdown |
| 6 | Event | π‘ | 600 | Timeline, storm detection, slow listeners, failed tracking |
| 7 | Exception | π₯ | 100 | Class, message, trace, chain traversal, xxh3 fingerprint |
Intelligence Features
N+1 Query Detection
π΄ N+1 DETECTED: SELECT * FROM comments WHERE post_id = ? (Γ47 executions)
Source: App\Repository\CommentRepository::findByPost() at line 42
The QueryCollector automatically fingerprints SQL by normalizing literals and compares execution counts against the configurable threshold.
Cache Hot Key Analysis
π₯ Hot Keys:
user:session:abc123 (Γ84 accesses)
config:app (Γ31 accesses)
route:cache (Γ22 accesses)
Event Storm Detection
πͺοΈ STORM: App\Event\CacheInvalidated dispatched 142 times in this request
Custom Collectors
Implement CollectorInterface to add your own:
use MonkeysLegion\DevTools\Contract\CollectorInterface; use MonkeysLegion\DevTools\Profiler\ProfileContext; final class MyCollector implements CollectorInterface { public function name(): string { return 'custom'; } public function label(): string { return 'Custom'; } public function icon(): string { return 'π§'; } public function priority(): int { return 500; } public function isEnabled(): bool { return true; } public function start(ProfileContext $context): void { /* setup */ } public function stop(ProfileContext $context): void { /* teardown */ } public function collect(ProfileContext $context): array { return [...]; } } $profiler->addCollector(new MyCollector());
π·οΈ Attributes
use MonkeysLegion\DevTools\Attribute\{Profile, IgnoreProfile, Redact}; // Force profiling on a specific route with a label #[Profile(name: 'checkout.process', includePayload: true)] public function processCheckout(): Response { } // Exclude high-frequency endpoints from profiling #[IgnoreProfile(reason: 'health check')] public function healthCheck(): Response { } // Mark sensitive constructor parameters public function __construct( #[Redact] private readonly string $apiSecret, #[Redact(replacement: '***')] private readonly string $dbPassword, ) {}
πͺ PHP 8.4 Property Hooks
DevTools leverages 26 PHP 8.4 property hooks β replacing traditional getters with declarative computed properties. This is a first for PHP frameworks.
// Profile model β zero getters, all computed $profile->durationMs // float: endedAt - startedAt $profile->durationFormatted // "42.7ms" | "1.23s" | "850ΞΌs" $profile->isError // statusCode >= 400 $profile->isSlow // durationMs > threshold $profile->statusBadge // π’ π΅ π π΄ βͺ $profile->memoryPeakFormatted // "12.4 MB" $profile->memoryDelta // bytes used during request $profile->createdAtFormatted // "2026-04-27 03:42:53.087" // Profiler engine β live state hooks $profiler->isActive // currently profiling? $profiler->collectorCount // number of registered collectors $profiler->collectorNames // ['request', 'query', 'cache', ...] // QueryCollector β computed analytics $collector->queryCount // total queries recorded $collector->totalDurationMs // sum of all query times $collector->duplicateCount // grouped duplicate queries $collector->hasNPlusOne // automatic N+1 flag $collector->slowestQueryMs // max single query time // CacheCollector β computed metrics $collector->hitRatio // hits / total (float) $collector->hitRatioFormatted // "85.7%" $collector->operationCount // total operations tracked // EventCollector β computed state $collector->hasStorm // event storm detected? $collector->failedListenerCount // listeners that threw $collector->totalListenerMs // aggregate listener time // ServiceProvider β boot state $provider->booted // has boot() been called? $provider->profiler // resolved Profiler instance $provider->toolbar // resolved ToolbarRenderer
Asymmetric Visibility
All mutable state uses private(set) β the profiler's internal state is read-only for external consumers:
public private(set) string $id; public private(set) bool $booted = false; public private(set) ?Profiler $profiler = null;
ποΈ Storage Drivers
| Driver | Use Case | Persistence |
|---|---|---|
FileProfileStorage |
Local development β JSON files with index | β Disk |
MemoryProfileStorage |
Testing & benchmarks | β Request-scoped |
NullProfileStorage |
Disabled / CI environments | β No-op |
File storage features:
- JSON format β human-readable, diffable, grep-friendly
- Index file β fast listing without deserializing all profiles
- Retention pruning β automatic cleanup on write (no cron needed)
- Query filtering β method, URI, status, duration, environment, time range
π₯οΈ Debug Toolbar Panels
Overview Panel
Request summary, performance alerts (slow/error), and collector badge aggregation.
Query Panel
SQL listing with per-query timing, duplicate warnings (π‘), and N+1 alerts (π΄). Source file tracing for each query.
Cache Panel
Hit/miss ratio gauges, per-store breakdown table, and π₯ hot key ranking.
Event Panel
Chronological timeline with relative timestamps, storm warnings (πͺοΈ), and failed listener tracking.
Exception Panel
Error display with class highlighting, sanitized stack traces, and previous exception chain traversal.
Custom Panels
Extend AbstractPanel to add your own:
use MonkeysLegion\DevTools\Toolbar\AbstractPanel; use MonkeysLegion\DevTools\Profiler\Profile; final class MyPanel extends AbstractPanel { public function id(): string { return 'custom'; } public function label(): string { return 'Custom'; } public function icon(): string { return 'π§'; } public function priority(): int { return 400; } public function badge(Profile $profile): string { return '3 items'; } public function badgeSeverity(Profile $profile): string { return 'ok'; } public function render(Profile $profile): string { return $this->section('Data', $this->renderTable([ 'Key' => 'Value', ])); } }
ποΈ Architecture
src/
βββ Attribute/ # #[Profile], #[IgnoreProfile], #[Redact]
βββ Collector/ # 7 intelligence collectors
β βββ CacheCollector.php # Hit/miss, hot keys, per-store
β βββ EventCollector.php # Timeline, storms, slow listeners
β βββ ExceptionCollector.php # Traces, chains, fingerprinting
β βββ MiddlewareCollector.php # Per-middleware timing, bottlenecks
β βββ QueryCollector.php # N+1, duplicates, SQL fingerprinting
β βββ RequestCollector.php # Headers, IP hash, fingerprint
β βββ RouteCollector.php # Pattern, controller, OpenAPI
βββ Command/ # 5 CLI commands (devtools:*)
βββ Contract/ # Stable interfaces
βββ Exception/ # Package exceptions
βββ Middleware/ # PSR-15 DevToolsMiddleware
βββ Profiler/ # Core engine
β βββ Profile.php # 10 property hooks
β βββ ProfileContext.php # Request lifecycle context
β βββ Profiler.php # Orchestrator with 3 hooks
βββ Redaction/ # Key-based recursive masking
βββ Sampler/ # Rate-based + deterministic sampling
βββ Storage/ # File, Memory, Null drivers
βββ Toolbar/ # Self-contained debug toolbar
β βββ Panel/ # 5 built-in panels
β βββ AbstractPanel.php # Rendering helpers
β βββ PanelInterface.php # Panel contract
β βββ ToolbarInjector.php # HTML response injection
β βββ ToolbarRenderer.php # Self-contained HTML/CSS/JS
βββ DevToolsServiceProvider.php # Config-driven bootstrap
40 source files Β· 5,099 lines Β· 22 test files Β· 184 tests Β· 572 assertions
π Competitive Comparison
| Feature | Symfony Profiler | Laravel Telescope | ML DevTools |
|---|---|---|---|
| PHP Version | 8.2+ | 8.3+ | 8.4+ |
| Property Hooks | 0 | 0 | 26 |
| N+1 Detection | β | β | β Automatic |
| Event Storm Detection | β | β | β |
| Cache Hot Key Analysis | β | β | β |
| Deterministic Sampling | β | β | β Hash-based |
| Request Fingerprinting | β | β | β xxh3 |
| Priority Collectors | β | β | β With wrap |
| Partial Value Redaction | β | β | β |
| Self-Contained Toolbar | β Requires Webpack | β Requires Tailwind | β Embedded |
| Zero-Overhead Disabled | β οΈ Partial | β | β Full |
| Asymmetric Visibility | β | β | β private(set) |
| MLC Config Format | β | β | β Native |
π§ͺ Testing
# Run all tests composer test # With testdox output ./vendor/bin/phpunit --testdox # Static analysis composer analyse
Test Suite Coverage
| Area | Test Files | Tests | Assertions |
|---|---|---|---|
| Collectors (7) | 7 | 62 | 178 |
| Profiler Core | 3 | 28 | 102 |
| Storage (3) | 3 | 28 | 72 |
| Toolbar & Panels | 3 | 38 | 108 |
| Service Provider | 1 | 12 | 34 |
| Middleware | 1 | 4 | 12 |
| Attributes | 1 | 9 | 18 |
| Exceptions | 1 | 3 | 6 |
| Redaction | 1 | 10 | 24 |
| Sampler | 1 | 6 | 18 |
| Total | 22 | 184 | 572 |
πΊοΈ Roadmap
| Phase | Focus | Status |
|---|---|---|
| 0 | Contracts & Skeleton | β Complete |
| 1 | MVP Profiler & CLI | β Complete |
| 2 | Debug Toolbar & Local DX | β Complete |
| 3 | Query, Cache & Event Intelligence | β Complete |
| 4 | Container, Entity & Config Inspectors | π Next |
| 5 | OpenAPI, Security & Validation Reports | π Planned |
| 6 | Production Diagnostics & APM | π Planned |
| 7 | MonkeysCloud SaaS Integration | π Planned |
π€ Contributing
- Fork & clone the repository
- Install dependencies:
composer install - Run the test suite:
composer test - Run static analysis:
composer analyse - Submit a PR against
main
Please ensure all new collectors include corresponding unit tests and property hooks where applicable.
π License
MIT β Β© 2026 MonkeysCloud Team
Built with π by MonkeysCloud