# API Reference This guide provides reference documentation for Laravel ChronoTrace's programmatic API. ## Service Classes ### TraceRecorder The main service for recording traces programmatically. ```php use Grazulex\LaravelChronotrace\Services\TraceRecorder; class TraceRecorder { /** * Start recording a new trace */ public function startTrace(string $traceId = null): string /** * Stop recording the current trace */ public function stopTrace(string $traceId): bool /** * Add a custom event to the current trace */ public function addEvent(string $type, array $data): void /** * Force record the current request regardless of mode */ public function forceRecord(): void /** * Check if currently recording */ public function isRecording(): bool } ``` #### Usage Examples ```php // Manually start/stop trace recording $recorder = app(TraceRecorder::class); $traceId = $recorder->startTrace(); // ... perform operations ... $recorder->stopTrace($traceId); // Add custom events $recorder->addEvent('custom', [ 'user_action' => 'button_click', 'element_id' => 'submit-form', 'timestamp' => now(), ]); // Force recording for important operations $recorder->forceRecord(); ``` --- ### TraceAnalyzer Service for analyzing and querying trace data. ```php use Grazulex\LaravelChronotrace\Services\TraceAnalyzer; class TraceAnalyzer { /** * Get trace by ID */ public function getTrace(string $traceId): ?array /** * Search traces by criteria */ public function searchTraces(array $criteria): Collection /** * Analyze performance patterns */ public function analyzePerformance(string $traceId): array /** * Find N+1 query patterns */ public function detectNPlusOne(string $traceId): array /** * Get trace statistics */ public function getTraceStats(string $traceId): array } ``` #### Usage Examples ```php $analyzer = app(TraceAnalyzer::class); // Get specific trace $trace = $analyzer->getTrace('chronotrace_20240806_143015_abc123'); // Search for error traces $errorTraces = $analyzer->searchTraces([ 'status' => ['>=', 400], 'created_at' => ['>=', now()->subHours(24)], ]); // Analyze performance $performance = $analyzer->analyzePerformance($traceId); echo "Total duration: {$performance['total_duration']}ms"; echo "Database time: {$performance['database_time']}ms"; // Detect N+1 queries $nPlusOneIssues = $analyzer->detectNPlusOne($traceId); foreach ($nPlusOneIssues as $issue) { echo "Found N+1 pattern: {$issue['pattern']}"; } ``` --- ### StorageManager Manages trace storage operations across different backends. ```php use Grazulex\LaravelChronotrace\Services\StorageManager; class StorageManager { /** * Store a trace */ public function store(string $traceId, array $data): bool /** * Retrieve a trace */ public function retrieve(string $traceId): ?array /** * Delete a trace */ public function delete(string $traceId): bool /** * Check if trace exists */ public function exists(string $traceId): bool /** * Get storage statistics */ public function getStats(): array /** * Purge old traces */ public function purge(int $days = null): int } ``` #### Usage Examples ```php $storage = app(StorageManager::class); // Store trace data $storage->store($traceId, $traceData); // Check if trace exists if ($storage->exists($traceId)) { $trace = $storage->retrieve($traceId); } // Get storage statistics $stats = $storage->getStats(); echo "Total traces: {$stats['total_traces']}"; echo "Storage used: {$stats['storage_used']}"; // Clean up old traces $deleted = $storage->purge(30); // Delete traces older than 30 days echo "Deleted {$deleted} traces"; ``` --- ## Facades ### ChronoTrace Facade Convenient facade for common operations. ```php use Grazulex\LaravelChronotrace\Facades\ChronoTrace; // Enable/disable recording ChronoTrace::enable(); ChronoTrace::disable(); // Check recording status $isEnabled = ChronoTrace::isEnabled(); $isRecording = ChronoTrace::isRecording(); // Force record current request ChronoTrace::forceRecord(); // Add custom event ChronoTrace::addEvent('user_action', [ 'action' => 'login', 'user_id' => 123, ]); // Get recent traces $traces = ChronoTrace::getRecentTraces(10); // Search traces $errorTraces = ChronoTrace::searchTraces([ 'status' => ['>=', 400], 'route' => 'api/*', ]); ``` --- ## Event System ### Custom Events ChronoTrace dispatches events during trace lifecycle: ```php // Event classes use Grazulex\LaravelChronotrace\Events\TraceStarted; use Grazulex\LaravelChronotrace\Events\TraceCompleted; use Grazulex\LaravelChronotrace\Events\TraceStored; use Grazulex\LaravelChronotrace\Events\TracePurged; // Listen to events Event::listen(TraceStarted::class, function (TraceStarted $event) { Log::info('Trace started', ['trace_id' => $event->traceId]); }); Event::listen(TraceCompleted::class, function (TraceCompleted $event) { // Analyze completed trace if ($event->duration > 5000) { // Alert on slow requests $this->sendSlowRequestAlert($event->traceId); } }); ``` ### Custom Event Capture Add your own events to traces: ```php // In your application code use Grazulex\LaravelChronotrace\Facades\ChronoTrace; class UserController extends Controller { public function store(Request $request) { // Capture custom application event ChronoTrace::addEvent('user_registration_start', [ 'email' => $request->email, 'source' => $request->source, 'timestamp' => now(), ]); $user = User::create($request->validated()); ChronoTrace::addEvent('user_registration_complete', [ 'user_id' => $user->id, 'duration_ms' => $this->getProcessingTime(), ]); return response()->json($user, 201); } } ``` --- ## Middleware Integration ### Custom Middleware Create middleware that integrates with ChronoTrace: ```php use Grazulex\LaravelChronotrace\Facades\ChronoTrace; class CustomTracingMiddleware { public function handle($request, Closure $next) { // Add request context ChronoTrace::addEvent('middleware_start', [ 'middleware' => static::class, 'route' => $request->route()?->getName(), 'user_id' => $request->user()?->id, ]); $response = $next($request); // Add response context ChronoTrace::addEvent('middleware_end', [ 'middleware' => static::class, 'status_code' => $response->getStatusCode(), ]); return $response; } } ``` ### Conditional Recording Enable recording based on custom logic: ```php class ConditionalTracingMiddleware { public function handle($request, Closure $next) { // Enable tracing for specific conditions if ($this->shouldTrace($request)) { ChronoTrace::forceRecord(); } return $next($request); } private function shouldTrace($request): bool { // Custom logic for when to trace return $request->hasHeader('X-Debug-Trace') || $request->user()?->hasRole('developer') || $request->is('api/critical/*'); } } ``` --- ## Configuration API ### Runtime Configuration Modify ChronoTrace configuration at runtime: ```php use Grazulex\LaravelChronotrace\Services\ConfigManager; $config = app(ConfigManager::class); // Enable specific event types $config->enableEventCapture('cache'); $config->disableEventCapture('events'); // Change recording mode temporarily $config->setMode('always', duration: '5m'); // Update sample rate $config->setSampleRate(0.1); // 10% // Add custom scrubbing patterns $config->addScrubPattern('/api_key_\w+/', 'api_key_[REDACTED]'); ``` --- ## Query Builder ### Trace Query Builder Fluent interface for querying traces: ```php use Grazulex\LaravelChronotrace\Query\TraceQuery; $query = new TraceQuery(); // Find slow API requests from last 24 hours $slowApiTraces = $query ->where('route', 'like', 'api/%') ->where('duration', '>', 1000) ->where('created_at', '>=', now()->subDay()) ->orderBy('duration', 'desc') ->limit(10) ->get(); // Find error traces with specific HTTP status codes $errorTraces = $query ->whereIn('status', [500, 502, 503, 504]) ->where('created_at', '>=', now()->subHours(6)) ->with(['database_events', 'http_events']) ->get(); // Get traces by user $userTraces = $query ->where('user_id', 123) ->where('created_at', '>=', now()->subWeek()) ->groupBy('route') ->selectRaw('route, COUNT(*) as count, AVG(duration) as avg_duration') ->get(); ``` --- ## Performance Metrics ### Metrics Collection Collect performance metrics from traces: ```php use Grazulex\LaravelChronotrace\Metrics\MetricsCollector; $collector = app(MetricsCollector::class); // Collect metrics for specific time period $metrics = $collector->collect([ 'from' => now()->subHours(24), 'to' => now(), 'routes' => ['api/*'], ]); // Available metrics echo "Request count: {$metrics['request_count']}"; echo "Average duration: {$metrics['average_duration']}ms"; echo "Error rate: {$metrics['error_rate']}%"; echo "95th percentile: {$metrics['p95_duration']}ms"; // Database metrics echo "Query count: {$metrics['database']['query_count']}"; echo "Slow queries: {$metrics['database']['slow_queries']}"; // Cache metrics echo "Cache hit rate: {$metrics['cache']['hit_rate']}%"; echo "Cache operations: {$metrics['cache']['operations']}"; ``` --- ## Testing Integration ### Testing Helpers Utilities for testing with ChronoTrace: ```php use Grazulex\LaravelChronotrace\Testing\ChronoTraceAssertions; class FeatureTest extends TestCase { use ChronoTraceAssertions; public function test_api_performance() { // Enable tracing for test $this->enableChronoTrace(); // Make request $response = $this->postJson('/api/users', $userData); // Assert performance $this->assertTraceDuration(lessThan: 1000); // < 1 second $this->assertDatabaseQueriesLessThan(10); $this->assertNoNPlusOneQueries(); $this->assertCacheHitRate(greaterThan: 80); // > 80% // Get trace data for further analysis $trace = $this->getLastTrace(); $this->assertArrayHasKey('database_events', $trace); } public function test_error_handling() { $this->enableChronoTrace(); // Trigger error $response = $this->postJson('/api/invalid-endpoint'); // Assert error was captured $this->assertTraceStatus(404); $this->assertTraceHasError(); $trace = $this->getLastTrace(); $this->assertEquals(404, $trace['response']['status']); } } ``` --- ## Custom Storage Drivers ### Implementing Storage Driver Create custom storage backends: ```php use Grazulex\LaravelChronotrace\Contracts\StorageDriver; class CustomStorageDriver implements StorageDriver { public function store(string $traceId, array $data): bool { // Implement storage logic $serialized = json_encode($data); return $this->writeToBackend($traceId, $serialized); } public function retrieve(string $traceId): ?array { $data = $this->readFromBackend($traceId); return $data ? json_decode($data, true) : null; } public function delete(string $traceId): bool { return $this->deleteFromBackend($traceId); } public function exists(string $traceId): bool { return $this->checkBackend($traceId); } public function list(array $filters = []): array { return $this->listFromBackend($filters); } public function purge(int $olderThanDays): int { return $this->purgeFromBackend($olderThanDays); } } ``` ### Registering Custom Driver ```php // In AppServiceProvider use Grazulex\LaravelChronotrace\Services\StorageManager; public function boot() { $this->app->afterResolving(StorageManager::class, function (StorageManager $manager) { $manager->extend('custom', function ($app, $config) { return new CustomStorageDriver($config); }); }); } ``` --- ## Error Handling ### Exception Classes ChronoTrace specific exceptions: ```php use Grazulex\LaravelChronotrace\Exceptions\ChronoTraceException; use Grazulex\LaravelChronotrace\Exceptions\StorageException; use Grazulex\LaravelChronotrace\Exceptions\TraceNotFoundException; use Grazulex\LaravelChronotrace\Exceptions\ConfigurationException; try { $trace = ChronoTrace::getTrace($traceId); } catch (TraceNotFoundException $e) { Log::warning('Trace not found', ['trace_id' => $traceId]); } catch (StorageException $e) { Log::error('Storage error', ['error' => $e->getMessage()]); } catch (ChronoTraceException $e) { Log::error('ChronoTrace error', ['error' => $e->getMessage()]); } ``` --- ## Advanced Usage ### Custom Event Processors Process events before storage: ```php use Grazulex\LaravelChronotrace\Contracts\EventProcessor; class CustomEventProcessor implements EventProcessor { public function process(array $event): array { // Add custom processing logic if ($event['type'] === 'database') { $event['query_hash'] = md5($event['sql']); $event['query_complexity'] = $this->calculateComplexity($event['sql']); } return $event; } } // Register processor ChronoTrace::addEventProcessor(new CustomEventProcessor()); ``` ### Trace Correlation Correlate traces across requests: ```php class TraceCorrelationService { public function createCorrelationGroup(array $traceIds): string { $groupId = Str::uuid(); foreach ($traceIds as $traceId) { $this->addTraceToGroup($traceId, $groupId); } return $groupId; } public function getCorrelatedTraces(string $groupId): Collection { return ChronoTrace::searchTraces([ 'correlation_group' => $groupId, ]); } } ``` --- ## 📚 Related Documentation - **[Basic Usage](Basic-Usage.md)** - Learn the fundamentals - **[Configuration](Configuration.md)** - Configure ChronoTrace - **[Examples](Example-Database-Debugging.md)** - Real-world examples - **[Testing](Testing-Internal-Operations.md)** - Testing with ChronoTrace --- **Use the programmatic API for advanced integrations!** The API provides full control over trace recording, analysis, and storage operations.