1
|
|
|
<?php namespace Understand\UnderstandLaravel5; |
2
|
|
|
|
3
|
|
|
use Illuminate\Foundation\AliasLoader; |
4
|
|
|
use Illuminate\Support\Str; |
5
|
|
|
use Illuminate\Foundation\Application; |
6
|
|
|
use Exception; |
7
|
|
|
use Throwable; |
8
|
|
|
|
9
|
|
|
class UnderstandLaravel5ServiceProvider extends UnderstandServiceProvider |
10
|
|
|
{ |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Indicates if loading of the provider is deferred. |
14
|
|
|
* |
15
|
|
|
* @var bool |
16
|
|
|
*/ |
17
|
|
|
protected $defer = false; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Bootstrap the application events. |
21
|
|
|
* |
22
|
|
|
* @return void |
23
|
|
|
*/ |
24
|
|
|
public function boot() |
25
|
|
|
{ |
26
|
|
|
$configPath = __DIR__ . '/../../config/understand-laravel.php'; |
27
|
|
|
$this->publishes([$configPath => config_path('understand-laravel.php')], 'config'); |
28
|
|
|
$enabled = $this->app['config']->get('understand-laravel.enabled'); |
29
|
|
|
|
30
|
|
|
if ($enabled) |
31
|
|
|
{ |
32
|
|
|
$this->listenLaravelEvents(); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
if ($enabled && $this->app['config']->get('understand-laravel.sql_enabled')) |
36
|
|
|
{ |
37
|
|
|
$this->listenQueryEvents(); |
38
|
|
|
} |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Register the service provider. |
43
|
|
|
* |
44
|
|
|
* @return void |
45
|
|
|
*/ |
46
|
|
|
public function register() |
47
|
|
|
{ |
48
|
|
|
$this->registerConfig(); |
49
|
|
|
$this->registerFieldProvider(); |
50
|
|
|
$this->registerDataCollector(); |
51
|
|
|
$this->registerTokenProvider(); |
52
|
|
|
$this->registerLogger(); |
53
|
|
|
$this->registerExceptionEncoder(); |
54
|
|
|
$this->registerEventLoggers(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Register field provider |
59
|
|
|
* |
60
|
|
|
* @return void |
61
|
|
|
*/ |
62
|
|
|
protected function registerFieldProvider() |
63
|
|
|
{ |
64
|
|
View Code Duplication |
$this->app->bind('understand.fieldProvider', function($app) |
|
|
|
|
65
|
|
|
{ |
66
|
|
|
$fieldProvider = new FieldProvider(); |
67
|
|
|
|
68
|
|
|
if ($app['config']['session.driver']) |
69
|
|
|
{ |
70
|
|
|
$fieldProvider->setSessionStore($app['session.store']); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
$fieldProvider->setRouter($app['router']); |
74
|
|
|
$fieldProvider->setRequest($app['request']); |
75
|
|
|
$fieldProvider->setEnvironment($app->environment()); |
76
|
|
|
$fieldProvider->setTokenProvider($app['understand.tokenProvider']); |
77
|
|
|
$fieldProvider->setDataCollector($app['understand.dataCollector']); |
78
|
|
|
$fieldProvider->setApp($app); |
79
|
|
|
|
80
|
|
|
return $fieldProvider; |
81
|
|
|
}); |
82
|
|
|
|
83
|
|
|
$this->app->booting(function() |
84
|
|
|
{ |
85
|
|
|
$loader = AliasLoader::getInstance(); |
86
|
|
|
$loader->alias('UnderstandFieldProvider', 'Understand\UnderstandLaravel5\Facades\UnderstandFieldProvider'); |
87
|
|
|
}); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Register exception and event logger |
92
|
|
|
* |
93
|
|
|
* @return void |
94
|
|
|
*/ |
95
|
|
|
protected function registerEventLoggers() |
96
|
|
|
{ |
97
|
|
|
parent::registerEventLoggers(); |
98
|
|
|
|
99
|
|
|
$this->app->booting(function() |
100
|
|
|
{ |
101
|
|
|
$loader = AliasLoader::getInstance(); |
102
|
|
|
$loader->alias('UnderstandExceptionLogger', 'Understand\UnderstandLaravel5\Facades\UnderstandExceptionLogger'); |
103
|
|
|
}); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Register understand logger |
108
|
|
|
* |
109
|
|
|
* @return void |
110
|
|
|
*/ |
111
|
|
|
protected function registerLogger() |
112
|
|
|
{ |
113
|
|
|
parent::registerLogger(); |
114
|
|
|
|
115
|
|
|
$this->app->booting(function() |
116
|
|
|
{ |
117
|
|
|
$loader = AliasLoader::getInstance(); |
118
|
|
|
$loader->alias('UnderstandLogger', 'Understand\UnderstandLaravel5\Facades\UnderstandLogger'); |
119
|
|
|
}); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Detect Laravel version |
124
|
|
|
* |
125
|
|
|
* @param array $versions |
126
|
|
|
* @return type |
127
|
|
|
*/ |
128
|
|
|
protected function detectLaravelVersion(array $versions) |
129
|
|
|
{ |
130
|
|
|
return Str::startsWith(Application::VERSION, $versions); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Listen Laravel logs and queue events |
135
|
|
|
* |
136
|
|
|
* @return void |
137
|
|
|
*/ |
138
|
|
|
protected function listenLaravelEvents() |
139
|
|
|
{ |
140
|
|
|
// only Laravel versions below L5.4 supports `illuminate.log` |
141
|
|
|
if ($this->detectLaravelVersion(['5.0', '5.1', '5.2', '5.3'])) |
142
|
|
|
{ |
143
|
|
|
$this->app['events']->listen('illuminate.log', function($level, $message, $context) |
144
|
|
|
{ |
145
|
|
|
$this->handleEvent($level, $message, $context); |
146
|
|
|
}); |
147
|
|
|
} |
148
|
|
View Code Duplication |
else |
|
|
|
|
149
|
|
|
{ |
150
|
|
|
// starting from L5.4 MessageLogged event class was introduced |
151
|
|
|
// https://github.com/laravel/framework/commit/57c82d095c356a0fe0f9381536afec768cdcc072 |
152
|
|
|
$this->app['events']->listen('Illuminate\Log\Events\MessageLogged', function($log) |
153
|
|
|
{ |
154
|
|
|
|
155
|
|
|
$this->handleEvent($log->level, $log->message, $log->context); |
156
|
|
|
}); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
// starting from L5.2 JobProcessing event class was introduced |
160
|
|
|
// https://github.com/illuminate/queue/commit/ce2b5518902b1bcb9ef650c41900fc8c6392eb0c |
161
|
|
View Code Duplication |
if ($this->app->runningInConsole()) |
|
|
|
|
162
|
|
|
{ |
163
|
|
|
if ($this->detectLaravelVersion(['5.0', '5.1'])) |
164
|
|
|
{ |
165
|
|
|
$this->app['events']->listen('illuminate.queue.after', function() |
166
|
|
|
{ |
167
|
|
|
$this->app['understand.tokenProvider']->generate(); |
168
|
|
|
$this->app['understand.dataCollector']->reset(); |
169
|
|
|
}); |
170
|
|
|
|
171
|
|
|
$this->app['events']->listen('illuminate.queue.failed', function() |
172
|
|
|
{ |
173
|
|
|
$this->app['understand.tokenProvider']->generate(); |
174
|
|
|
$this->app['understand.dataCollector']->reset(); |
175
|
|
|
}); |
176
|
|
|
} |
177
|
|
|
else |
178
|
|
|
{ |
179
|
|
|
$this->app['events']->listen('Illuminate\Queue\Events\JobProcessing', function() |
180
|
|
|
{ |
181
|
|
|
$this->app['understand.tokenProvider']->generate(); |
182
|
|
|
$this->app['understand.dataCollector']->reset(); |
183
|
|
|
}); |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Listen Query events |
190
|
|
|
* |
191
|
|
|
* @return void |
192
|
|
|
*/ |
193
|
|
View Code Duplication |
protected function listenQueryEvents() |
|
|
|
|
194
|
|
|
{ |
195
|
|
|
// only Laravel versions below L5.2 supports `illuminate.query` |
196
|
|
|
if ($this->detectLaravelVersion(['5.0', '5.1'])) |
197
|
|
|
{ |
198
|
|
|
// $this->events->fire('illuminate.query', [$query, $bindings, $time, $this->getName()]); |
199
|
|
|
$this->app['events']->listen('illuminate.query', function($query, $bindings, $time) |
200
|
|
|
{ |
201
|
|
|
$this->app['understand.dataCollector']->setInArray('sql_queries', [ |
202
|
|
|
'query' => $query, |
203
|
|
|
'bindings' => $bindings, |
204
|
|
|
'time' => $time, |
205
|
|
|
]); |
206
|
|
|
}); |
207
|
|
|
} |
208
|
|
|
else |
209
|
|
|
{ |
210
|
|
|
// https://laravel.com/api/5.3/Illuminate/Database/Events/QueryExecuted.html |
211
|
|
|
$this->app['events']->listen('Illuminate\Database\Events\QueryExecuted', function($event) |
212
|
|
|
{ |
213
|
|
|
$this->app['understand.dataCollector']->setInArray('sql_queries', [ |
214
|
|
|
'query' => $event->sql, |
215
|
|
|
'bindings' => $event->bindings, |
216
|
|
|
'time' => $event->time, |
217
|
|
|
]); |
218
|
|
|
}); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Handle a new log event |
224
|
|
|
* |
225
|
|
|
* @param string $level |
226
|
|
|
* @param mixed $message |
227
|
|
|
* @param array $context |
228
|
|
|
* @return void |
229
|
|
|
*/ |
230
|
|
|
protected function handleEvent($level, $message, $context) |
231
|
|
|
{ |
232
|
|
|
if ($this->shouldIgnoreEvent($level, $message, $context)) |
233
|
|
|
{ |
234
|
|
|
return; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// `\Log::info`, `\Log::debug` and NOT `\Exception` or `\Throwable` |
238
|
|
|
if (in_array($level, ['info', 'debug']) && ! ($message instanceof Exception || $message instanceof Throwable)) |
|
|
|
|
239
|
|
|
{ |
240
|
|
|
$this->app['understand.eventLogger']->logEvent($level, $message, $context); |
241
|
|
|
} |
242
|
|
|
// `\Log::notice`, `\Log::warning`, `\Log::error`, `\Log::critical`, `\Log::alert`, `\Log::emergency` and `\Exception`, `\Throwable` |
243
|
|
|
// '5.5', '5.6', '5.7', '5.8' |
244
|
|
|
else if ( ! $this->detectLaravelVersion(['5.0', '5.1', '5.2', '5.3', '5.4']) && isset($context['exception']) && ($context['exception'] instanceof Exception || $context['exception'] instanceof Throwable)) |
|
|
|
|
245
|
|
|
{ |
246
|
|
|
$exception = $context['exception']; |
247
|
|
|
unset($context['exception']); |
248
|
|
|
|
249
|
|
|
$this->app['understand.exceptionLogger']->logError($level, $exception, $context); |
250
|
|
|
} |
251
|
|
|
else |
252
|
|
|
{ |
253
|
|
|
$this->app['understand.exceptionLogger']->logError($level, $message, $context); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.