Completed
Push — master ( 14da43...08fd2e )
by Russell
30s queued 27s
created

SentryHandler::getMessageScope()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Class: SentryHandler.
5
 *
6
 * @author  Russell Michell 2017-2019 <[email protected]>
7
 * @package phptek/sentry
8
 */
9
10
namespace PhpTek\Sentry\Handler;
11
12
use Monolog\Handler\AbstractProcessingHandler;
13
use Monolog\Logger;
14
use Sentry\Severity;
15
use Sentry\State\Scope;
16
use SilverStripe\Core\Injector\Injectable;
17
use PhpTek\Sentry\Log\SentryLogger;
18
use PhpTek\Sentry\Adaptor\SentryAdaptor;
19
use PhpTek\Sentry\Adaptor\SentrySeverity;
20
21
/**
22
 * Monolog handler to send messages to a Sentry (https://github.com/getsentry/sentry) server
23
 * using sentry-php (https://github.com/getsentry/sentry-php).
24
 */
25
class SentryHandler extends AbstractProcessingHandler
26
{
27
28
    use Injectable;
29
30
    /**
31
     * @param  int     $level
32
     * @param  boolean $bubble
33
     * @param  array   $extras
34
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
35
     */
36
    public function __construct(int $level = Logger::DEBUG, bool $bubble = true, array $extras = [])
37
    {
38
        // Returns an instance of {@link SentryLogger}
39
        $logger = SentryLogger::factory($extras);
40
        $this->client = $logger->getAdaptor();
0 ignored issues
show
Bug introduced by
The property client does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
41
42
        parent::__construct($level, $bubble);
43
    }
44
45
    /**
46
     * write() forms the entry point into the physical sending of the error. The
47
     * sending itself is done by the current adaptor's `send()` method.
48
     *
49
     * @param  array $record An array of error-context metadata with the following
50
     *                       available keys:
51
     *
52
     *                       - message
53
     *                       - context
54
     *                       - level
55
     *                       - level_name
56
     *                       - channel
57
     *                       - datetime
58
     *                       - extra
59
     *                       - formatted
60
     *
61
     * @return void
62
     */
63
    protected function write(array $record) : void
64
    {
65
        // TODO $record['stacktrace'] is never actually sent anywhere. As such,
66
        // we cannot clean-up the class::methods that we'd like to.
67
        $record = array_merge($record, [
68
            'timestamp' => $record['datetime']->getTimestamp(),
69
            'stacktrace' => SentryLogger::backtrace($record),
70
        ]);
71
72
        if (
73
                isset($record['context']['exception']) &&
74
                $record['context']['exception'] instanceof \Throwable
75
        ) {
76
            $this->client->getSDK()->captureException(
77
                $record['context']['exception'],
78
                $this->client->getContext()
79
            );
80
        } else {
81
            // Note: We are setting Sentry\Options::setAttachStacktrace(true) in
82
            // SentryAdaptor and therefore have no control over cleaning-up the exceptions
83
            // it produces
84
            $this->client->getSDK()->captureMessage(
85
                $record['formatted'],
86
                new Severity(SentrySeverity::process_severity($record['level_name'])),
87
                $this->client->getContext()
88
            );
89
        }
90
    }
91
92
    /**
93
     * @return SentryAdaptor
94
     */
95
    public function getClient() : SentryAdaptor
96
    {
97
        return $this->client;
98
    }
99
100
}
101