JustAnalytics for Laravel

Step-by-step guide to add analytics, error tracking, and APM to your Laravel app

JustAnalytics for Laravel

Add distributed tracing, error tracking, structured logging, and infrastructure metrics to your Laravel application.

Time to data: 3-5 minutes

Prerequisites#


Install the SDK

composer require justanalyticsapp/justanalytics-php

Configure environment variables

The SDK auto-discovers in Laravel via the service provider. Add your credentials to .env:

JUSTANALYTICS_SITE_ID=site_abc123
JUSTANALYTICS_API_KEY=ja_sk_your_api_key_here
JUSTANALYTICS_SERVICE_NAME=laravel-app

Publish the configuration (optional)

Publish the config file to customize settings:

php artisan vendor:publish --tag=justanalytics-config

This creates config/justanalytics.php:

// config/justanalytics.php
return [
    'site_id' => env('JUSTANALYTICS_SITE_ID'),
    'api_key' => env('JUSTANALYTICS_API_KEY'),
    'service_name' => env('JUSTANALYTICS_SERVICE_NAME', 'laravel-app'),
    'environment' => env('APP_ENV', 'production'),
    'release' => env('APP_VERSION'),
    'enabled' => env('JUSTANALYTICS_ENABLED', true),
];

Automatic request tracing

The auto-registered middleware creates server spans for every HTTP request. No code changes needed:

// routes/api.php — these are automatically traced
Route::get('/users/{id}', function (int $id) {
    // Traced as "GET /users/{id}"
    return User::findOrFail($id);
});

Route::post('/orders', function (Request $request) {
    $order = Order::create($request->validated());
    return response()->json($order, 201);
});

Add error tracking

Add JustAnalytics to your exception handler for comprehensive error capture:

// app/Exceptions/Handler.php (Laravel 10)
use JustAnalytics\JustAnalytics;

public function register(): void
{
    $this->reportable(function (\Throwable $e) {
        JustAnalytics::captureException($e, [
            'tags' => ['source' => 'exception_handler'],
        ]);
    });
}

For Laravel 11+ with the new exception handling:

// bootstrap/app.php
use JustAnalytics\JustAnalytics;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->reportable(function (\Throwable $e) {
        JustAnalytics::captureException($e);
    });
})

Verify Your Setup

Make a request to any route (e.g., curl http://localhost:8000/api/users/1), then check the Traces tab.

Open Dashboard

Advanced Features#

Custom spans#

use JustAnalytics\JustAnalytics;

Route::get('/reports/{id}', function (string $id) {
    return JustAnalytics::startSpan('generate-report', 'internal', [], function ($span) use ($id) {
        $span->setAttribute('report.id', $id);

        $data = JustAnalytics::startSpan('query-data', 'db', [], function () use ($id) {
            return Report::with('items')->findOrFail($id);
        });

        $pdf = JustAnalytics::startSpan('render-pdf', 'internal', [], function () use ($data) {
            return PDF::loadView('reports.show', compact('data'));
        });

        return $pdf->download("report-{$id}.pdf");
    });
});

User identification#

// In a middleware or after authentication
use JustAnalytics\JustAnalytics;

class IdentifyUser
{
    public function handle(Request $request, Closure $next)
    {
        if ($user = $request->user()) {
            JustAnalytics::setUser([
                'id' => (string) $user->id,
                'email' => $user->email,
            ]);
        }
        return $next($request);
    }
}

Capture messages#

JustAnalytics::captureMessage('User exceeded rate limit', 'warning');
JustAnalytics::captureMessage('Deployment complete', 'info');

Guzzle auto-instrumentation#

Trace outgoing HTTP requests with Guzzle:

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use JustAnalytics\Integrations\Guzzle\GuzzleMiddleware;

$stack = HandlerStack::create();
$stack->push(GuzzleMiddleware::create(), 'justanalytics');

$client = new Client(['handler' => $stack]);

// All requests are now traced with W3C traceparent headers
$response = $client->get('https://api.stripe.com/v1/charges');

Queue job tracing#

use JustAnalytics\JustAnalytics;

class ProcessOrder implements ShouldQueue
{
    public function handle(): void
    {
        JustAnalytics::startSpan('process-order', 'queue', [], function ($span) {
            $span->setAttribute('order.id', $this->order->id);
            $this->order->process();
        });
    }

    public function failed(\Throwable $exception): void
    {
        JustAnalytics::captureException($exception, [
            'tags' => ['job' => 'ProcessOrder', 'order_id' => $this->order->id],
        ]);
    }
}

Custom metrics#

JustAnalytics::recordMetric('custom.queue_size', Queue::size('default'));
JustAnalytics::recordMetric('custom.cache_hit_rate', $hitRate, ['store' => 'redis']);

Flush on termination#

Laravel automatically flushes the SDK on request termination via the service provider. For queue workers, use the flush() method in job lifecycle hooks.

Environment variables#

| Variable | Description | Required | |----------|-------------|----------| | JUSTANALYTICS_SITE_ID | Your site ID from the dashboard | Yes | | JUSTANALYTICS_API_KEY | API key (starts with ja_sk_) | Yes | | JUSTANALYTICS_SERVICE_NAME | Service name for traces | No | | JUSTANALYTICS_ENABLED | Enable/disable SDK (default: true) | No | | APP_ENV | Used as the environment tag | No |