Flare by Spatie
    • Error Tracking
    • Performance Monitoring
    • Logs Coming soon
  • Pricing
  • Docs
  • Insights
  • Changelog
  • Back to Flare ⌘↵ Shortcut: Command or Control Enter
  • Sign in
  • Try Flare for free
  • Error Tracking
  • Performance Monitoring
  • Logs Coming soon
  • Pricing
  • Docs
  • Insights
  • Changelog
    • Back to Flare ⌘↵ Shortcut: Command or Control Enter
    • Try Flare for free
    • Sign in
Flare Flare Laravel Laravel PHP PHP JavaScript JavaScript React React Vue Vue Protocol Protocol
  • General
  • Installation
  • Integrating into a framework
  • Attribute providers
  • Application lifecycle
  • Censoring collected data
  • Ignoring collected data
  • Flare daemon
  • Errors
  • Adding custom context
  • Customise error report
  • Customising error grouping
  • Handling errors
  • Linking to errors
  • Reporting errors
  • Logs
  • Introduction
  • Levels
  • With errors
  • Performance
  • Introduction
  • Sampling
  • Limits
  • Modify spans and events
  • Data Collection
  • Application info
  • Cache events
  • Console commands
  • Database transactions
  • Dumps
  • Errors when tracing
  • Exception context
  • External http requests
  • Filesystem operations
  • Git information
  • Glows
  • Identifying users
  • Jobs and queues
  • Queries
  • Redis commands
  • Requests
  • Routing
  • Server info
  • Spans
  • Stacktrace arguments
  • Views
  • Older Packages
  • Flare Client PHP V2
  • Flare Client PHP V1

Attribute providers

Recorders use attribute providers to turn framework-specific objects (a Symfony request, a Console input, a queued job) into the attributes that Flare records on a span. Going through a provider instead of accepting framework objects directly lets flare-client-php stay framework-agnostic while still shipping ready-to-use helpers for the common stacks.

You hand a provider to a recorder when you start or end a span, and the recorder calls the provider to get the attributes it needs. For the common cases, recorders expose recordStartFrom* and recordEndFrom* helpers that build the matching provider for you. When you work with a framework or object that Flare does not ship a provider for, you write your own.

The base contract is small. Every provider implements AttributesProvider:

namespace Spatie\FlareClient\Contracts;

interface AttributesProvider
{
    /** @return array<string, mixed> */
    public function toArray(): array;
}

Each recorder accepts a more specific provider contract that adds methods for the data the recorder needs.

Contract Used by Methods beyond toArray()
RequestAttributesProvider RequestRecorder url(), path(), method()
ResponseAttributesProvider RequestRecorder (on recordEnd) toArray() only
RouteAttributesProvider RoutingRecorder, RequestRecorder route()
CommandAttributesProvider CommandRecorder command(), commandClass()
JobAttributesProvider JobRecorder, QueueRecorder jobName(), jobClass()
UserAttributesProvider (abstract base class) RequestRecorder (on recordEnd) id(), fullName(), email(), attributes()

Built-in providers

flare-client-php ships with implementations for plain PHP and for Symfony's HttpFoundation / Console components. They live under Spatie\FlareClient\AttributesProviders\:

Provider Builds attributes from
PhpRequestAttributesProvider PHP superglobals ($_SERVER, $_GET, etc.)
SymfonyRequestAttributesProvider A Symfony HttpFoundation\Request
PhpResponseAttributesProvider A defined status code, body size, and header set
SymfonyResponseAttributesProvider A Symfony HttpFoundation\Response
PhpRouteAttributesProvider A route pattern, method, and handler name
PhpCommandAttributesProvider A command name, class, and arguments array
SymfonyInputCommandAttributesProvider A Symfony Console InputInterface
PhpJobAttributesProvider A job name and class
UserAttributesProvider (abstract) The user object you pass to its constructor
EmptyUserAttributesProvider A no-op for cases where there is no user
GitAttributesProvider The git working copy at applicationPath

Each recorder also exposes recordStartFrom* and recordEndFrom* helpers that build the matching provider from common framework objects. For example:

$flare->request()->recordStartFromSymfonyRequest($request);
$flare->command()->recordStartFromSymfonyInput(
    'my:command', 
    $input, 
    MyCommand::class
);
$flare->job()->recordStartFromJob(
    'SendWelcomeEmail', 
    SendWelcomeEmail::class
);

If you do not have one of those framework objects, build a provider yourself and pass it to recordStart() or recordEnd().

Writing a custom attributes provider

Implement the contract that matches the recorder you want to feed. As an example, here is a minimal request provider for a hypothetical framework that exposes the request through a MyHttpRequest object:

use Spatie\FlareClient\Contracts\RequestAttributesProvider;

class MyHttpRequestAttributesProvider implements RequestAttributesProvider
{
    public function __construct(protected MyHttpRequest $request)
    {
    }

    public function url(): string
    {
        return $this->request->fullUrl();
    }

    public function path(): ?string
    {
        return $this->request->path();
    }

    public function method(): string
    {
        return $this->request->method();
    }

    public function toArray(): array
    {
        return [
            'url.full' => $this->url(),
            'url.path' => $this->path(),
            'http.request.method' => $this->method(),
            'http.request.headers' => $this->request->headers(),
        ];
    }
}

Pass it to the recorder:

$flare->request()->recordStart(new MyHttpRequestAttributesProvider($request));

The same approach applies to every recorder. Implement the contract, return the attribute keys documented in the protocol events, and the recorder will merge them into the span.

Describing the entry point handler

Some recorders also need to know who the entry point handler is (the controller, command class, or job class). When the same provider can describe both the framework object and the handler, implement the optional EntryPointHandlerProvider interface alongside the main contract:

use Spatie\FlareClient\Contracts\EntryPointHandlerProvider;
use Spatie\FlareClient\Contracts\RouteAttributesProvider;

class MyRouteAttributesProvider implements RouteAttributesProvider, EntryPointHandlerProvider
{
    public function __construct(protected MyRoute $route)
    {
    }

    public function route(): ?string
    {
        return $this->route->pattern();
    }

    public function toArray(): array
    {
        return ['http.route' => $this->route()];
    }

    public function entryPointHandlerIdentifier(): ?string
    {
        return "{$this->route->method()} {$this->route->pattern()}";
    }

    public function entryPointHandlerName(): ?string
    {
        return $this->route->controller();
    }

    public function entryPointHandlerType(): ?string
    {
        return 'my_framework_controller';
    }
}

The recorders detect the interface and call setHandler() on the entry point automatically. See Entry points for the attribute schema and the recommended handler.type values.

Integrating into a framework Application lifecycle
  • On this page
  • Built-in providers
  • Writing a custom attributes provider
  • Describing the entry point handler

Catch errors and fix slowdowns with Flare, the full-stack application monitoring platform for Laravel, PHP & JavaScript.

  • Platform
  • Error Tracking
  • Performance Monitoring
  • Pricing
  • Support
  • Resources
  • Insights
  • Newsletter
  • Changelog
  • Documentation
  • Affiliate program
  • uptime status badge Service status
  • Terms of use
  • DPA
  • Privacy & cookie Policy
Made in by
Flare