1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Liip\MonitorBundle\DependencyInjection; |
4
|
|
|
|
5
|
|
|
use Symfony\Component\Config\Definition\Builder\TreeBuilder; |
6
|
|
|
use Symfony\Component\Config\Definition\ConfigurationInterface; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* This class contains the configuration information for the bundle. |
10
|
|
|
* |
11
|
|
|
* This information is solely responsible for how the different configuration |
12
|
|
|
* sections are normalized, and merged. |
13
|
|
|
* |
14
|
|
|
* @author Lukas Kahwe Smith <[email protected]> |
15
|
|
|
*/ |
16
|
|
|
class Configuration implements ConfigurationInterface |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* Generates the configuration tree. |
20
|
|
|
* |
21
|
|
|
* @return TreeBuilder |
22
|
|
|
*/ |
23
|
49 |
|
public function getConfigTreeBuilder() |
24
|
|
|
{ |
25
|
49 |
|
$treeBuilder = new TreeBuilder('liip_monitor'); |
26
|
|
|
|
27
|
|
|
// Keep compatibility with symfony/config < 4.2 |
28
|
49 |
|
if (\method_exists($treeBuilder, 'getRootNode')) { |
29
|
49 |
|
$rootNode = $treeBuilder->getRootNode(); |
30
|
|
|
} else { |
31
|
|
|
$rootNode = $treeBuilder->root('liip_monitor'); |
|
|
|
|
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
$rootNode |
|
|
|
|
35
|
49 |
|
->beforeNormalization() |
36
|
|
|
->always(function ($v) { |
37
|
49 |
|
if (empty($v['default_group'])) { |
38
|
49 |
|
$v['default_group'] = 'default'; |
39
|
|
|
} |
40
|
|
|
|
41
|
49 |
|
if (isset($v['checks']) && is_array($v['checks']) && !isset($v['checks']['groups'])) { |
42
|
40 |
|
$checks = $v['checks']; |
43
|
40 |
|
unset($v['checks']); |
44
|
|
|
|
45
|
40 |
|
$v['checks']['groups'][$v['default_group']] = $checks; |
46
|
|
|
} |
47
|
|
|
|
48
|
49 |
|
return $v; |
49
|
49 |
|
}) |
50
|
49 |
|
->end() |
51
|
49 |
|
->children() |
52
|
49 |
|
->booleanNode('enable_controller')->defaultFalse()->end() |
53
|
49 |
|
->scalarNode('view_template')->defaultNull()->end() |
54
|
49 |
|
->integerNode('failure_status_code') |
55
|
49 |
|
->min(100)->max(598) |
56
|
49 |
|
->defaultValue(502) |
57
|
49 |
|
->end() |
58
|
49 |
|
->arrayNode('mailer') |
59
|
49 |
|
->canBeEnabled() |
60
|
49 |
|
->children() |
61
|
49 |
|
->arrayNode('recipient') |
62
|
49 |
|
->isRequired()->requiresAtLeastOneElement() |
63
|
49 |
|
->prototype('scalar')->end() |
64
|
49 |
|
->beforeNormalization() |
65
|
49 |
|
->ifString() |
66
|
|
|
->then(function ($v) { return [$v]; }) |
67
|
49 |
|
->end() |
68
|
49 |
|
->end() |
69
|
49 |
|
->scalarNode('sender')->isRequired()->cannotBeEmpty()->end() |
70
|
49 |
|
->scalarNode('subject')->isRequired()->cannotBeEmpty()->end() |
71
|
49 |
|
->booleanNode('send_on_warning')->defaultTrue()->end() |
72
|
49 |
|
->end() |
73
|
49 |
|
->end() |
74
|
49 |
|
->scalarNode('default_group')->defaultValue('default')->end() |
75
|
49 |
|
->arrayNode('checks') |
76
|
49 |
|
->canBeUnset() |
77
|
49 |
|
->children() |
78
|
49 |
|
->append($this->createGroupsNode()) |
79
|
49 |
|
->end() |
80
|
49 |
|
->end() |
81
|
49 |
|
->end() |
82
|
49 |
|
->end(); |
83
|
|
|
|
84
|
49 |
|
return $treeBuilder; |
85
|
|
|
} |
86
|
|
|
|
87
|
49 |
|
private function createGroupsNode() |
88
|
|
|
{ |
89
|
49 |
|
$builder = new TreeBuilder('groups'); |
90
|
|
|
|
91
|
|
|
// Keep compatibility with symfony/config < 4.2 |
92
|
49 |
|
if (\method_exists($builder, 'getRootNode')) { |
93
|
49 |
|
$node = $builder->getRootNode(); |
94
|
|
|
} else { |
95
|
|
|
$node = $builder->root('groups'); |
|
|
|
|
96
|
|
|
} |
97
|
|
|
$node |
98
|
49 |
|
->requiresAtLeastOneElement() |
99
|
49 |
|
->info('Grouping checks') |
100
|
49 |
|
->useAttributeAsKey('name') |
101
|
49 |
|
->prototype('array') |
102
|
49 |
|
->children() |
103
|
49 |
|
->arrayNode('php_extensions') |
104
|
49 |
|
->info('Validate that a named extension or a collection of extensions is available') |
105
|
49 |
|
->example('session.use_only_cookies: false') |
106
|
49 |
|
->prototype('scalar')->end() |
107
|
49 |
|
->end() |
108
|
49 |
|
->arrayNode('php_flags') |
109
|
49 |
|
->info('Pairs of a PHP setting and an expected value') |
110
|
49 |
|
->example('session.use_only_cookies: false') |
111
|
49 |
|
->useAttributeAsKey('setting') |
112
|
49 |
|
->prototype('scalar')->defaultValue(true)->end() |
113
|
49 |
|
->end() |
114
|
49 |
|
->arrayNode('php_version') |
115
|
49 |
|
->info('Pairs of a version and a comparison operator') |
116
|
49 |
|
->example('5.4.15: >=') |
117
|
49 |
|
->useAttributeAsKey('version') |
118
|
49 |
|
->prototype('scalar')->end() |
119
|
49 |
|
->end() |
120
|
49 |
|
->variableNode('process_running') |
121
|
49 |
|
->info('Process name/pid or an array of process names/pids') |
122
|
49 |
|
->example('[apache, foo]') |
123
|
49 |
|
->end() |
124
|
49 |
|
->arrayNode('readable_directory') |
125
|
49 |
|
->info('Validate that a given path (or a collection of paths) is a dir and is readable') |
126
|
49 |
|
->example('["%kernel.cache_dir%"]') |
127
|
49 |
|
->prototype('scalar')->end() |
128
|
49 |
|
->end() |
129
|
49 |
|
->arrayNode('writable_directory') |
130
|
49 |
|
->info('Validate that a given path (or a collection of paths) is a dir and is writable') |
131
|
49 |
|
->example('["%kernel.cache_dir%"]') |
132
|
49 |
|
->prototype('scalar')->end() |
133
|
49 |
|
->end() |
134
|
49 |
|
->arrayNode('class_exists') |
135
|
49 |
|
->info('Validate that a class or a collection of classes is available') |
136
|
49 |
|
->example('["Lua", "My\Fancy\Class"]') |
137
|
49 |
|
->prototype('scalar')->end() |
138
|
49 |
|
->end() |
139
|
49 |
|
->scalarNode('cpu_performance') |
140
|
49 |
|
->info('Benchmark CPU performance and return failure if it is below the given ratio') |
141
|
49 |
|
->example('1.0 # This is the power of an EC2 micro instance') |
142
|
49 |
|
->end() |
143
|
49 |
|
->arrayNode('disk_usage') |
144
|
49 |
|
->info('Checks to see if the disk usage is below warning/critical percent thresholds') |
145
|
49 |
|
->children() |
146
|
49 |
|
->integerNode('warning')->defaultValue(70)->end() |
147
|
49 |
|
->integerNode('critical')->defaultValue(90)->end() |
148
|
49 |
|
->scalarNode('path')->defaultValue('%kernel.cache_dir%')->end() |
149
|
49 |
|
->end() |
150
|
49 |
|
->end() |
151
|
49 |
|
->arrayNode('symfony_requirements') |
152
|
49 |
|
->info('Checks Symfony2 requirements file') |
153
|
49 |
|
->children() |
154
|
49 |
|
->scalarNode('file')->defaultValue('%kernel.root_dir%/SymfonyRequirements.php')->end() |
155
|
49 |
|
->end() |
156
|
49 |
|
->end() |
157
|
49 |
|
->arrayNode('opcache_memory') |
158
|
49 |
|
->info('Checks to see if the OpCache memory usage is below warning/critical thresholds') |
159
|
49 |
|
->children() |
160
|
49 |
|
->integerNode('warning')->defaultValue(70)->end() |
161
|
49 |
|
->integerNode('critical')->defaultValue(90)->end() |
162
|
49 |
|
->end() |
163
|
49 |
|
->end() |
164
|
49 |
|
->arrayNode('apc_memory') |
165
|
49 |
|
->info('Checks to see if the APC memory usage is below warning/critical thresholds') |
166
|
49 |
|
->children() |
167
|
49 |
|
->integerNode('warning')->defaultValue(70)->end() |
168
|
49 |
|
->integerNode('critical')->defaultValue(90)->end() |
169
|
49 |
|
->end() |
170
|
49 |
|
->end() |
171
|
49 |
|
->arrayNode('apc_fragmentation') |
172
|
49 |
|
->info('Checks to see if the APC fragmentation is below warning/critical thresholds') |
173
|
49 |
|
->children() |
174
|
49 |
|
->integerNode('warning')->defaultValue(70)->end() |
175
|
49 |
|
->integerNode('critical')->defaultValue(90)->end() |
176
|
49 |
|
->end() |
177
|
49 |
|
->end() |
178
|
49 |
|
->variableNode('doctrine_dbal') |
179
|
49 |
|
->defaultNull() |
180
|
49 |
|
->info('Connection name or an array of connection names') |
181
|
49 |
|
->example('[default, crm]') |
182
|
49 |
|
->end() |
183
|
49 |
|
->variableNode('doctrine_mongodb') |
184
|
49 |
|
->defaultNull() |
185
|
49 |
|
->info('Connection name or an array of connection names') |
186
|
49 |
|
->example('[default, crm]') |
187
|
49 |
|
->end() |
188
|
49 |
|
->arrayNode('doctrine_migrations') |
189
|
49 |
|
->useAttributeAsKey('name') |
190
|
49 |
|
->info('Checks to see if migrations from specified configuration file are applied') |
191
|
49 |
|
->prototype('array') |
192
|
49 |
|
->children() |
193
|
49 |
|
->scalarNode('configuration_file') |
194
|
49 |
|
->info('Absolute path to doctrine migrations configuration') |
195
|
49 |
|
->end() |
196
|
49 |
|
->scalarNode('connection') |
197
|
49 |
|
->isRequired() |
198
|
49 |
|
->cannotBeEmpty() |
199
|
49 |
|
->info('Connection name from doctrine DBAL configuration') |
200
|
49 |
|
->end() |
201
|
49 |
|
->end() |
202
|
49 |
|
->beforeNormalization() |
203
|
49 |
|
->ifString() |
204
|
|
|
->then(function ($value) { |
205
|
|
|
if (is_string($value)) { |
206
|
|
|
$value = ['connection' => $value]; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
return $value; |
210
|
49 |
|
}) |
211
|
49 |
|
->end() |
212
|
49 |
|
->validate() |
213
|
|
|
->always(function ($value) { |
214
|
|
|
if (is_array($value) && !isset($value['configuration_file']) && !class_exists('Doctrine\\Bundle\\MigrationsBundle\\Command\\DoctrineCommand')) { |
215
|
|
|
throw new \InvalidArgumentException('You should explicitly define "configuration_file" parameter or install doctrine/doctrine-migrations-bundle to use empty parameter.'); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
return $value; |
219
|
49 |
|
}) |
220
|
49 |
|
->end() |
221
|
49 |
|
->end() |
222
|
49 |
|
->example( |
223
|
|
|
[ |
224
|
|
|
'application_migrations' => [ |
225
|
49 |
|
'configuration_file' => '%kernel.root_dir%/Resources/config/migrations.yml', |
226
|
|
|
'connection' => 'default', |
227
|
|
|
], |
228
|
|
|
'migrations_with_doctrine_bundle' => [ |
229
|
|
|
'connection' => 'default', |
230
|
|
|
], |
231
|
|
|
'migrations_with_doctrine_bundle_v2' => 'default', |
232
|
|
|
] |
233
|
|
|
) |
234
|
49 |
|
->end() |
235
|
49 |
|
->arrayNode('memcache') |
236
|
49 |
|
->info('Check if MemCache extension is loaded and given server is reachable') |
237
|
49 |
|
->useAttributeAsKey('name') |
238
|
49 |
|
->prototype('array') |
239
|
49 |
|
->children() |
240
|
49 |
|
->scalarNode('host')->defaultValue('localhost')->end() |
241
|
49 |
|
->integerNode('port')->defaultValue(11211)->end() |
242
|
49 |
|
->end() |
243
|
49 |
|
->end() |
244
|
49 |
|
->end() |
245
|
49 |
|
->arrayNode('memcached') |
246
|
49 |
|
->info('Check if MemCached extension is loaded and given server is reachable') |
247
|
49 |
|
->useAttributeAsKey('name') |
248
|
49 |
|
->prototype('array') |
249
|
49 |
|
->children() |
250
|
49 |
|
->scalarNode('host')->defaultValue('localhost')->end() |
251
|
49 |
|
->integerNode('port')->defaultValue(11211)->end() |
252
|
49 |
|
->end() |
253
|
49 |
|
->end() |
254
|
49 |
|
->end() |
255
|
49 |
|
->arrayNode('redis') |
256
|
49 |
|
->info('Validate that a Redis service is running') |
257
|
49 |
|
->useAttributeAsKey('name') |
258
|
49 |
|
->beforeNormalization() |
259
|
49 |
|
->ifString() |
260
|
|
|
->then(function ($v) { return ['dsn' => $v]; }) |
261
|
49 |
|
->end() |
262
|
49 |
|
->prototype('array') |
263
|
49 |
|
->children() |
264
|
49 |
|
->scalarNode('host')->defaultValue('localhost')->end() |
265
|
49 |
|
->integerNode('port')->defaultValue(6379)->end() |
266
|
49 |
|
->scalarNode('password')->defaultNull()->end() |
267
|
49 |
|
->scalarNode('dsn')->defaultNull()->end() |
268
|
49 |
|
->end() |
269
|
49 |
|
->end() |
270
|
49 |
|
->end() |
271
|
49 |
|
->arrayNode('http_service') |
272
|
49 |
|
->info('Attempt connection to given HTTP host and (optionally) check status code and page content') |
273
|
49 |
|
->useAttributeAsKey('name') |
274
|
49 |
|
->prototype('array') |
275
|
49 |
|
->children() |
276
|
49 |
|
->scalarNode('host')->defaultValue('localhost')->end() |
277
|
49 |
|
->integerNode('port')->defaultValue(80)->end() |
278
|
49 |
|
->scalarNode('path')->defaultValue('/')->end() |
279
|
49 |
|
->integerNode('status_code')->defaultValue(200)->end() |
280
|
49 |
|
->scalarNode('content')->defaultNull()->end() |
281
|
49 |
|
->end() |
282
|
49 |
|
->end() |
283
|
49 |
|
->end() |
284
|
49 |
|
->arrayNode('guzzle_http_service') |
285
|
49 |
|
->info('Attempt connection using Guzzle to given HTTP host and (optionally) check status code and page content') |
286
|
49 |
|
->useAttributeAsKey('name') |
287
|
49 |
|
->prototype('array') |
288
|
49 |
|
->children() |
289
|
49 |
|
->scalarNode('url')->defaultValue('localhost')->end() |
290
|
49 |
|
->variableNode('headers')->defaultValue([])->end() |
291
|
49 |
|
->variableNode('options')->defaultValue([])->end() |
292
|
49 |
|
->integerNode('status_code')->defaultValue(200)->end() |
293
|
49 |
|
->scalarNode('content')->defaultNull()->end() |
294
|
49 |
|
->scalarNode('method')->defaultValue('GET')->end() |
295
|
49 |
|
->scalarNode('body')->defaultNull()->end() |
296
|
49 |
|
->end() |
297
|
49 |
|
->end() |
298
|
49 |
|
->end() |
299
|
49 |
|
->arrayNode('rabbit_mq') |
300
|
49 |
|
->info('Validate that a RabbitMQ service is running') |
301
|
49 |
|
->useAttributeAsKey('name') |
302
|
49 |
|
->beforeNormalization() |
303
|
49 |
|
->ifString() |
304
|
|
|
->then(function ($v) { return ['dsn' => $v]; }) |
305
|
49 |
|
->end() |
306
|
49 |
|
->prototype('array') |
307
|
49 |
|
->children() |
308
|
49 |
|
->scalarNode('host')->defaultValue('localhost')->end() |
309
|
49 |
|
->integerNode('port')->defaultValue(5672)->end() |
310
|
49 |
|
->scalarNode('user')->defaultValue('guest')->end() |
311
|
49 |
|
->scalarNode('password')->defaultValue('guest')->end() |
312
|
49 |
|
->scalarNode('vhost')->defaultValue('/')->end() |
313
|
49 |
|
->scalarNode('dsn')->defaultNull()->end() |
314
|
49 |
|
->end() |
315
|
49 |
|
->end() |
316
|
49 |
|
->end() |
317
|
49 |
|
->booleanNode('symfony_version') |
318
|
49 |
|
->info('Checks the version of this app against the latest stable release') |
319
|
49 |
|
->end() |
320
|
49 |
|
->arrayNode('custom_error_pages') |
321
|
49 |
|
->info('Checks if error pages have been customized for given error codes') |
322
|
49 |
|
->children() |
323
|
49 |
|
->arrayNode('error_codes') |
324
|
49 |
|
->isRequired() |
325
|
49 |
|
->requiresAtLeastOneElement() |
326
|
49 |
|
->prototype('scalar')->end() |
327
|
49 |
|
->end() |
328
|
49 |
|
->scalarNode('path')->defaultValue('%kernel.root_dir%')->end() |
329
|
49 |
|
->scalarNode('controller')->defaultValue('%twig.exception_listener.controller%')->end() |
330
|
49 |
|
->end() |
331
|
49 |
|
->end() |
332
|
49 |
|
->arrayNode('security_advisory') |
333
|
49 |
|
->info('Checks installed composer dependencies against the SensioLabs Security Advisory database') |
334
|
49 |
|
->children() |
335
|
49 |
|
->scalarNode('lock_file')->defaultValue('%kernel.root_dir%'.'/../composer.lock')->end() |
336
|
49 |
|
->end() |
337
|
49 |
|
->end() |
338
|
49 |
|
->arrayNode('stream_wrapper_exists') |
339
|
49 |
|
->info('Validate that a stream wrapper or collection of stream wrappers exists') |
340
|
49 |
|
->example('[\'zlib\', \'bzip2\', \'zip\']') |
341
|
49 |
|
->prototype('scalar')->end() |
342
|
49 |
|
->end() |
343
|
49 |
|
->arrayNode('file_ini') |
344
|
49 |
|
->info('Find and validate INI files') |
345
|
49 |
|
->example('[\'path/to/my.ini\']') |
346
|
49 |
|
->prototype('scalar')->end() |
347
|
49 |
|
->end() |
348
|
49 |
|
->arrayNode('file_json') |
349
|
49 |
|
->info('Find and validate JSON files') |
350
|
49 |
|
->example('[\'path/to/my.json\']') |
351
|
49 |
|
->prototype('scalar')->end() |
352
|
49 |
|
->end() |
353
|
49 |
|
->arrayNode('file_xml') |
354
|
49 |
|
->info('Find and validate XML files') |
355
|
49 |
|
->example('[\'path/to/my.xml\']') |
356
|
49 |
|
->prototype('scalar')->end() |
357
|
49 |
|
->end() |
358
|
49 |
|
->arrayNode('file_yaml') |
359
|
49 |
|
->info('Find and validate YAML files') |
360
|
49 |
|
->example('[\'path/to/my.yml\']') |
361
|
49 |
|
->prototype('scalar')->end() |
362
|
49 |
|
->end() |
363
|
49 |
|
->arrayNode('pdo_connections') |
364
|
49 |
|
->info('PDO connections to check for connection') |
365
|
49 |
|
->useAttributeAsKey('name') |
366
|
49 |
|
->prototype('array') |
367
|
49 |
|
->children() |
368
|
49 |
|
->scalarNode('dsn')->defaultNull()->end() |
369
|
49 |
|
->scalarNode('username')->defaultNull()->end() |
370
|
49 |
|
->scalarNode('password')->defaultNull()->end() |
371
|
49 |
|
->integerNode('timeout')->defaultValue(1)->end() |
372
|
49 |
|
->end() |
373
|
49 |
|
->end() |
374
|
49 |
|
->end() |
375
|
49 |
|
->arrayNode('expressions') |
376
|
49 |
|
->useAttributeAsKey('alias') |
377
|
49 |
|
->info('Checks that fail/warn when given expression is false (expressions are evaluated with symfony/expression-language)') |
378
|
49 |
|
->example([ |
379
|
|
|
'opcache' => [ |
380
|
49 |
|
'label' => 'OPcache', |
381
|
|
|
'warning_expression' => "ini('opcache.revalidate_freq') > 0", |
382
|
|
|
'critical_expression' => "ini('opcache.enable')", |
383
|
|
|
'warning_message' => 'OPcache not optimized for production', |
384
|
|
|
'critical_message' => 'OPcache not enabled', |
385
|
|
|
], |
386
|
|
|
]) |
387
|
49 |
|
->prototype('array') |
388
|
49 |
|
->addDefaultsIfNotSet() |
389
|
49 |
|
->validate() |
390
|
|
|
->ifTrue(function ($value) { |
391
|
2 |
|
return !$value['warning_expression'] && !$value['critical_expression']; |
392
|
49 |
|
}) |
393
|
49 |
|
->thenInvalid('A warning_expression or a critical_expression must be set.') |
394
|
49 |
|
->end() |
395
|
49 |
|
->children() |
396
|
49 |
|
->scalarNode('label')->isRequired()->end() |
397
|
49 |
|
->scalarNode('warning_expression') |
398
|
49 |
|
->defaultNull() |
399
|
49 |
|
->example('ini(\'apc.stat\') == 0') |
400
|
49 |
|
->end() |
401
|
49 |
|
->scalarNode('critical_expression') |
402
|
49 |
|
->defaultNull() |
403
|
49 |
|
->example('ini(\'short_open_tag\') == 1') |
404
|
49 |
|
->end() |
405
|
49 |
|
->scalarNode('warning_message')->defaultNull()->end() |
406
|
49 |
|
->scalarNode('critical_message')->defaultNull()->end() |
407
|
49 |
|
->end() |
408
|
49 |
|
->end() |
409
|
49 |
|
->end() |
410
|
|
|
; |
411
|
|
|
|
412
|
49 |
|
return $node; |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.