|
2 | 2 |
|
3 | 3 | namespace Sentry\SentryLaravel; |
4 | 4 |
|
| 5 | +use Exception; |
| 6 | +use Illuminate\Database\Events\QueryExecuted; |
5 | 7 | use Illuminate\Events\Dispatcher; |
| 8 | +use Illuminate\Log\Events\MessageLogged; |
| 9 | +use Illuminate\Routing\Events\RouteMatched; |
| 10 | +use Illuminate\Routing\Route; |
| 11 | +use Raven_Client; |
6 | 12 |
|
7 | | -// Event handling inspired by the ``laravel-debugbar`` project: |
8 | | -// https://github.com/barryvdh/laravel-debugbar |
9 | 13 | class SentryLaravelEventHandler |
10 | 14 | { |
11 | | - public function __construct(\Raven_Client $client, array $config) |
| 15 | + |
| 16 | + /** |
| 17 | + * Maps event handler function to event names. |
| 18 | + * |
| 19 | + * @var array |
| 20 | + */ |
| 21 | + protected static $eventHandlerMap = [ |
| 22 | + 'router.matched' => 'routerMatched', // Until Laravel 5.1 |
| 23 | + 'Illuminate\Routing\Events\RouteMatched' => 'routeMatched', // Since Laravel 5.2 |
| 24 | + |
| 25 | + 'illuminate.query' => 'query', // Until Laravel 5.1 |
| 26 | + 'Illuminate\Database\Events\QueryExecuted' => 'queryExecuted', // Since Laravel 5.2 |
| 27 | + |
| 28 | + 'illuminate.log' => 'log', // Until Laravel 5.3 |
| 29 | + 'Illuminate\Log\Events\MessageLogged' => 'messageLogged', // Since Laravel 5.4 |
| 30 | + ]; |
| 31 | + |
| 32 | + /** |
| 33 | + * Event recorder. |
| 34 | + * |
| 35 | + * @var Raven_Client |
| 36 | + */ |
| 37 | + protected $client; |
| 38 | + |
| 39 | + /** |
| 40 | + * @param Raven_Client $client |
| 41 | + * @param array $config |
| 42 | + */ |
| 43 | + public function __construct(Raven_Client $client, array $config) |
12 | 44 | { |
13 | 45 | $this->client = $client; |
14 | | - $this->sqlBindings = ( |
15 | | - isset($config['breadcrumbs.sql_bindings']) |
| 46 | + $this->sqlBindings = isset($config['breadcrumbs.sql_bindings']) |
16 | 47 | ? $config['breadcrumbs.sql_bindings'] |
17 | | - : true |
18 | | - ); |
| 48 | + : true; |
19 | 49 | } |
20 | 50 |
|
| 51 | + /** |
| 52 | + * Attach all event handlers. |
| 53 | + * |
| 54 | + * @param Dispatcher $events |
| 55 | + */ |
21 | 56 | public function subscribe(Dispatcher $events) |
22 | 57 | { |
23 | | - $this->events = $events; |
24 | | - $events->listen('*', [$this, 'onWildcardEvent']); |
| 58 | + foreach (static::$eventHandlerMap as $eventName => $handler) { |
| 59 | + $events->listen($eventName, [$this, $handler]); |
| 60 | + } |
25 | 61 | } |
26 | 62 |
|
27 | | - public function onWildcardEvent() |
| 63 | + /** |
| 64 | + * Pass through the event and capture any errors. |
| 65 | + * |
| 66 | + * @param $method |
| 67 | + * @param $arguments |
| 68 | + */ |
| 69 | + public function __call($method, $arguments) |
28 | 70 | { |
29 | | - $args = func_get_args(); |
30 | 71 | try { |
31 | | - $this->_onWildcardEvent($args); |
32 | | - } catch (\Exception $e) { |
| 72 | + call_user_func_array([$this, $method . 'handler'], $arguments); |
| 73 | + } catch (Exception $exception) { |
| 74 | + // Ignore |
33 | 75 | } |
34 | 76 | } |
35 | 77 |
|
36 | | - protected function _onWildcardEvent($args) |
| 78 | + /** |
| 79 | + * Record the event with default values. |
| 80 | + * |
| 81 | + * @param array $payload |
| 82 | + */ |
| 83 | + protected function record($payload) |
37 | 84 | { |
38 | | - $name = $this->events->firing(); |
39 | | - $data = null; |
40 | | - $level = 'info'; |
41 | | - if ($name === 'Illuminate\Routing\Events\RouteMatched') { |
42 | | - $route = $args[0]->route; |
43 | | - $routeName = $route->getActionName(); |
44 | | - if ($routeName && $routeName !== 'Closure') { |
45 | | - $this->client->transaction->push($routeName); |
46 | | - } |
47 | | - } elseif ($name === 'router.matched') { |
48 | | - $route = $args[0]; |
49 | | - $routeName = $route->getActionName(); |
50 | | - if ($routeName && $routeName !== 'Closure') { |
51 | | - $this->client->transaction->push($routeName); |
52 | | - } |
| 85 | + $this->client->breadcrumbs->record(array_merge([ |
| 86 | + 'data' => null, |
| 87 | + 'level' => 'info', |
| 88 | + ], $payload)); |
| 89 | + } |
| 90 | + |
| 91 | + /** |
| 92 | + * Until Laravel 5.1 |
| 93 | + * |
| 94 | + * @param Route $route |
| 95 | + */ |
| 96 | + protected function routerMatchedHandler(Route $route) |
| 97 | + { |
| 98 | + $routeName = $route->getActionName(); |
| 99 | + |
| 100 | + if ($routeName && $routeName !== 'Closure') { |
| 101 | + $this->client->transaction->push($routeName); |
53 | 102 | } |
| 103 | + } |
54 | 104 |
|
55 | | - if ($name === 'Illuminate\Database\Events\QueryExecuted') { |
56 | | - $name = 'sql.query'; |
57 | | - $message = $args[0]->sql; |
58 | | - $data = array( |
59 | | - 'connectionName' => $args[0]->connectionName, |
60 | | - ); |
61 | | - if ($this->sqlBindings) { |
62 | | - $bindings = $args[0]->bindings; |
63 | | - if (!empty($bindings)) { |
64 | | - $data['bindings'] = $bindings; |
65 | | - } |
66 | | - } |
67 | | - } elseif ($name === 'illuminate.query') { |
68 | | - // $args = array(sql, bindings, ...) |
69 | | - $name = 'sql.query'; |
70 | | - $message = $args[0]; |
71 | | - $data = array( |
72 | | - 'connectionName' => $args[3], |
73 | | - ); |
74 | | - if ($this->sqlBindings) { |
75 | | - $bindings = $args[1]; |
76 | | - if (!empty($bindings)) { |
77 | | - $data['bindings'] = $bindings; |
78 | | - } |
79 | | - } |
80 | | - } elseif ($name === 'illuminate.log') { |
81 | | - $name = 'log.' . $args[0]; |
82 | | - $level = $args[0]; |
83 | | - $message = $args[1]; |
84 | | - if (!empty($args[2])) { |
85 | | - $data = array('params' => $args[2]); |
86 | | - } |
87 | | - } else { |
88 | | - return; |
| 105 | + /** |
| 106 | + * Since Laravel 5.2 |
| 107 | + * |
| 108 | + * @param RouteMatched $match |
| 109 | + */ |
| 110 | + protected function routeMatchedHandler(RouteMatched $match) |
| 111 | + { |
| 112 | + $this->routerMatchedHandler($match->route); |
| 113 | + } |
| 114 | + |
| 115 | + /** |
| 116 | + * Until Laravel 5.1 |
| 117 | + * |
| 118 | + * @param $query |
| 119 | + * @param $bindings |
| 120 | + * @param $time |
| 121 | + * @param $connectionName |
| 122 | + */ |
| 123 | + protected function queryHandler($query, $bindings, $time, $connectionName) |
| 124 | + { |
| 125 | + $data = [ |
| 126 | + 'connectionName' => $connectionName, |
| 127 | + ]; |
| 128 | + |
| 129 | + if ($this->sqlBindings && !empty($bindings)) { |
| 130 | + $data['bindings'] = $bindings; |
| 131 | + } |
| 132 | + |
| 133 | + $this->record([ |
| 134 | + 'message' => $query, |
| 135 | + 'category' => 'sql.query', |
| 136 | + ]); |
| 137 | + } |
| 138 | + |
| 139 | + /** |
| 140 | + * Since Laravel 5.2 |
| 141 | + * |
| 142 | + * @param QueryExecuted $query |
| 143 | + */ |
| 144 | + protected function queryExecutedHandler(QueryExecuted $query) |
| 145 | + { |
| 146 | + $data = [ |
| 147 | + 'connectionName' => $query->connectionName, |
| 148 | + ]; |
| 149 | + |
| 150 | + if ($this->sqlBindings && !empty($bindings)) { |
| 151 | + $data['bindings'] = $query->bindings; |
89 | 152 | } |
90 | | - $this->client->breadcrumbs->record(array( |
91 | | - 'message' => $message, |
92 | | - 'category' => $name, |
93 | | - 'data' => $data, |
94 | | - 'level' => $level, |
95 | | - )); |
| 153 | + |
| 154 | + $this->client->breadcrumbs->record([ |
| 155 | + 'message' => $query->sql, |
| 156 | + 'category' => 'sql.query', |
| 157 | + 'data' => $data, |
| 158 | + ]); |
| 159 | + } |
| 160 | + |
| 161 | + /** |
| 162 | + * Until Laravel 5.3 |
| 163 | + * |
| 164 | + * @param $level |
| 165 | + * @param $message |
| 166 | + * @param $context |
| 167 | + */ |
| 168 | + protected function logHandler($level, $message, $context) |
| 169 | + { |
| 170 | + $this->client->breadcrumbs->record([ |
| 171 | + 'message' => $message, |
| 172 | + 'category' => 'log.' . $level, |
| 173 | + 'data' => empty($context) ? null : ['params' => $context], |
| 174 | + 'level' => $level, |
| 175 | + ]); |
| 176 | + } |
| 177 | + |
| 178 | + /** |
| 179 | + * Since Laravel 5.4 |
| 180 | + * |
| 181 | + * @param MessageLogged $logEntry |
| 182 | + */ |
| 183 | + protected function messageLoggedHandler(MessageLogged $logEntry) |
| 184 | + { |
| 185 | + $this->client->breadcrumbs->record([ |
| 186 | + 'message' => $logEntry->message, |
| 187 | + 'category' => 'log.' . $logEntry->level, |
| 188 | + 'data' => empty($logEntry->context) ? null : ['params' => $logEntry->context], |
| 189 | + 'level' => $logEntry->level, |
| 190 | + ]); |
96 | 191 | } |
97 | 192 | } |
0 commit comments