Skip to content

Your First Trace

Jean-Marc Strauven edited this page Aug 6, 2025 · 1 revision

Your First Trace

A step-by-step walkthrough to capture, analyze, and understand your first ChronoTrace. Perfect for getting familiar with the basic workflow.


🎯 What You'll Learn

  • How to capture your first trace
  • How to analyze trace output
  • How to identify issues in traces
  • Basic filtering and analysis techniques

Prerequisites: ChronoTrace should be installed and configured.


πŸ“‹ Step 1: Verify Installation

First, let's make sure ChronoTrace is working correctly:

# Check if ChronoTrace is properly installed
php artisan chronotrace:diagnose

Expected output:

βœ… ChronoTrace Configuration
   Enabled: Yes
   Mode: record_on_error
   Storage: local (/path/to/storage/chronotrace)

βœ… Storage
   Writable: Yes
   Free Space: 15.2 GB

If you see any ❌ errors, check the Troubleshooting Guide.


🎬 Step 2: Enable Recording

For this tutorial, we'll use "always" mode to capture everything:

# Temporarily enable full recording (in .env)
CHRONOTRACE_MODE=always
CHRONOTRACE_ENABLED=true

# Clear config cache to apply changes
php artisan config:clear

πŸš€ Step 3: Generate a Test Request

Let's create a simple test request that we can trace. You have several options:

Option A: Use Built-in Test Command

# Generate a test trace with sample events
php artisan chronotrace:test-internal

Option B: Make a Real Request

# Make a request to your application
curl -X GET http://localhost:8000/

# Or make a POST request with data
curl -X POST http://localhost:8000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John Doe","email":"john@example.com"}'

Option C: Use Your Browser

Simply visit your application in a browser and navigate to any page.


πŸ“‹ Step 4: List Your Traces

Now let's see what traces were captured:

# List recent traces
php artisan chronotrace:list

You should see output like this:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Trace ID   β”‚ Timestamp           β”‚ Method β”‚ Status   β”‚ Route                   β”‚ Duration β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ abc123...  β”‚ 2024-08-06 14:30:15 β”‚ GET    β”‚ 200      β”‚ /                       β”‚ 89ms     β”‚
β”‚ def456...  β”‚ 2024-08-06 14:28:42 β”‚ POST   β”‚ 201      β”‚ api/users               β”‚ 156ms    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Found 2 traces.

Understanding the output:

  • Trace ID: Unique identifier for this trace
  • Timestamp: When the request was made
  • Method: HTTP method (GET, POST, PUT, DELETE)
  • Status: HTTP response code
  • Route: The route that was accessed
  • Duration: How long the request took

πŸ” Step 5: Replay Your First Trace

Now let's examine a trace in detail. Copy a Trace ID from the list and replay it:

# Replace 'abc123...' with your actual Trace ID
php artisan chronotrace:replay abc123def456789

πŸ“Š Understanding Trace Output

Request Information

The trace starts with basic request information:

β”Œβ”€ REQUEST INFORMATION ────────────────────────────────────────┐
β”‚ Trace ID: abc123def456789                                    β”‚
β”‚ Method: GET /                                                β”‚
β”‚ Status: 200 OK                                               β”‚
β”‚ Duration: 89ms                                               β”‚
β”‚ Memory: 8.2MB                                                β”‚
β”‚ Timestamp: 2024-08-06 14:30:15 UTC                         β”‚
β”‚ User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)      β”‚
β”‚ IP Address: 127.0.0.1                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key information:

  • Duration: Total request processing time
  • Memory: Peak memory usage during request
  • Status: HTTP response code (200 = success)

Event Timeline

Next, you'll see events organized by type and time:

Database Events

β”Œβ”€ DATABASE EVENTS (3 queries, 12ms total) ───────────────────┐
β”‚ [+0ms] SELECT * FROM users WHERE email = ? ['john@example.com'] (4ms)
β”‚        Connection: mysql, Rows: 1
β”‚ 
β”‚ [+15ms] SELECT * FROM user_profiles WHERE user_id = ? [123] (3ms)
β”‚         Connection: mysql, Rows: 1
β”‚ 
β”‚ [+45ms] UPDATE users SET last_login = ? WHERE id = ? ['2024-08-06 14:30:15', 123] (5ms)
β”‚         Connection: mysql, Affected: 1
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Understanding database events:

  • [+0ms]: Time offset from request start
  • SQL Query: The actual query executed
  • Bindings: Parameter values (in brackets)
  • Duration: Time this query took
  • Metadata: Connection, rows returned/affected

Cache Events

β”Œβ”€ CACHE EVENTS (2 operations) ───────────────────────────────┐
β”‚ [+25ms] GET user:123:profile (HIT) 
β”‚         Store: redis, TTL: 3600s
β”‚ 
β”‚ [+67ms] SET user:123:last_activity (TTL: 3600s)
β”‚         Store: redis, Size: 45 bytes
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Understanding cache events:

  • GET/SET/FORGET: Cache operation type
  • HIT/MISS: Whether cache lookup succeeded
  • TTL: Time-to-live in seconds
  • Size: Data size for SET operations

HTTP Events

β”Œβ”€ HTTP EVENTS (1 request) ────────────────────────────────────┐
β”‚ [+78ms] POST https://api.example.com/webhook (45ms)
β”‚         Status: 200 OK
β”‚         Request Size: 234 bytes
β”‚         Response Size: 89 bytes
β”‚         Headers: Content-Type: application/json
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Understanding HTTP events:

  • URL: External API called
  • Duration: Time the external request took
  • Status: Response code from external API
  • Sizes: Request and response payload sizes

🎯 Step 6: Practice with Filtering

Let's focus on specific types of events:

View Only Database Events

php artisan chronotrace:replay abc123def456789 --filter=database

This shows only SQL queries, making it easier to identify database performance issues.

View Only HTTP Events

php artisan chronotrace:replay abc123def456789 --filter=http

Perfect for debugging external API integration issues.

View Multiple Event Types

php artisan chronotrace:replay abc123def456789 --filter=database,http

Combines database and HTTP events while hiding cache operations.

View Only Slow Events

php artisan chronotrace:replay abc123def456789 --min-duration=10

Shows only events that took longer than 10ms.


πŸ› Step 7: Create an Error Trace

Let's intentionally create an error to see how ChronoTrace captures failures:

Option A: Make an Invalid Request

# Request a non-existent endpoint
curl -X GET http://localhost:8000/non-existent-page

Option B: Create a Controller with an Error

Create a test route that throws an exception:

// In routes/web.php
Route::get('/test-error', function () {
    throw new \Exception('This is a test error for ChronoTrace');
});

Then visit: http://localhost:8000/test-error

View the Error Trace

# List traces, look for 500 status
php artisan chronotrace:list --status=error

# Replay the error trace
php artisan chronotrace:replay error-trace-id

Error traces show:

  • Complete execution flow up to the error
  • The exact point where the error occurred
  • Stack trace and error message
  • All database queries before the failure
  • External API calls that might have caused issues

πŸ“ˆ Step 8: Performance Analysis

Let's create a slow request to practice performance analysis:

Create a Slow Endpoint

// In routes/web.php
Route::get('/test-slow', function () {
    // Simulate slow database query
    sleep(1);
    
    // Simulate external API call
    $response = Http::timeout(30)->get('https://httpbin.org/delay/2');
    
    return response()->json(['status' => 'completed']);
});

Generate and Analyze the Trace

# Make the slow request
curl -X GET http://localhost:8000/test-slow

# Find slow traces (>1000ms)
php artisan chronotrace:list --min-duration=1000

# Analyze the slow trace
php artisan chronotrace:replay slow-trace-id

Look for:

  • Long-running database queries
  • Slow external HTTP calls
  • Memory usage spikes
  • Overall request timeline

🧹 Step 9: Clean Up

After testing, let's clean up:

# Remove test traces
php artisan chronotrace:purge --days=0

# Reset to production-safe mode
CHRONOTRACE_MODE=record_on_error

# Clear config cache
php artisan config:clear

πŸŽ“ What You've Learned

Congratulations! You've successfully:

  • βœ… Captured traces using different methods
  • βœ… Listed and filtered traces by various criteria
  • βœ… Replayed traces to see detailed execution flow
  • βœ… Analyzed different event types (database, cache, HTTP)
  • βœ… Debugged errors with complete context
  • βœ… Identified performance issues in slow requests
  • βœ… Used filtering to focus on specific problems

πŸš€ Next Steps

Now that you understand the basics:

  1. Basic Usage - Learn more advanced workflows
  2. Event Capturing - Configure what events to capture
  3. Configuration - Customize ChronoTrace for your needs
  4. Commands - Explore all available commands

Production Usage

When you're ready for production:

# Set production-safe configuration
CHRONOTRACE_MODE=record_on_error
CHRONOTRACE_SAMPLE_RATE=0.001
CHRONOTRACE_ASYNC_STORAGE=true

Check the Production Monitoring guide for best practices.


πŸ’‘ Pro Tips

  1. Bookmark useful traces: Note trace IDs of important requests for future reference
  2. Use targeted recording: Focus on specific routes during debugging
  3. Regular cleanup: Set up automatic purging to manage storage
  4. Filter smartly: Use event filtering to reduce noise in complex traces
  5. Monitor performance: Watch for trends in request duration and memory usage

Ready for more advanced usage? Check out our example scenarios for real-world debugging techniques!

Clone this wiki locally