Giter VIP home page Giter VIP logo

cake-sentry's Introduction

CakePHP Sentry Plugin

CakePHP integration for Sentry.

Latest Stable Version Total Downloads Build Status codecov PHP Code Sniffer License

Requirements

  • PHP 7.2+ / PHP 8.0+
  • CakePHP 4.0+
  • and Sentry account

๐Ÿ’ก For CakePHP3.x, use 2.x branch.

Installation

With composer install.

composer require connehito/cake-sentry:^3.0

If you do not have the php-http/async-client-implementation package, you will need to install it together.
In that case, you will get a message like the following

Problem 1
- sentry/sentry[3.2.0, ... , 3.3.0] require php-http/async-client-implementation ^1.0 -> could not be found in any version, but the following packages provide it:

Then, you can use the following command to provide a package such as symfony/http-client.

composer require connehito/cake-sentry symfony/http-client

You can find the available packages on Packagist.

Usage

Set config files.

Write your sentry account info.

// in `config/app.php`
return [
  'Sentry' => [
    'dsn' => YOUR_SENTRY_DSN_HERE
  ]
];

Loading plugin.

In Application.php

public function bootstrap()
{
    parent::bootstrap();

    $this->addPlugin(\Connehito\CakeSentry\Plugin::class);
}

Or use cake command.

bin/cake plugin load Connehito/CakeSentry

That's all! ๐ŸŽ‰

NOTE:
If the events(error/exception) don't be captured in Sentry, try changing the order in which the plugins are loaded.
It is recommended to load this plugin after running BaseApplication::bootstrap() and loading other plugins.

Advanced Usage

Ignore noisy exceptions

You can filter out exceptions that make a fuss and harder to determine the issues to address(like PageNotFoundException)
Set exceptions not to log in Error.skipLog.

ex)

// in `config/app.php`
'Error' => [
    'skipLog' => [
        NotFoundException::class,
        MissingRouteException::class,
        MissingControllerException::class,
    ],
]

ref: CakePHP Cookbook
https://book.cakephp.org/4/en/development/errors.html#error-exception-configuration

Set Options

All configure written in Configure::write('Sentry') will be passed to Sentry\init().
Please check Sentry's official document about configuration and about php-sdk's configuraion.

In addition to it, CakeSentry provides event hook to set dynamic values to options more easily if you need.
Client dispatch CakeSentry.Client.afterSetup event before sending error to sentry.
Subscribe the event with your logic.

ex)

use Cake\Event\Event;
use Cake\Event\EventListenerInterface;

class SentryOptionsContext implements EventListenerInterface
{
    public function implementedEvents(): array  
    {
        return [
            'CakeSentry.Client.afterSetup' => 'setServerContext',
        ];
    }

    public function setServerContext(Event $event): void
    {
        /** @var Client $subject */
        $subject = $event->getSubject();
        $options = $subject->getHub()->getClient()->getOptions();

        $options->setEnvironment('test_app');
        $options->setRelease('3.0.0@dev');
    }
}

And in config/bootstrap.php

\Cake\Event\EventManager::instance()->on(new SentryOptionsContext());

Send more context

Client dispatch CakeSentry.Client.beforeCapture event before sending error to sentry.
You can set context with EventListener.With facade sentryConfigureScope() etc, or with $event->getContext()->getHub() to access and set context.
In case you want to handle the information in server request, cake-sentry supports to get Request instance in implemented event via $event->getData('request').

See also the section about context in offical doc.

ex)

use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\Http\ServerRequest;
use Cake\Http\ServerRequestFactory;
use Sentry\State\Scope;

use function Sentry\configureScope as sentryConfigureScope;

class SentryErrorContext implements EventListenerInterface
{
    public function implementedEvents(): array
    {
        return [
            'CakeSentry.Client.beforeCapture' => 'setContext',
        ];
    }

    public function setContext(Event $event): void
    {
        if (PHP_SAPI !== 'cli') {
            /** @var ServerRequest $request */
            $request = $event->getData('request') ?? ServerRequestFactory::fromGlobals();
            $request->trustProxy = true;

            sentryConfigureScope(function (Scope $scope) use ($request, $event) {
                $scope->setTag('app_version',  $request->getHeaderLine('App-Version') ?: 1.0);
                $exception = $event->getData('exception');
                if ($exception) {
                    assert($exception instanceof \Exception);
                    $scope->setTag('status', $exception->getCode());
                }
                $scope->setUser(['ip_address' => $request->clientIp()]);
                $scope->setExtras([
                    'foo' => 'bar',
                    'request attributes' => $request->getAttributes(),
                ]);
            });
        }
    }
}

And in config/bootstrap.php

\Cake\Event\EventManager::instance()->on(new SentryErrorContext());

Collecting User feedback

In CakeSentry.Client.afterCapture event, you can get last event ID.
See also offcial doc.

ex)

class SentryErrorContext implements EventListenerInterface
{
    public function implementedEvents(): array
    {
        return [
            'CakeSentry.Client.afterCapture' => 'callbackAfterCapture',
        ];
    }

    public function callbackAfterCapture(Event $event): void
    {
        $lastEventId = $event->getData('lastEventId');
    }
}

Contributing

Pull requests and feedback are very welcome :)
on GitHub at https://github.com/connehito/cake-sentry .

License

The plugin is available as open source under the terms of the MIT License.

cake-sentry's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cake-sentry's Issues

Blocking all exceptions when enabling Sentry?

When I follow the instructions for cake-sentry 2.x (CakePHP 3.6+), I'm unable to get anything to work. The annoying part is that when I enable the plugin, no exceptions are logged whatsoever, it completely shuts off all loggin from CakePHP, and nothing is being send to Sentry.

Please help?

cakephp/cakephp 3.9.8
connehito/cake-sentry 2.0.0
sentry/sdk 2.2.0
sentry/sentry 2.5.2

How to enable only in production ?

I've seen that it's messing up my error config, because when I check if I'm in production or not and disable Cake Sentry in local environment, php is not displaying deprecated messages.

So how is the correct way to do it ?

with `cake plugin load`, the plugin seems not to work

#29 (comment)

After bin/cake plugin load Connehito/CakeSentry in CakePHP4, Applicaiton.php is modified like below.

@@ -39,6 +39,8 @@
      */
     public function bootstrap(): void
     {
+        $this->addPlugin('Connehito/CakeSentry');
+
         // Call parent to load bootstrap from files.
         parent::bootstrap();
 

This does not apply the Error/Logger settings correctly

CakePHP 4.4: Use of `BaseErrorHandler` and subclasses are deprecated.

Description

The file cake-sentry/config/bootstrap.php contains the following lines:

if ($isCli) {
    (new ConsoleErrorHandler(Configure::read('Error', [])))->register();
} else {
    (new ErrorHandler(Configure::read('Error', [])))->register();
}

These classes have been deprecated in CakePHP 4.4 and make my application crash with the following stack trace (simplified):

vendor/connehito/cake-sentry/src/Http/Client.php(144): Sentry\Severity::fromError('notice')
vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php(94): deprecationWarning('Use of `BaseErrorHandler` and subclasses are deprecated...')
vendor/connehito/cake-sentry/config/bootstrap.php(22): Cake\Error\BaseErrorHandler->register()

How to reproduce

  • Create a CakePHP application.
  • Add connehito/cake-sentry to the application.
  • Add the following snippet to Application.php:
public function bootstrap(): void
{
    ...
    if (Configure::read('Environment') != 'localhost') {
        $this->addPlugin('Connehito/CakeSentry');
        $debugLogConfig = Log::getConfig('debug');
        $debugLogConfig['className'] = SentryLog::class;
        Log::drop('debug');
        Log::setConfig('debug', $debugLogConfig);
        \Cake\Event\EventManager::instance()->on(new \App\Log\SentryOptionsContext());
    }
}
  • Open the application in a browser.

Breadcrumb Recursion

Hey! First of all, thanks you for the great plugin! Have been using it throughout a lot of my projects. I recently upgrades tot ^2.0 and encountered the following issue:

Could not encode value into JSON format. Error was: "Recursion detected".
Sentry\Exception\JsonException

at

โŸฉ Sentry\Util\JSON::encode
ROOT/vendor/sentry/sentry/src/Transport/HttpTransport.php, line 113

Its quite hard do share the actual dump with you, because its full of confidential data. But the digging that I have managed to do points to the Sentry Breadcrumbs. I am unsure if this is a bug with Sentry or with the plugin.

Update: more specifically:

  • I have a controller, that uses a component.
  • The component (obviously) has a ComponentRepository
  • the ComponentRepository again has a reference to the controller
  • hence, recursion

convertLevelToSeverity Method behaves incorrectly

Hallo,

$engine = \Cake\Log\Log::engine('error');

$engine->debug("Debug thing", ['bla'=>new \Exception('Debug exception')]); // ok
$engine->info("Info thing", ['bla'=>new \Exception('Info exception')]); // ok
$engine->warning("Warn thing", ['bla'=>new \Exception('Warn exception')]); // ok
$engine->error("Error thing", ['bla'=>new \Exception('Error exception')]); // ok

$engine->notice("Notice thing", ['bla'=>new \Exception('Notice exception')]); // error
$engine->critical("Critical thing", ['bla'=>new \Exception('Critical exception')]); // error
$engine->alert("Alert thing", ['bla'=>new \Exception('Alert exception')]); // error
$engine->emergency("Emergency thing", ['bla'=>new \Exception('Emergency exception')]); // error

Error:
"Sentry\\Severity::fromError(): Argument #1 ($severity) must be of type int, string given, called in /app/vendor/connehito/cake-sentry/src/Http/Client.php on line 144"

"notice", "alert", "critical" and "emergency" are log levels as a string which cause a TypeError when passed to the "fromError" method.

Since Sentry does not support these log levels, it tries to set them to the "Error" level (notices as info level), but it fails because the "fromError" method only accepts integers as the level.

With the call
$engine->log(E_NOTICE, "Notice thing", ['bla'=>new \Exception('Notice exception')]);
it works again. The error is logged with info level.

Please adapt the method so that all log levels are mapped correctly, regardless of whether they are strings or integers.
My workaround is now to overwrite the log method and set the log level myself before passing it to the parent method. Not nice.

Thanks

Release for 4.x

We have released the beta version of the next major version ๐Ÿ˜„
https://github.com/Connehito/cake-sentry/releases/tag/4.0.0-beta1

The goals for version 4.0.0 are managed in milestones.
https://github.com/Connehito/cake-sentry/milestone/3

In this issue, we will review the issues and remaining tasks until the official release.


The scope of 4.0.0 will include resolution of the following existing issues

The following tasks need to be completed before the stable version can be released

  • Write documents to migration from 3.x to 4.0
  • Appropriate amount of behavior verification (in real applications if possible)

any more?

Compatibility with guzzlehttp/guzzle 7.2.0 ?

Hi,
many thanks for your job, it's very useful !
Please, could it be possible to let guzzlehttp/guzzle 7.2.0 in required in addition with guzzlehttp/guzzle 6.X ?

Because i use aws/aws-sdk-php and it use guzzlehttp/guzzle 7.2.0.

Many thanks for your help,
Best regards

PHP 8 compatibility

Any plans for PHP 8 upgrade?

This would need an upgrade to Sentry 3.x as well AFAIK

CLI Support

Is there a way to setup this to send CLI errors to sentry?

Record useful logs as Breadcrumbs to understand and reproduce the situation.

Sentry provides a feature called Breadcrumbs.
According to the mention on the official site, this feature is intended for server-side use in the following ways

Sentry server-side SDKs, including Python and PHP, provide breadcrumbs for logging messages, network requests, database queries, and more.
https://sentry.io/features/breadcrumbs/

If this plugin can also retain "what was happening" with these features, the development and maintenance of CakePHP applications will be even more pleasant.

In sentry-laravel, The following PR is the initial version implemented.
https://github.com/getsentry/sentry-laravel/pull/31/files

Would it be possible to perform a similar process? I think it's worth looking into.

Cake 4.4 deprecation warning

Use of `BaseErrorHandler` and subclasses are deprecated. Upgrade to the new `ErrorTrap` and `ExceptionTrap` subsystem. 
See https://book.cakephp.org/4/en/appendices/4-4-migration-guide.html
<my-path>/vendor/connehito/cake-sentry/config/bootstrap.php, line: 22

Adding scope does not work

I have tried multiple ways to add scope after Sentry::init(). The new tags are not showing up.

e.g.: I am calling this from in my AppController->before

\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
    $scope->setUser(['email' => $this->user->email]);
    $scope->setTag('email', $this->user->email);
});

or I have been implementing certain EventListenerInterface and set the tags there. They never show up.

So I got curios and tried to add a new tag in my app.php and the test tag was shown immediately!!

'Sentry' => [
    'tags' => ['test' => 'test'],
    'dsn' => env('SENTRY_DSN'),
    'environment' => env('ENVIRONMENT', 'localhost'),
],

Versions:

  • cakephp/cakephp: 4.2.7
  • "connehito/cake-sentry": "^4.0",
  • sentry/sentry (3.3.1) -- also tried with sentry/sentry (3.3.4)

CakeSentry.Client.afterCapture event is dispatched after ErrorController rendering.

Following my use case of issue #3 I noticed that it never worked on the first time (but only the second time an exception/error is triggered).

For the v2.x of the plugin, the Event CakeSentry.Client.afterCapture that is used to set the last_event_id in session to pass it to the view is triggered after the rendering of my ErrorController so when I FIRST try to use the event id in my custom Error view, it is not defined, so it only works the second time (refresh) because the last_event_id is putted in session after the view rendering.

Any idea how to workaround that ?

CakePHP 3.6.x Sentry Environments

Hi,
how to define Environments for

  • local
  • staging
  • production

can't find any Docs how to do it for a CakePHP App

EDIT:
in "app/config/app.php" i have setup these settings for each instance

'Sentry' => [
        'dsn' => '__DSN__',
        'environment' => 'production' // can be 'local' or 'staging'
    ],

Pass returned sentry id to view

Hi,

First of all, thanks for this integration of sentry with CakePHP 3.5+ ๐Ÿ˜
I was wondering if it will be possible to get back the incident/issue id returned by raven and to pass it to my error view.

Is it possible to do that ? Can you guide me ?

Thanks again ๐Ÿ™‚

Error with sentry/sentry:2.4.0

cron build job failed: https://travis-ci.org/github/Connehito/cake-sentry/jobs/691024262
release: https://github.com/getsentry/sentry-php/releases/tag/2.4.0

I've reproduced it in my local environment:

  • After composer update, failed in ClientTest
    • Symfony\Component\OptionsResolver\Exception\InvalidOptionsException : The option "dsn" with value "https://user:[email protected]/yourproject" is invalid.
  • After composer require sentry/sentry:2.3.2, succeeded in ClientTest

I haven't been able to find out the details yet, but it seems that the behavior of the Client setup has changed and there is a problem.

Exception not being sent to Sentry

Hello,

I am trying to upgrade to the 2.x version of the plugin.

I have correctly setup everything but exception are not being sent to Sentry.
Trying to understand what is going on, I succeeded to send the exception to Sentry if I replace

if (!Hash::get($config, 'before_send')) {
     $config['before_send'] = function () {
          $event = new Event('CakeSentry.Client.afterCapture', $this, func_get_args());
          $this->getEventManager()->dispatch($event);
     };
}

by

if (!Hash::get($config, 'before_send')) {
     $config['before_send'] = function ($event) {
         return $event;
     };
}

in the file vendor/connehito/cake-sentry/src/Http/Client.php


If I do not do that, when prepareEvent() function is called in vendor/sentry/sentry/src/Client.php, \call_user_func($this->options->getBeforeSendCallback(), $event); returns null instead of the expected object(Sentry\Event) causing the exception to not being sent to Sentry :(

Of course, swapping

'Sentry' => [
        'dsn' => env('SENTRY_DSN'),
    ],

to

'Sentry' => [
        'dsn' => env('SENTRY_DSN'),
        'before_send' => function ($event) {
            return $event;
        }
    ],

in app.php works as expected but this should not be necessary, right ?

Any idea why this is happening ? Thanks ๐Ÿ˜‰

Sentry Performance

Hi I was wondering if there was any thought to adding the performance side of sentry to this plugin? ive tried to add the array key in but it crashes as the sentry SDK currently in place with it doesnt support the new option key.

issue while installing in cake php 3.7

using command
composer require connehito/cake-sentry

error:
Problem 1
- Installation request for connehito/cake-sentry ^4.0 -> satisfiable by connehito/cake-sentry[4.0.0].
- connehito/cake-sentry 4.0.0 requires cakephp/cakephp ^4.0 -> satisfiable by cakephp/cakephp[4.0.0, 4.0.0-RC1, 4.0.0-RC2, 4.0.0-alpha1, 4.0.0-alpha2, 4.0.0-beta1, 4.0.0-beta2, 4.0.0-beta3, 4.0.0-beta4, 4.0.1, 4.0.10, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.0.7, 4.0.8, 4.0.9, 4.1.0, 4.1.0-RC1, 4.1.0-RC2, 4.1.0-beta1, 4.1.1, 4.1.2, 4.1.3, 4.1.4, 4.1.5, 4.1.6, 4.1.7, 4.2.0, 4.2.0-RC1, 4.2.0-beta1, 4.2.1, 4.2.10, 4.2.11, 4.2.12, 4.2.2, 4.2.3, 4.2.4, 4.2.5, 4.2.6, 4.2.7, 4.2.8, 4.2.9, 4.3.0, 4.3.0-RC1, 4.3.0-RC2, 4.3.0-RC3, 4.3.0-RC4, 4.3.1, 4.3.10, 4.3.11, 4.3.2, 4.3.3, 4.3.4, 4.3.5, 4.3.6, 4.3.7, 4.3.8, 4.3.9, 4.4.0, 4.4.0-RC1, 4.4.0-RC2, 4.4.1, 4.4.10, 4.4.2, 4.4.3, 4.4.4, 4.4.5, 4.4.6, 4.4.7, 4.4.8, 4.4.9, 4.x-dev] but these conflict with your requirements or minimum-stability.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.