🎼 Laravel Integration Guide
Learn how to instrument your Laravel applications with TraceKit APM for zero-config distributed tracing and performance monitoring.
Zero-Config Automatic Tracing!
TraceKit Laravel package automatically traces HTTP requests, database queries, queue jobs, cache operations, and more with minimal setup. Just install and configure your API key!
Prerequisites
- • PHP 8.1 or higher
- • Laravel 10.x, 11.x, or 12.x
- • An active TraceKit account
- • A generated API key from the API Keys page
🔍 What Gets Traced Automatically?
With TraceKit Laravel package installed, these operations are traced automatically with zero configuration:
| Component | What's Captured | Auto-Traced? |
|---|---|---|
| HTTP Requests | Route, method, status, duration | ✓ Yes |
| Database Queries | SQL, bindings, duration, connection | ✓ Yes |
| Queue Jobs | Job class, queue name, status, payload | ✓ Yes |
| Exceptions | Type, message, stack trace, context | ✓ Yes |
| Custom Spans | Manual instrumentation (optional) | Manual |
📦 Installation
Install the TraceKit Laravel package via Composer:
composer require tracekit/laravel-apmPackage Autodiscovery
The service provider is automatically registered via Laravel's package discovery. No need to manually register it!
⚙️ Configuration
1. Publish Configuration (Optional)
If you want to customize settings, publish the configuration file:
php artisan vendor:publish --provider="TraceKit\Laravel\TracekitServiceProvider"This creates config/tracekit.php where you can customize settings.
2. Add API Key to .env
Add your TraceKit API key to your .env file:
# TraceKit APM Configuration
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
TRACEKIT_ENDPOINT=https://app.tracekit.dev/v1/traces
TRACEKIT_SERVICE_NAME=my-laravel-app
TRACEKIT_ENABLED=trueImportant Security Note
Never commit your API key to version control. Keep it in your .env file and use environment-specific values.
🚀 Laravel 12+ Middleware Setup
For Laravel 12+, middleware registration has changed. The package attempts automatic registration, but if needed, manually add the middleware to bootstrap/app.php:
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
use TraceKit\Laravel\Middleware\TracekitMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
TracekitMiddleware::class,
]);
$middleware->api(append: [
TracekitMiddleware::class,
]);
})
// ... rest of your configuration
->create();Laravel 10 & 11
For Laravel 10 and 11, the middleware is registered automatically via the service provider. No manual configuration needed!
⚡ Configuration Options
Available configuration options in config/tracekit.php:
<?php
return [
// Enable/disable tracing
'enabled' => env('TRACEKIT_ENABLED', env('APP_ENV') !== 'local'),
// Your TraceKit API key
'api_key' => env('TRACEKIT_API_KEY', ''),
// OTLP endpoint for sending traces
'endpoint' => env('TRACEKIT_ENDPOINT', 'https://app.tracekit.dev/v1/traces'),
// Service name as it appears in TraceKit
'service_name' => env('TRACEKIT_SERVICE_NAME', env('APP_NAME', 'laravel-app')),
// Sample rate (0.0 to 1.0)
'sample_rate' => env('TRACEKIT_SAMPLE_RATE', 1.0),
// Enable/disable specific features
'features' => [
'http' => env('TRACEKIT_HTTP_ENABLED', true),
'database' => env('TRACEKIT_DATABASE_ENABLED', true),
'cache' => env('TRACEKIT_CACHE_ENABLED', true),
'queue' => env('TRACEKIT_QUEUE_ENABLED', true),
'redis' => env('TRACEKIT_REDIS_ENABLED', true),
],
// Routes to ignore
'ignored_routes' => [
'/health',
'/up',
'/_healthz',
],
// Slow query threshold (ms)
'slow_query_threshold' => env('TRACEKIT_SLOW_QUERY_MS', 100),
// Include query bindings in traces
'include_query_bindings' => env('TRACEKIT_INCLUDE_BINDINGS', true),
];📸 Code Monitoring (Live Debugging)
Production-Safe Live Debugging
Capture variable state, stack traces, and request context at any point in your code without redeployment. Perfect for debugging production issues!
→ Full Code Monitoring DocumentationSetup
To enable code monitoring for live debugging, add these settings to your .env:
# Enable code monitoring
TRACEKIT_CODE_MONITORING_ENABLED=true
# Polling interval (seconds)
# - 1-5: Development (fast updates, higher load)
# - 10-30: Production (recommended)
# - 60+: Low traffic/minimal overhead
TRACEKIT_CODE_MONITORING_POLL_INTERVAL=30
# Variable inspection depth (1-10)
TRACEKIT_CODE_MONITORING_MAX_DEPTH=3
# String truncation length
TRACEKIT_CODE_MONITORING_MAX_STRING=1000Usage: Add Debug Points
Use the tracekit_snapshot() helper to capture variable state:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class OrderController extends Controller
{
public function processOrder(Request $request)
{
$userId = $request->user()->id;
$cartTotal = $request->input('cart_total');
// Capture variable state at checkout start
tracekit_snapshot('checkout-start', [
'user_id' => $userId,
'cart_total' => $cartTotal,
'items_count' => $request->input('items', [])->count(),
]);
try {
$order = $this->createOrder($request->all());
$payment = $this->processPayment($order);
// Capture successful payment state
tracekit_snapshot('payment-success', [
'order_id' => $order->id,
'payment_id' => $payment->id,
'amount' => $payment->amount,
]);
return response()->json(['order' => $order], 201);
} catch (\Exception $e) {
// Exception automatically captured with stack trace!
throw $e;
}
}
}Features
Auto-Registration
Breakpoints automatically created on first call
Variable Capture
Deep inspection of arrays, objects, and primitives
Stack Traces
Full call stack with file and line numbers
Request Context
HTTP method, route, headers, and query params
Exception Handling
Exceptions are automatically captured with full stack traces for code discovery:
<?php
// Exceptions are AUTOMATICALLY captured with full stack traces!
// No additional code needed - just throw exceptions as normal
Route::get('/payment/{id}', function ($id) {
$payment = Payment::find($id);
if (!$payment) {
// This exception will be captured with:
// - Full stack trace
// - File and line number
// - Request context (route, headers, params)
// - All for code discovery!
throw new \Exception('Payment not found');
}
return $payment;
});
// You can also manually capture at exception points
Route::post('/process', function (Request $request) {
try {
$result = $this->riskyOperation($request->all());
} catch (\Exception $e) {
// Optionally add a snapshot before re-throwing
tracekit_snapshot('operation-failed', [
'error' => $e->getMessage(),
'input' => $request->all(),
]);
throw $e; // Auto-captured!
}
});Production Safe
Snapshots are sampled and have minimal performance impact. Capture rates and conditions can be controlled via the TraceKit dashboard.
🚀 Local UI (Development Mode)
Debug your Laravel application locally without creating an account. TraceKit Local UI runs on your machine at http://localhost:9999 and automatically receives traces when you run your app in local environment.
Automatic Detection
The Laravel SDK automatically detects when Local UI is running on port 9999 and sends traces to both Local UI and cloud (if you have an API key configured).
Quick Start
1. Install the Local UI:
npm install -g @tracekit/local-ui2. Start the Local UI:
tracekit-local3. Run your app (Laravel automatically uses APP_ENV=local):
php artisan serve4. Open your browser:
http://localhost:9999Features
Auto-Detection
SDK checks for Local UI at localhost:9999 on startup
Real-Time Updates
See traces instantly with WebSocket live updates
Development Only
Only activates when APP_ENV=local
Works Offline
No internet connection required - everything runs locally
Benefits
- See your first trace in under 60 seconds
- Debug locally without switching to the cloud dashboard
- Stay in your flow - everything runs on your machine
- Works completely offline
- Perfect for development and demos
Troubleshooting
If traces aren't appearing in Local UI, check:
- Local UI is running (
curl http://localhost:9999/api/health) APP_ENV=localis set in .env file- SDK version is v1.1.1 or higher
- Check logs for "🔍 Local UI detected" message
🌐 Service Discovery
TraceKit automatically instruments outgoing HTTP calls made with Laravel's HTTP client to create service dependency graphs. When your service makes an HTTP request to another service, TraceKit creates CLIENT spans and injects trace context headers.
Usage with Laravel HTTP Client
Just use Laravel's HTTP client as normal - everything is traced automatically:
<?php
use Illuminate\Support\Facades\Http;
// All HTTP calls are automatically traced!
Route::post('/checkout', function (Request $request) {
// This creates a CLIENT span for the payment-service call
$paymentResponse = Http::post('http://payment-service/charge', [
'amount' => $request->input('amount'),
'user_id' => auth()->id(),
]);
// This creates another CLIENT span for the inventory-service call
$inventoryResponse = Http::post('http://inventory-service/reserve', [
'item_id' => $request->input('item_id'),
]);
return response()->json([
'status' => 'success',
'payment_id' => $paymentResponse['payment_id'],
]);
});Custom Service Name Mappings
For local development or when service names can't be inferred from hostnames, configure service name mappings in config/tracekit.php:
// config/tracekit.php
return [
// ... other config
// Map localhost URLs to actual service names
'service_name_mappings' => [
'localhost:8082' => 'payment-service',
'localhost:8083' => 'user-service',
'localhost:8084' => 'inventory-service',
],
];
// Now requests to localhost:8082 will show as "payment-service" in your service graph
// Http::get('http://localhost:8082/charge');
// -> Creates CLIENT span with peer.service = "payment-service"Service Name Detection
TraceKit intelligently extracts service names from URLs:
| URL | Extracted Service Name |
|---|---|
| http://payment-service:3000 | payment-service |
| http://payment.internal | payment |
| http://payment.svc.cluster.local | payment |
| https://api.example.com | api.example.com |
Viewing Service Dependencies
Visit your TraceKit dashboard to see the Service Map - a visual graph showing which services call which, with health metrics and latency data.
🔧 Manual Instrumentation (Optional)
For custom business logic or specific operations you want to measure, you can manually create spans:
<?php
use TraceKit\Laravel\TracekitClient;
class OrderController extends Controller
{
public function processOrder(Request $request, TracekitClient $tracekit)
{
// Create a custom span
$span = $tracekit->startSpan('process-order', null, [
'order.id' => $request->input('order_id'),
'user.id' => auth()->id(),
]);
try {
$order = $this->createOrder($request->all());
$this->processPayment($order);
$this->sendConfirmation($order);
$tracekit->endSpan($span, [
'order.total' => $order->total,
'order.items_count' => $order->items()->count(),
]);
return response()->json($order, 201);
} catch (\Exception $e) {
$tracekit->recordException($span, $e);
$tracekit->endSpan($span, [], 'ERROR');
throw $e;
}
}
}✅ Complete Example
Here's a complete example showing automatic and manual tracing:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use TraceKit\Laravel\TracekitClient;
class UserController extends Controller
{
// HTTP requests are automatically traced!
public function index()
{
// Database queries are automatically traced!
$users = User::where('active', true)->get();
return response()->json($users);
}
// You can add custom spans for specific operations
public function processUserData(Request $request, TracekitClient $tracekit)
{
// Start custom span
$span = $tracekit->startSpan('process-user-data', null, [
'user.count' => $request->input('user_ids')->count(),
]);
try {
// Your business logic here
$results = [];
foreach ($request->input('user_ids') as $userId) {
$user = User::find($userId);
$results[] = $this->processUser($user);
}
$tracekit->endSpan($span, [
'results.count' => count($results),
]);
return response()->json($results);
} catch (\Exception $e) {
$tracekit->recordException($span, $e);
$tracekit->endSpan($span, [], 'ERROR');
throw $e;
}
}
private function processUser($user)
{
// Database queries here are also automatically traced!
$user->last_processed_at = now();
$user->save();
return $user;
}
}You're all set!
Your Laravel application is now sending traces to TraceKit. Visit the Dashboard to see your traces.
Custom Metrics
Track custom metrics like request counts, queue sizes, and response times using the TraceKit metrics API.
Counter
Track monotonically increasing values (requests, events):
use TraceKit\Laravel\Facades\Tracekit;
// Create a counter with optional tags
$counter = Tracekit::counter('http.requests.total', [
'service' => 'api',
'method' => 'GET',
]);
// Increment by 1
$counter->inc();
// Add a specific value
$counter->add(5);Gauge
Track values that can go up or down (queue size, connections):
// Create a gauge
$gauge = Tracekit::gauge('http.connections.active');
// Set to specific value
$gauge->set(42);
// Increment/decrement
$gauge->inc();
$gauge->dec();Histogram
Track value distributions (latencies, sizes):
// Create a histogram with tags
$histogram = Tracekit::histogram('http.request.duration', [
'unit' => 'ms',
]);
// Record values
$histogram->record(45.2);
$histogram->record(123.5);🔧 Troubleshooting
Traces Not Appearing?
- Verify your API key is correct in
.env - Check
TRACEKIT_ENABLED=truein your.env - Clear config cache:
php artisan config:clear - Check Laravel logs in
storage/logs/laravel.log - Verify TraceKit endpoint is accessible
Package Not Auto-Discovered?
Run package discovery manually:
php artisan package:discover php artisan config:clear🚀 Next Steps
- • Explore your traces on the Traces page to identify slow queries and performance bottlenecks
- • Configure alert rules to get notified when issues occur
- • Add custom spans for specific business logic you want to measure
- • Adjust sampling rates for high-traffic applications
Pro Tip
Enable query bindings to see actual SQL values in traces. Just set TRACEKIT_INCLUDE_BINDINGS=true in your .env file. Perfect for debugging!