Skip to content

API Reference

Jean-Marc Strauven edited this page Aug 6, 2025 · 2 revisions

API Reference

This guide provides reference documentation for Laravel ChronoTrace's programmatic API.

Service Classes

TraceRecorder

The main service for recording traces programmatically.

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

// 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.

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

$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.

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

$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.

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:

// 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:

// 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:

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:

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:

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:

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:

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:

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:

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

// 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:

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:

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:

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


Use the programmatic API for advanced integrations! The API provides full control over trace recording, analysis, and storage operations.

Clone this wiki locally