Search by

greenhat-services / magpie-laravel

greenhat

Magpie error tracking and performance monitoring for Laravel.

Package info

github.com/Greenhat-Services/magpie-laravel

pkg:composer/greenhat-services/magpie-laravel

Statistics

Installs: 13

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.1 2026-10-20 06:11 UTC

This package is not auto-updated.

Last update: 2026-10-20 09:23:31 UTC


README

Error tracking and performance monitoring for Laravel apps, reporting to Magpie. Supports Laravel 11, 12 and 13 on PHP 8.2+.

Install

composer require greenhat-services/magpie-laravel

Add the DSN from App settings > DSN keys to .env:

MAGPIE_LARAVEL_DSN=https://<key>@ingest.magpie.example.com/<project>
MAGPIE_TRACES_SAMPLE_RATE=0.2

Report exceptions in bootstrap/app.php:

use Magpie\Laravel\Integration;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(web: __DIR__.'/../routes/web.php')
    ->withExceptions(function (Exceptions $exceptions) {
        Integration::handles($exceptions);
    })->create();

Verify the setup:

php artisan magpie:test

The command fails with the reason when Magpie rejects the event (unknown key, unreachable host, oversized payload).

Publish the config if you need to change defaults: php artisan vendor:publish --tag=magpie-config.

What is captured

  • Exceptions reported by Laravel, with stack traces, source context, in-app frames, chained causes, request details and (opt-in) the signed-in user. Framework noise such as 404s, validation and authentication failures is ignored by default (ignore_exceptions).
  • Breadcrumbs: log messages, SQL queries, outgoing HTTP client calls, cache hits and misses, queue jobs and console commands leading up to an error.
  • Performance: sampled requests, jobs and commands become transactions with a span per SQL query and per Laravel HTTP client call (MAGPIE_TRACES_SAMPLE_RATE). An error raised during a transaction links to it.
  • Distributed tracing: traced requests send a magpie-trace header on outgoing HTTP client calls and embed it in queued job payloads, so a job or another Magpie-instrumented service continues the same trace. Incoming magpie-trace headers are honoured.
  • Release: MAGPIE_RELEASE, or the git commit of the checkout when a .git directory is present.
  • Queue workers, Octane and commands: events are flushed after every job, request or command, and each unit of work starts with a clean scope. Jobs run on the sync driver stay inside the surrounding request as a span.

What is never sent

  • Request bodies, cookies and session data.
  • Credentials in headers: Authorization, Proxy-Authorization, HTTP Basic auth (php-auth-*), CSRF tokens, and any header whose name contains auth, token, secret, session, api-key, signature, credential or password.
  • Client IP addresses (X-Forwarded-For, X-Real-IP, CF-Connecting-IP, Forwarded and similar) unless send_default_pii is on.
  • Values of query, referer, outgoing-URL and log-context keys that look like credentials: password, secret, token, api_key, credential, session, csrf, otp, cvv, ssn, signature, private_key, auth, code, pin, card_number and similar are replaced with [Filtered].
  • SQL bindings, unless breadcrumbs.sql_bindings is on.

Source lines around each frame are sent unless context_lines is 0. Use before_send to scrub anything specific to your application.

Usage

use Magpie\Laravel\Facades\Magpie;
use Magpie\Laravel\Scope;

Magpie::captureException($e);
Magpie::captureMessage('Nightly sync is late', 'warning');

Magpie::addBreadcrumb(['category' => 'billing', 'message' => 'Invoice created']);

Magpie::configureScope(fn (Scope $scope) => $scope
    ->setTag('tenant', 'acme')
    ->setUser(['id' => $user->id])
    ->setExtra('order', $order->id));

Magpie::withScope(function (Scope $scope) {
    $scope->setTag('import', 'bookings');
    Magpie::captureMessage('Row skipped');   // tag applies here only
});

Magpie::traceHeader();   // "magpie-trace" value for a hand-made outgoing request, or null

Log channel

Send log records to Magpie by adding a channel to config/logging.php:

'magpie' => [
    'driver' => 'custom',
    'via' => Magpie\Laravel\Logs\LogChannel::class,
    'level' => 'error',
],

then use it alone (LOG_CHANNEL=magpie) or in a stack. Records with an exception context become exceptions; others become messages.

Queued delivery

By default events are sent over HTTP when the request, job or command finishes, with a 3 second timeout. To keep that off the web process:

MAGPIE_QUEUE=true
MAGPIE_QUEUE_CONNECTION=redis   # optional, defaults to your queue default
MAGPIE_QUEUE_NAME=monitoring    # optional

Each event becomes a Magpie\Laravel\Jobs\SendPayload job. The SDK never traces or reports its own job, and falls back to inline delivery when the queue cannot accept it.

Configuration

Option Env Default
dsn MAGPIE_LARAVEL_DSN none Empty or invalid disables the SDK.
environment MAGPIE_ENVIRONMENT APP_ENV
release MAGPIE_RELEASE git commit Version string; falls back to the checkout's commit.
sample_rate MAGPIE_SAMPLE_RATE 1.0 Fraction of errors sent.
traces_sample_rate MAGPIE_TRACES_SAMPLE_RATE none Fraction of requests, jobs and commands traced.
send_default_pii MAGPIE_SEND_DEFAULT_PII false Attach the user, client IP headers and REMOTE_ADDR.
ignore_exceptions framework noise Classes and interfaces never reported, subclasses included.
ignore_transactions GET /up, HEAD /up Transaction names never traced.
context_lines 5 Source lines around each frame; 0 sends no source.
timeout MAGPIE_TIMEOUT 3 Seconds to wait for Magpie.
queue.* MAGPIE_QUEUE, MAGPIE_QUEUE_CONNECTION, MAGPIE_QUEUE_NAME off Deliver from a queue worker.
before_send null callable(array $event, array $hint): ?array; return null to drop. Use an invokable class or [Class::class, 'method'] so config:cache works.
trace_propagation_targets ['*'] Hosts (exact or parent domain) that receive the magpie-trace header.
breadcrumbs.* on logs, sql_queries, sql_bindings (off), http_client, cache, queue_info, command_info, max (100).
limits.* 8192, 100, 100 string_length in bytes, spans per transaction, frames per exception.

Wire protocol

This is the contract between the SDK and a Magpie server.

  • POST {scheme}://{host}/api/{project}/events for errors and .../transactions for traces, taken from the DSN https://<key>@<host>/<project>.
  • Header X-Magpie-Auth: Magpie magpie_version=1, magpie_key=<key>, magpie_client=magpie-laravel/<version>.
  • JSON body, gzip-compressed (Content-Encoding: gzip) above 4 KB. Bodies are kept under 1 MB: breadcrumbs, spans, extra and source context are dropped to fit, and an event that is still too large is not sent.
  • Errors carry event_id, timestamp, platform, level, environment, release, server_name, exception.values[] (type, value, mechanism, stacktrace.frames[] oldest first), message, tags, extra, user, request, contexts, breadcrumbs, transaction and sdk. An error raised inside a trace also carries contexts.trace.trace_id and span_id.
  • Transactions carry type: "transaction", transaction, start_timestamp, timestamp, contexts.trace (trace_id, span_id, parent_span_id when continuing a trace, op, status, http.status_code, dropped_spans when the span cap was hit) and spans[] (span_id, parent_span_id, op, description, start_timestamp, timestamp, data).
  • Distributed tracing header magpie-trace: <32 hex trace id>-<16 hex span id>-<0|1 sampled>. The same value travels in queued job payloads under magpie_trace.

Delivery never throws. Magpie::flush() returns false when any payload was rejected.

Testing

composer install
composer check        # Pint, PHPStan and PHPUnit
vendor/bin/phpunit

Bind your own Magpie\Laravel\Transport\Transport in the container to replace HTTP delivery, as the test suite does. See CONTRIBUTING.md for conventions.