-
-
Notifications
You must be signed in to change notification settings - Fork 1
API Reference
This guide provides reference documentation for Laravel ChronoTrace's programmatic API.
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
}// 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();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
}$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']}";
}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
}$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";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/*',
]);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);
}
});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);
}
}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;
}
}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/*');
}
}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]');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();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']}";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']);
}
}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);
}
}// 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);
});
});
}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()]);
}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());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,
]);
}
}- Basic Usage - Learn the fundamentals
- Configuration - Configure ChronoTrace
- Examples - Real-world examples
- Testing - Testing with ChronoTrace
Use the programmatic API for advanced integrations! The API provides full control over trace recording, analysis, and storage operations.
- Getting Started - Install and configure ChronoTrace
- Examples - Real-world debugging scenarios
- Production Guide - Deploy safely in production
- Troubleshooting - Solve common issues
| Section | Page | Description |
|---|---|---|
| π Basics | Your First Trace | Step-by-step beginner guide |
| ποΈ Config | Recording Modes | Choose when to record traces |
| π‘οΈ Security | Security & PII | Protect sensitive data |
| π§ Tools | Commands | Complete command reference |
- π¬ GitHub Discussions - Community support
- π Report Issues - Bug reports & feature requests
- π§ Contact - Direct support
- π‘ Feature Requests - Suggest improvements
ChronoTrace helps Laravel developers debug applications faster with intelligent request tracing.
Made with β€οΈ by Grazulex β’ Documentation updated August 2024