/sentry-symfony

Symfony integration for Sentry

Primary LanguagePHPApache License 2.0Apache-2.0

sentry-symfony

Symfony integration for Sentry.

Stable release Unstable release

Build status Scrutinizer Coverage Status

Benefits

Use sentry-symfony for:

  • A fast sentry setup
  • Access to the sentry.client through the container
  • Automatic wiring in your app. Each event has the following things added automatically to it:
    • user
    • Symfony environment
    • app path
    • hostname
    • excluded paths (cache and vendor)

Installation

Step 1: Download the Bundle

Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:

$ composer require sentry/sentry-symfony

This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.

Step 2: Enable the Bundle

Then, enable the bundle by adding it to the list of registered bundles in the app/AppKernel.php file of your project:

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
        );

        if (in_array($this->getEnvironment(), ['staging', 'prod'], true)) {
            $bundles[] = new Sentry\SentryBundle\SentryBundle();
        }
        // ...
    }

    // ...
}

Note that, with this snippet of code, the bundle will be enabled only for the staging and prod environment; adjust it to your needs. It's discouraged to enable this bundle in the test environment, because the Sentry client will change the error handler, which is already used by other packages like Symfony's deprecation handler (see #46 and #95).

Step 3: Configure the SDK

Add your Sentry DSN value of your project to app/config/config.yml. Leaving this value empty will effectively disable Sentry reporting.

sentry:
    dsn: "https://public:secret@sentry.example.com/1"

Maintained versions

  • 2.x is actively maintained on the master branch, but it requires Symfony 3+ and PHP 7.1+;
  • 1.x is still supported to allow Symfony 2 and PHP 5.6/7.0; it may receive backports of features from the master branch, but it's not guaranteed
  • 0.8.x is no longer maintained, with the 0.8.8 release containing the latest new features; it may only receive security fixes in the future.

Configuration

The following options can be configured via app/config/config.yml.

Skip some exceptions

sentry:
    skip_capture:
        - 'Symfony\Component\HttpKernel\Exception\HttpExceptionInterface'

Listeners' priority

You can change the priority of the 3 default listeners of this bundle with the listener_priorities key of your config. The default value is 0, and here are the 3 possible sub-keys:

listener_priorities:
    request: 0
    kernel_exception: 0
    console_exception: 0

... respectively for the onKernelRequest, onKernelException and onConsoleException events.

Options

In the following section you will find some of the available options you can configure, listed alphabetically. All available options and a more detailed description of each can be found here, in the Sentry documentation.

app_path

The base path to your application. Used to trim prefixes and mark frames of the stack trace as part of your application.

sentry:
    options:
        app_path: "/path/to/myapp"

environment

The environment your code is running in (e.g. production).

sentry:
    options:
        environment: "%kernel.environment%"

error types

Define which error types should be reported.

sentry:
    options:
        error_types: E_ALL & ~E_DEPRECATED & ~E_NOTICE

exception_listener

This is used to replace the default exception listener that this bundle uses. The value must be a FQCN of a class implementing the SentryExceptionListenerInterface interface. See Create a Custom ExceptionListener for more details.

sentry:
    exception_listener: AppBundle\EventListener\MySentryExceptionListener

prefixes

A list of prefixes to strip from filenames. Often these would be vendor/include paths.

sentry:
    options:
        prefixes:
            - /usr/lib/include

release

The version of your application. Often this is the Git SHA hash of the commit.

sentry:
    options:
        release: "beeee2a06521a60e646bbb8fe38702e61e4929bf"

tags

Define tags for the logged errors.

sentry:
    options:
        tags:
            tag1: tagvalue
            tag2: tagvalue

Deprecated configuration options

In previous releases of this bundle, up to 0.8.2, some of the previous options where set outside of the options level of the configuration file. Those still work but are deprecated, and they will be dropped in the stable 1.x release, so you are advised to abandon them; to provide forward compatibility, they can still be used alongside the standard syntax, but values must match. This is a list of those options:

sentry:
    app_path: ~
    environment: ~
    error_types: ~
    excluded_app_paths: ~
    prefixes: ~
    release: ~

Customization

It is possible to customize the configuration of the user context, as well as modify the client immediately before an exception is captured by wiring up an event subscriber to the events that are emitted by the default configured ExceptionListener (alternatively, you can also just define your own custom exception listener).

Create a custom ExceptionListener

You can always replace the default ExceptionListener with your own custom listener. To do this, assign a different class to the exception_listener property in your Sentry configuration, e.g.:

sentry:
    exception_listener: AppBundle\EventListener\MySentryExceptionListener

... and then define the custom ExceptionListener that implements the SentryExceptionListenerInterface, e.g.:

// src/AppBundle/EventSubscriber/MySentryEventListener.php
namespace AppBundle\EventSubscriber;

use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class MySentryExceptionListener implements SentryExceptionListenerInterface
{
    // ...

    public function __construct(TokenStorageInterface $tokenStorage = null, AuthorizationCheckerInterface $authorizationChecker = null, \Raven_Client $client = null, array $skipCapture, EventDispatcherInterface $dispatcher = null)
    {
        // ...
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        // ...
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // ...
    }

    public function onConsoleException(ConsoleExceptionEvent $event)
    {
        // ...
    }
}

As a side note, while the above demonstrates a custom exception listener that does not extend anything you could choose to extend the default ExceptionListener and only override the functionality that you want to.

Add an EventSubscriber for Sentry Events

Create a new class, e.g. MySentryEventSubscriber:

// src/AppBundle/EventSubscriber/MySentryEventListener.php
namespace AppBundle\EventSubscriber;

use Sentry\SentryBundle\Event\SentryUserContextEvent;
use Sentry\SentryBundle\SentrySymfonyEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MySentryEventSubscriber implements EventSubscriberInterface
{
    /** @var \Raven_Client */
    protected $client;

    public function __construct(\Raven_Client $client)
    {
        $this->client = $client;
    }

    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return array(
            SentrySymfonyEvents::PRE_CAPTURE => 'onPreCapture',
            SentrySymfonyEvents::SET_USER_CONTEXT => 'onSetUserContext'
        );
    }

    public function onSetUserContext(SentryUserContextEvent $event)
    {
        // ...
    }

    public function onPreCapture(Event $event)
    {
        if ($event instanceof GetResponseForExceptionEvent) {
            // ...
        }
        elseif ($event instanceof ConsoleExceptionEvent) {
            // ...
        }
    }
}

In the example above, if you subscribe to the PRE_CAPTURE event you may get an event object that caters more toward a response to a web request (e.g. GetResponseForExceptionEvent) or one for actions taken at the command line (e.g. ConsoleExceptionEvent). Depending on what and how the code was invoked, and whether or not you need to distinguish between these events during pre-capture, it might be best to test for the type of the event (as is demonstrated above) before you do any relevant processing of the object.

To configure the above add the following configuration to your services definitions:

app.my_sentry_event_subscriber:
    class: AppBundle\EventSubscriber\MySentryEventSubscriber
    arguments:
      - '@sentry.client'
    tags:
      - { name: kernel.event_subscriber }