microsoft/application-insights
Send PHP telemetry (events, traces, exceptions, metrics) to Azure Application Insights for monitoring and diagnostics. Install via Composer and use the SDK to report app performance and availability data to the Azure Portal. Community SDK; not Microsoft-supported.
Installation:
composer require microsoft/application-insights
Add autoloader:
require_once __DIR__ . '/vendor/autoload.php';
Initialize Client:
$telemetryClient = new \ApplicationInsights\Telemetry_Client();
$telemetryClient->getContext()->setInstrumentationKey(env('APP_INSIGHTS_KEY'));
First Use Case:
Track an exception in a Laravel exception handler (app/Exceptions/Handler.php):
public function report(Throwable $exception)
{
$telemetryClient = new \ApplicationInsights\Telemetry_Client();
$telemetryClient->getContext()->setInstrumentationKey(env('APP_INSIGHTS_KEY'));
$telemetryClient->trackException($exception);
$telemetryClient->flush();
}
Middleware for Request Tracking: Create a middleware to track HTTP requests:
namespace App\Http\Middleware;
use Closure;
use ApplicationInsights\Telemetry_Client;
class TrackRequests
{
public function handle($request, Closure $next)
{
$telemetryClient = new Telemetry_Client();
$telemetryClient->getContext()->setInstrumentationKey(env('APP_INSIGHTS_KEY'));
$startTime = microtime(true);
$response = $next($request);
$duration = (microtime(true) - $startTime) * 1000; // ms
$telemetryClient->trackRequest(
$request->method() . ' ' . $request->path(),
$request->fullUrl(),
time(),
$duration,
$response->getStatusCode(),
$response->getStatusCode() < 400
);
$telemetryClient->flush();
return $response;
}
}
Register in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\TrackRequests::class,
];
Service Container Binding: Bind the client to Laravel’s service container for dependency injection:
// In a ServiceProvider (e.g., AppServiceProvider)
$this->app->singleton(\ApplicationInsights\Telemetry_Client::class, function ($app) {
$client = new \ApplicationInsights\Telemetry_Client();
$client->getContext()->setInstrumentationKey(env('APP_INSIGHTS_KEY'));
return $client;
});
Use in controllers:
public function __construct(private Telemetry_Client $telemetry)
{
}
public function index()
{
$this->telemetry->trackEvent('Homepage Loaded');
$this->telemetry->flush();
}
Database Query Tracking: Use Laravel’s query observer to track slow queries:
use Illuminate\Database\Events\QueryExecuted;
use ApplicationInsights\Telemetry_Client;
Event::listen(QueryExecuted::class, function ($query) {
$telemetry = app(Telemetry_Client::class);
$duration = $query->time * 1000; // ms
if ($duration > 100) { // Log slow queries
$telemetry->trackDependency(
'DB Query',
'SQL',
$query->sql,
time(),
$duration,
true
);
$telemetry->flush();
}
});
Custom Metrics: Track business metrics (e.g., orders, signups):
$telemetry->trackMetric('orders_placed', $orderCount);
$telemetry->trackMetric('signup_conversion_rate', $conversionRate, \ApplicationInsights\Channel\Contracts\Data_Point_Type::Aggregation);
$telemetry->flush();
Context Propagation: Pass context (e.g., user ID, session) across requests:
$telemetry->getContext()->getUserContext()->setId(auth()->id());
$telemetry->getContext()->getSessionContext()->setId(session()->getId());
Instrumentation Key:
.env and validate it in a service provider:
if (empty(env('APP_INSIGHTS_KEY'))) {
throw new \RuntimeException('Application Insights key is not configured.');
}
Flush Behavior:
flush(). Unflushed telemetry may be lost if the script ends abruptly (e.g., CLI commands, long-running tasks).flush() explicitly or use a shutdown function:
register_shutdown_function(function () {
$telemetry = app(Telemetry_Client::class);
$telemetry->flush();
});
Performance Overhead:
// Bad: Inside a loop
foreach ($items as $item) {
$telemetry->trackEvent('Processed Item', ['id' => $item->id]);
$telemetry->flush(); // Expensive!
}
// Good: Batch and flush once
foreach ($items as $item) {
$telemetry->trackEvent('Processed Item', ['id' => $item->id]);
}
$telemetry->flush();
Deprecated Features:
Dependency_Type enum and async argument in trackDependency are removed (v0.4.4+).// Old (deprecated)
$telemetry->trackDependency('name', \ApplicationInsights\Dependency_Type::SQL, 'query', time(), 100, true, false);
// New
$telemetry->trackDependency('name', "SQL", 'query', time(), 100, true);
Gzip Compression:
setSendGzipped(true)) may not always reduce payload size for small telemetry batches.$telemetry->getChannel()->setSendGzipped(false); // Disable if not needed
Context Overrides:
setInstrumentationKey) are global per Telemetry_Client instance. Reusing a client with different keys will override settings.if ($telemetry->getContext()->getInstrumentationKey() !== env('APP_INSIGHTS_KEY')) {
throw new \RuntimeException('Instrumentation key mismatch!');
}
Verify Telemetry: Use the Application Insights Live Metrics Stream to confirm data is being received.
Log Telemetry Locally: Temporarily log telemetry to Laravel’s log for debugging:
$telemetry->trackEvent('Debug Event', ['data' => $debugData]);
\Log::debug('Telemetry sent:', ['event' => 'Debug Event', 'data' => $debugData]);
Check HTTP Errors: Enable Guzzle’s debug mode to inspect HTTP requests:
$telemetry->getChannel()->setDebug(true);
Validate Schema: Ensure custom properties/metrics conform to Application Insights’ schema. Invalid fields may be silently dropped.
Custom Telemetry Types: Extend the client to support custom telemetry (e.g., Laravel-specific events):
class LaravelTelemetryClient extends \ApplicationInsights\Telemetry_Client
{
public function trackJob(JobExecution $job, float $duration)
{
$this->trackEvent('Job Executed', [
'job' => $job->name,
'queue' => $job->queue,
'status' => $job->status(),
], ['duration_ms' => $duration]);
}
}
Middleware for Global Tracking: Create a base middleware to initialize telemetry for all requests:
namespace App\Http\Middleware;
use Closure;
use ApplicationInsights\Telemetry_Client;
class InitializeTelemetry
{
public function handle($request, Closure $next)
{
if (!app()->bound(Telemetry_Client::class)) {
How can I help you explore Laravel packages today?