https://github.com/last9/php-7.4-laravel-otel
Manual OpenTelemetry Instrumentation for PHP 7.4 and Laravel app
https://github.com/last9/php-7.4-laravel-otel
laravel opentelemetry php traces
Last synced: 3 months ago
JSON representation
Manual OpenTelemetry Instrumentation for PHP 7.4 and Laravel app
- Host: GitHub
- URL: https://github.com/last9/php-7.4-laravel-otel
- Owner: last9
- Created: 2025-07-16T19:44:02.000Z (3 months ago)
- Default Branch: master
- Last Pushed: 2025-07-23T19:03:47.000Z (3 months ago)
- Last Synced: 2025-07-23T21:30:45.325Z (3 months ago)
- Topics: laravel, opentelemetry, php, traces
- Language: PHP
- Homepage: https://last9.io
- Size: 23.4 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Complete OpenTelemetry Setup Guide for Your Laravel App
## 📁 Files to Copy
Copy these 3 essential files from this project to your Laravel app:
```
bootstrap/otel.php # Core OpenTelemetry SDK setup
app/Http/Middleware/OpenTelemetryMiddleware.php # HTTP request/response tracing
app/Providers/AppServiceProvider.php # Database tracing (copy the boot() method)
```## 🔧 Integration Steps
### 1. **Update `public/index.php`**
Add this line after the autoloader, before Laravel bootstrap:```php
// Initialize OpenTelemetry SDK
require_once __DIR__.'/../bootstrap/otel.php';
```### 2. **Register HTTP Middleware**
In `app/Http/Kernel.php`, add to the `$middleware` array:```php
protected $middleware = [
// ... existing middleware
\App\Http\Middleware\OpenTelemetryMiddleware::class,
];
```### 3. **Add Database Tracing**
In your existing `AppServiceProvider.php` `boot()` method, add this code:```php
public function boot()
{
$tracer = $GLOBALS['otel_tracer'] ?? null;
\Illuminate\Support\Facades\DB::listen(function ($query) use ($tracer) {
if (!$tracer) {
return;
}
try {
$connectionName = $query->connectionName ?? config('database.default');
$connection = config("database.connections.{$connectionName}");
$span = $tracer->spanBuilder('db.query')
->setSpanKind(\OpenTelemetry\API\Trace\SpanKind::KIND_CLIENT)
->setAttribute(\OpenTelemetry\SemConv\TraceAttributes::DB_SYSTEM, $connection['driver'] ?? 'unknown')
->setAttribute(\OpenTelemetry\SemConv\TraceAttributes::DB_NAME, $connection['database'] ?? $connectionName)
->setAttribute('server.address', $connection['host'] ?? 'localhost')
->setAttribute('server.port', $connection['port'] ?? 3306)
->setAttribute('db.statement', $query->sql)
->setAttribute('db.query.duration_ms', $query->time)
->startSpan();
$span->setStatus(\OpenTelemetry\API\Trace\StatusCode::STATUS_OK);
$span->end();
} catch (\Throwable $e) {
// Silently fail
}
});
}
```### 4. **Environment Variables**
Add to your `.env` file:```env
OTEL_SERVICE_NAME=your-app-name
OTEL_SERVICE_VERSION=1.0.0
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://your-collector-endpoint/v1/traces
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic your-auth-token"
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```### 5. **Composer Dependencies**
Add to your `composer.json` and run `composer install`:```json
{
"require": {
"open-telemetry/sdk": "^1.0",
"open-telemetry/contrib-otlp": "^1.0",
"open-telemetry/sem-conv": "^1.0"
}
}
```## 🎯 What You'll Get
- ✅ **HTTP Request Spans** - All incoming requests traced automatically
- ✅ **Database Spans** - All Eloquent ORM and raw DB queries traced
- ✅ **External HTTP Call Tracing** - Use helper functions `traced_curl_exec()` and `traced_guzzle_request()`
- ✅ **Proper Span Relationships** - Database spans are children of HTTP request spans
- ✅ **Performance Optimized** - Zero regex parsing, minimal overhead## 🚀 Optional: External HTTP Calls
For tracing external HTTP calls, use these helper functions (included in `bootstrap/otel.php`):
```php
// Instead of curl_exec($ch)
$result = traced_curl_exec($ch);// Instead of $client->request($method, $url, $options)
$response = traced_guzzle_request($client, $method, $url, $options);
```## 🔍 Testing Your Setup
After integration, test that tracing is working:
### Quick Test Endpoints
You can add these test routes to verify everything is working:```php
// Test basic functionality
Route::get('/test-otel', function () {
// This will create HTTP span automatically via middleware
// Test database span
$users = \Illuminate\Support\Facades\DB::select('SELECT COUNT(*) as count FROM users');
// Test external HTTP call (if needed)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://httpbin.org/get');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = traced_curl_exec($ch);
curl_close($ch);
return response()->json([
'message' => 'OpenTelemetry test completed',
'user_count' => $users[0]->count ?? 0,
'external_call' => 'success'
]);
});
```### Verification Checklist
- [ ] HTTP request span appears in your tracing backend
- [ ] Database query spans appear as children of HTTP span
- [ ] External HTTP call spans appear (if using helper functions)
- [ ] All spans contain proper semantic attributes
- [ ] No application errors or performance degradation## 🐛 Troubleshooting
### Common Issues
1. **No spans appearing**
- Check environment variables are set correctly
- Verify collector endpoint is reachable
- Check Laravel logs for any errors2. **Database spans missing**
- Ensure `AppServiceProvider.php` boot method includes the DB::listen code
- Verify database queries are actually executing3. **HTTP spans missing**
- Confirm middleware is registered in `Kernel.php`
- Check middleware order (should be early in the stack)4. **Performance issues**
- This implementation is optimized for minimal overhead
- Monitor your application performance before/after
- Adjust batch processor settings in `bootstrap/otel.php` if needed## 📚 Additional Resources
- [OpenTelemetry PHP Documentation](https://opentelemetry.io/docs/php/)
- [OpenTelemetry Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/)
- [Laravel Service Providers](https://laravel.com/docs/providers)
- [Laravel Middleware](https://laravel.com/docs/middleware)---
That's it! Your Laravel app will now have comprehensive OpenTelemetry tracing with HTTP, database, and external call monitoring.