├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock └── src ├── Controller └── MetricsController.php ├── DependencyInjection ├── CollectorCompilerPass.php ├── Configuration.php ├── StorageAdapterCompilerPass.php └── TweedeGolfPrometheusExtension.php ├── Resources └── config │ ├── routing.yml │ └── services.yml └── TweedeGolfPrometheusBundle.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 tweede golf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TweedeGolfPrometheusBundle 2 | A Symfony bundle for the [tweede golf prometheus client]. For more information 3 | on Prometheus you can [check their website][prometheus]. 4 | 5 | ## Installation and configuration 6 | Using [Composer] add the bundle to your dependencies using the require command: 7 | 8 | composer require tweedegolf/prometheus-bundle 9 | 10 | ### Add the bundle to your AppKernel 11 | Add the bundle in your `app/AppKernel.php`: 12 | 13 | ```php 14 | public function registerBundles() 15 | { 16 | return array( 17 | // ... 18 | new TweedeGolf\PrometheusBundle\TweedeGolfPrometheusBundle(), 19 | // ... 20 | ); 21 | } 22 | ``` 23 | 24 | ### Configure storage, collectors and routes 25 | To allow prometheus to scrape your metrics from your application, make sure you 26 | make a route available for the prometheus metrics controller: 27 | 28 | ```yaml 29 | tweede_golf_prometheus: 30 | resource: "@TweedeGolfPrometheusBundle/Resources/config/routing.yml" 31 | prefix: / 32 | ``` 33 | 34 | You can also implement your own controller, take a look at the source code of 35 | `TweedeGolf\PrometheusBundle\Controller\MetricsController::metricsAction`. 36 | You can configure some aspects of the prometheus client using the configuration, 37 | the default values are shown below: 38 | 39 | ```yaml 40 | tweede_golf_prometheus: 41 | storage_adapter_service: TweedeGolf\PrometheusClient\Storage\ApcuAdapter 42 | metrics_path: /metrics 43 | make_memory_adapter: true 44 | register_defaults: true 45 | collectors: ~ 46 | ``` 47 | 48 | To adjust, create a section `tweede_golf_prometheus` in your `config.yml`. You 49 | may specify any number of collectors. An example where four different collectors 50 | are defined is shown below: 51 | 52 | ```yaml 53 | tweede_golf_prometheus: 54 | collectors: 55 | requests: 56 | counter: 57 | labels: [url] 58 | help: Number of requests 59 | throughput: 60 | gauge: 61 | labels: [url] 62 | help: Throughput per url 63 | initializer: 10.0 64 | response_timing: 65 | histogram: 66 | labels: [url] 67 | help: Response timings 68 | buckets: [0.1, 0.2, 0.3, 0.5, 0.7, 1, 2, 5, 10, 30, 60] 69 | shorthand_example: 70 | counter: ~ 71 | ``` 72 | 73 | ### Modifying (incrementing/observing/setting) metrics 74 | To modify a metric, retrieve it via the `CollectorRegistry` service and call 75 | one of the type specific metric modification methods. 76 | 77 | ```php 78 | use TweedeGolf\PrometheusClient\CollectorRegistry; 79 | 80 | public function exampleAction() 81 | { 82 | $metric = $this->get(CollectorRegistry::class)->getCounter('requests'); 83 | $metric->inc(); 84 | } 85 | ``` 86 | 87 | ### Register a collector service 88 | You can also register services as collectors with the collector registry. To 89 | do this, add a `tweede_golf_prometheus.collector` tag to your service and make 90 | sure the service implements the `CollectorInterface`. You can also use the 91 | factory methods of the registry service: 92 | 93 | ```yaml 94 | services: 95 | example.collector.test: 96 | class: TweedeGolf\PrometheusClient\Collector\Counter 97 | factory: TweedeGolf\PrometheusClient\CollectorRegistry:createCounter 98 | arguments: [test] 99 | tags: [tweede_golf_prometheus.collector] 100 | ``` 101 | 102 | [tweede golf prometheus client]: https://github.com/tweedegolf/prometheus-client 103 | [prometheus]: https://prometheus.io 104 | [Composer]: https://getcomposer.org 105 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweedegolf/prometheus-bundle", 3 | "description": "Symfony bundle for Prometheus client", 4 | "license": "MIT", 5 | "autoload": { 6 | "psr-4": { 7 | "TweedeGolf\\PrometheusBundle\\": "src/" 8 | } 9 | }, 10 | "authors": [ 11 | { 12 | "name": "Ruben Nijveld", 13 | "email": "ruben@tweedegolf.com" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=7.1.3", 18 | "tweedegolf/prometheus-client": "^0.4", 19 | "symfony/config": "~2.7|~3.0|~4.0|~5.0|~6.0", 20 | "symfony/dependency-injection": "~2.7|~3.0|~4.0|~5.0|~6.0", 21 | "symfony/framework-bundle": "~2.7|~3.0|~4.0|~5.0|~6.0", 22 | "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0|~6.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b5f329fdc5972f6d3804df4af8dc192e", 8 | "packages": [ 9 | { 10 | "name": "psr/cache", 11 | "version": "1.0.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/php-fig/cache.git", 15 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", 20 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.3.0" 25 | }, 26 | "type": "library", 27 | "extra": { 28 | "branch-alias": { 29 | "dev-master": "1.0.x-dev" 30 | } 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "Psr\\Cache\\": "src/" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "MIT" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "PHP-FIG", 44 | "homepage": "http://www.php-fig.org/" 45 | } 46 | ], 47 | "description": "Common interface for caching libraries", 48 | "keywords": [ 49 | "cache", 50 | "psr", 51 | "psr-6" 52 | ], 53 | "time": "2016-08-06T20:24:11+00:00" 54 | }, 55 | { 56 | "name": "psr/container", 57 | "version": "1.0.0", 58 | "source": { 59 | "type": "git", 60 | "url": "https://github.com/php-fig/container.git", 61 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 62 | }, 63 | "dist": { 64 | "type": "zip", 65 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 66 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 67 | "shasum": "" 68 | }, 69 | "require": { 70 | "php": ">=5.3.0" 71 | }, 72 | "type": "library", 73 | "extra": { 74 | "branch-alias": { 75 | "dev-master": "1.0.x-dev" 76 | } 77 | }, 78 | "autoload": { 79 | "psr-4": { 80 | "Psr\\Container\\": "src/" 81 | } 82 | }, 83 | "notification-url": "https://packagist.org/downloads/", 84 | "license": [ 85 | "MIT" 86 | ], 87 | "authors": [ 88 | { 89 | "name": "PHP-FIG", 90 | "homepage": "http://www.php-fig.org/" 91 | } 92 | ], 93 | "description": "Common Container Interface (PHP FIG PSR-11)", 94 | "homepage": "https://github.com/php-fig/container", 95 | "keywords": [ 96 | "PSR-11", 97 | "container", 98 | "container-interface", 99 | "container-interop", 100 | "psr" 101 | ], 102 | "time": "2017-02-14T16:28:37+00:00" 103 | }, 104 | { 105 | "name": "psr/event-dispatcher", 106 | "version": "1.0.0", 107 | "source": { 108 | "type": "git", 109 | "url": "https://github.com/php-fig/event-dispatcher.git", 110 | "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" 111 | }, 112 | "dist": { 113 | "type": "zip", 114 | "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", 115 | "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", 116 | "shasum": "" 117 | }, 118 | "require": { 119 | "php": ">=7.2.0" 120 | }, 121 | "type": "library", 122 | "extra": { 123 | "branch-alias": { 124 | "dev-master": "1.0.x-dev" 125 | } 126 | }, 127 | "autoload": { 128 | "psr-4": { 129 | "Psr\\EventDispatcher\\": "src/" 130 | } 131 | }, 132 | "notification-url": "https://packagist.org/downloads/", 133 | "license": [ 134 | "MIT" 135 | ], 136 | "authors": [ 137 | { 138 | "name": "PHP-FIG", 139 | "homepage": "http://www.php-fig.org/" 140 | } 141 | ], 142 | "description": "Standard interfaces for event handling.", 143 | "keywords": [ 144 | "events", 145 | "psr", 146 | "psr-14" 147 | ], 148 | "time": "2019-01-08T18:20:26+00:00" 149 | }, 150 | { 151 | "name": "psr/log", 152 | "version": "1.1.3", 153 | "source": { 154 | "type": "git", 155 | "url": "https://github.com/php-fig/log.git", 156 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" 157 | }, 158 | "dist": { 159 | "type": "zip", 160 | "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", 161 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", 162 | "shasum": "" 163 | }, 164 | "require": { 165 | "php": ">=5.3.0" 166 | }, 167 | "type": "library", 168 | "extra": { 169 | "branch-alias": { 170 | "dev-master": "1.1.x-dev" 171 | } 172 | }, 173 | "autoload": { 174 | "psr-4": { 175 | "Psr\\Log\\": "Psr/Log/" 176 | } 177 | }, 178 | "notification-url": "https://packagist.org/downloads/", 179 | "license": [ 180 | "MIT" 181 | ], 182 | "authors": [ 183 | { 184 | "name": "PHP-FIG", 185 | "homepage": "http://www.php-fig.org/" 186 | } 187 | ], 188 | "description": "Common interface for logging libraries", 189 | "homepage": "https://github.com/php-fig/log", 190 | "keywords": [ 191 | "log", 192 | "psr", 193 | "psr-3" 194 | ], 195 | "time": "2020-03-23T09:12:05+00:00" 196 | }, 197 | { 198 | "name": "symfony/cache", 199 | "version": "v5.2.0", 200 | "source": { 201 | "type": "git", 202 | "url": "https://github.com/symfony/cache.git", 203 | "reference": "c15fd2b3dcf2bd7d5ee3265874870d6cc694306b" 204 | }, 205 | "dist": { 206 | "type": "zip", 207 | "url": "https://api.github.com/repos/symfony/cache/zipball/c15fd2b3dcf2bd7d5ee3265874870d6cc694306b", 208 | "reference": "c15fd2b3dcf2bd7d5ee3265874870d6cc694306b", 209 | "shasum": "" 210 | }, 211 | "require": { 212 | "php": ">=7.2.5", 213 | "psr/cache": "~1.0", 214 | "psr/log": "^1.1", 215 | "symfony/cache-contracts": "^1.1.7|^2", 216 | "symfony/polyfill-php80": "^1.15", 217 | "symfony/service-contracts": "^1.1|^2", 218 | "symfony/var-exporter": "^4.4|^5.0" 219 | }, 220 | "conflict": { 221 | "doctrine/dbal": "<2.10", 222 | "symfony/dependency-injection": "<4.4", 223 | "symfony/http-kernel": "<4.4", 224 | "symfony/var-dumper": "<4.4" 225 | }, 226 | "provide": { 227 | "psr/cache-implementation": "1.0", 228 | "psr/simple-cache-implementation": "1.0", 229 | "symfony/cache-implementation": "1.0" 230 | }, 231 | "require-dev": { 232 | "cache/integration-tests": "dev-master", 233 | "doctrine/cache": "^1.6", 234 | "doctrine/dbal": "^2.10|^3.0", 235 | "predis/predis": "^1.1", 236 | "psr/simple-cache": "^1.0", 237 | "symfony/config": "^4.4|^5.0", 238 | "symfony/dependency-injection": "^4.4|^5.0", 239 | "symfony/filesystem": "^4.4|^5.0", 240 | "symfony/http-kernel": "^4.4|^5.0", 241 | "symfony/messenger": "^4.4|^5.0", 242 | "symfony/var-dumper": "^4.4|^5.0" 243 | }, 244 | "type": "library", 245 | "autoload": { 246 | "psr-4": { 247 | "Symfony\\Component\\Cache\\": "" 248 | }, 249 | "exclude-from-classmap": [ 250 | "/Tests/" 251 | ] 252 | }, 253 | "notification-url": "https://packagist.org/downloads/", 254 | "license": [ 255 | "MIT" 256 | ], 257 | "authors": [ 258 | { 259 | "name": "Nicolas Grekas", 260 | "email": "p@tchwork.com" 261 | }, 262 | { 263 | "name": "Symfony Community", 264 | "homepage": "https://symfony.com/contributors" 265 | } 266 | ], 267 | "description": "Symfony Cache component with PSR-6, PSR-16, and tags", 268 | "homepage": "https://symfony.com", 269 | "keywords": [ 270 | "caching", 271 | "psr6" 272 | ], 273 | "time": "2020-11-21T09:39:55+00:00" 274 | }, 275 | { 276 | "name": "symfony/cache-contracts", 277 | "version": "v2.2.0", 278 | "source": { 279 | "type": "git", 280 | "url": "https://github.com/symfony/cache-contracts.git", 281 | "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb" 282 | }, 283 | "dist": { 284 | "type": "zip", 285 | "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8034ca0b61d4dd967f3698aaa1da2507b631d0cb", 286 | "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb", 287 | "shasum": "" 288 | }, 289 | "require": { 290 | "php": ">=7.2.5", 291 | "psr/cache": "^1.0" 292 | }, 293 | "suggest": { 294 | "symfony/cache-implementation": "" 295 | }, 296 | "type": "library", 297 | "extra": { 298 | "branch-alias": { 299 | "dev-master": "2.2-dev" 300 | }, 301 | "thanks": { 302 | "name": "symfony/contracts", 303 | "url": "https://github.com/symfony/contracts" 304 | } 305 | }, 306 | "autoload": { 307 | "psr-4": { 308 | "Symfony\\Contracts\\Cache\\": "" 309 | } 310 | }, 311 | "notification-url": "https://packagist.org/downloads/", 312 | "license": [ 313 | "MIT" 314 | ], 315 | "authors": [ 316 | { 317 | "name": "Nicolas Grekas", 318 | "email": "p@tchwork.com" 319 | }, 320 | { 321 | "name": "Symfony Community", 322 | "homepage": "https://symfony.com/contributors" 323 | } 324 | ], 325 | "description": "Generic abstractions related to caching", 326 | "homepage": "https://symfony.com", 327 | "keywords": [ 328 | "abstractions", 329 | "contracts", 330 | "decoupling", 331 | "interfaces", 332 | "interoperability", 333 | "standards" 334 | ], 335 | "time": "2020-09-07T11:33:47+00:00" 336 | }, 337 | { 338 | "name": "symfony/config", 339 | "version": "v5.4.3", 340 | "source": { 341 | "type": "git", 342 | "url": "https://github.com/symfony/config.git", 343 | "reference": "d65e1bd990c740e31feb07d2b0927b8d4df9956f" 344 | }, 345 | "dist": { 346 | "type": "zip", 347 | "url": "https://api.github.com/repos/symfony/config/zipball/d65e1bd990c740e31feb07d2b0927b8d4df9956f", 348 | "reference": "d65e1bd990c740e31feb07d2b0927b8d4df9956f", 349 | "shasum": "" 350 | }, 351 | "require": { 352 | "php": ">=7.2.5", 353 | "symfony/deprecation-contracts": "^2.1|^3", 354 | "symfony/filesystem": "^4.4|^5.0|^6.0", 355 | "symfony/polyfill-ctype": "~1.8", 356 | "symfony/polyfill-php80": "^1.16", 357 | "symfony/polyfill-php81": "^1.22" 358 | }, 359 | "conflict": { 360 | "symfony/finder": "<4.4" 361 | }, 362 | "require-dev": { 363 | "symfony/event-dispatcher": "^4.4|^5.0|^6.0", 364 | "symfony/finder": "^4.4|^5.0|^6.0", 365 | "symfony/messenger": "^4.4|^5.0|^6.0", 366 | "symfony/service-contracts": "^1.1|^2|^3", 367 | "symfony/yaml": "^4.4|^5.0|^6.0" 368 | }, 369 | "suggest": { 370 | "symfony/yaml": "To use the yaml reference dumper" 371 | }, 372 | "type": "library", 373 | "autoload": { 374 | "psr-4": { 375 | "Symfony\\Component\\Config\\": "" 376 | }, 377 | "exclude-from-classmap": [ 378 | "/Tests/" 379 | ] 380 | }, 381 | "notification-url": "https://packagist.org/downloads/", 382 | "license": [ 383 | "MIT" 384 | ], 385 | "authors": [ 386 | { 387 | "name": "Fabien Potencier", 388 | "email": "fabien@symfony.com" 389 | }, 390 | { 391 | "name": "Symfony Community", 392 | "homepage": "https://symfony.com/contributors" 393 | } 394 | ], 395 | "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", 396 | "homepage": "https://symfony.com", 397 | "support": { 398 | "source": "https://github.com/symfony/config/tree/v5.4.3" 399 | }, 400 | "funding": [ 401 | { 402 | "url": "https://symfony.com/sponsor", 403 | "type": "custom" 404 | }, 405 | { 406 | "url": "https://github.com/fabpot", 407 | "type": "github" 408 | }, 409 | { 410 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 411 | "type": "tidelift" 412 | } 413 | ], 414 | "time": "2022-01-03T09:50:52+00:00" 415 | }, 416 | { 417 | "name": "symfony/dependency-injection", 418 | "version": "v5.2.12", 419 | "source": { 420 | "type": "git", 421 | "url": "https://github.com/symfony/dependency-injection.git", 422 | "reference": "2f0326ab0e142a3600b1b435cb3e852bc96264b6" 423 | }, 424 | "dist": { 425 | "type": "zip", 426 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2f0326ab0e142a3600b1b435cb3e852bc96264b6", 427 | "reference": "2f0326ab0e142a3600b1b435cb3e852bc96264b6", 428 | "shasum": "" 429 | }, 430 | "require": { 431 | "php": ">=7.2.5", 432 | "psr/container": "^1.0", 433 | "symfony/deprecation-contracts": "^2.1", 434 | "symfony/polyfill-php80": "^1.16", 435 | "symfony/service-contracts": "^1.1.6|^2" 436 | }, 437 | "conflict": { 438 | "symfony/config": "<5.1", 439 | "symfony/finder": "<4.4", 440 | "symfony/proxy-manager-bridge": "<4.4", 441 | "symfony/yaml": "<4.4" 442 | }, 443 | "provide": { 444 | "psr/container-implementation": "1.0", 445 | "symfony/service-implementation": "1.0|2.0" 446 | }, 447 | "require-dev": { 448 | "symfony/config": "^5.1", 449 | "symfony/expression-language": "^4.4|^5.0", 450 | "symfony/yaml": "^4.4|^5.0" 451 | }, 452 | "suggest": { 453 | "symfony/config": "", 454 | "symfony/expression-language": "For using expressions in service container configuration", 455 | "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", 456 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 457 | "symfony/yaml": "" 458 | }, 459 | "type": "library", 460 | "autoload": { 461 | "psr-4": { 462 | "Symfony\\Component\\DependencyInjection\\": "" 463 | }, 464 | "exclude-from-classmap": [ 465 | "/Tests/" 466 | ] 467 | }, 468 | "notification-url": "https://packagist.org/downloads/", 469 | "license": [ 470 | "MIT" 471 | ], 472 | "authors": [ 473 | { 474 | "name": "Fabien Potencier", 475 | "email": "fabien@symfony.com" 476 | }, 477 | { 478 | "name": "Symfony Community", 479 | "homepage": "https://symfony.com/contributors" 480 | } 481 | ], 482 | "description": "Allows you to standardize and centralize the way objects are constructed in your application", 483 | "homepage": "https://symfony.com", 484 | "support": { 485 | "source": "https://github.com/symfony/dependency-injection/tree/v5.2.12" 486 | }, 487 | "funding": [ 488 | { 489 | "url": "https://symfony.com/sponsor", 490 | "type": "custom" 491 | }, 492 | { 493 | "url": "https://github.com/fabpot", 494 | "type": "github" 495 | }, 496 | { 497 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 498 | "type": "tidelift" 499 | } 500 | ], 501 | "time": "2021-07-23T15:54:19+00:00" 502 | }, 503 | { 504 | "name": "symfony/deprecation-contracts", 505 | "version": "v2.2.0", 506 | "source": { 507 | "type": "git", 508 | "url": "https://github.com/symfony/deprecation-contracts.git", 509 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" 510 | }, 511 | "dist": { 512 | "type": "zip", 513 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", 514 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", 515 | "shasum": "" 516 | }, 517 | "require": { 518 | "php": ">=7.1" 519 | }, 520 | "type": "library", 521 | "extra": { 522 | "branch-alias": { 523 | "dev-master": "2.2-dev" 524 | }, 525 | "thanks": { 526 | "name": "symfony/contracts", 527 | "url": "https://github.com/symfony/contracts" 528 | } 529 | }, 530 | "autoload": { 531 | "files": [ 532 | "function.php" 533 | ] 534 | }, 535 | "notification-url": "https://packagist.org/downloads/", 536 | "license": [ 537 | "MIT" 538 | ], 539 | "authors": [ 540 | { 541 | "name": "Nicolas Grekas", 542 | "email": "p@tchwork.com" 543 | }, 544 | { 545 | "name": "Symfony Community", 546 | "homepage": "https://symfony.com/contributors" 547 | } 548 | ], 549 | "description": "A generic function and convention to trigger deprecation notices", 550 | "homepage": "https://symfony.com", 551 | "time": "2020-09-07T11:33:47+00:00" 552 | }, 553 | { 554 | "name": "symfony/error-handler", 555 | "version": "v5.2.0", 556 | "source": { 557 | "type": "git", 558 | "url": "https://github.com/symfony/error-handler.git", 559 | "reference": "289008c5be039e39908d33ae0a8ac99be1210bba" 560 | }, 561 | "dist": { 562 | "type": "zip", 563 | "url": "https://api.github.com/repos/symfony/error-handler/zipball/289008c5be039e39908d33ae0a8ac99be1210bba", 564 | "reference": "289008c5be039e39908d33ae0a8ac99be1210bba", 565 | "shasum": "" 566 | }, 567 | "require": { 568 | "php": ">=7.2.5", 569 | "psr/log": "^1.0", 570 | "symfony/polyfill-php80": "^1.15", 571 | "symfony/var-dumper": "^4.4|^5.0" 572 | }, 573 | "require-dev": { 574 | "symfony/deprecation-contracts": "^2.1", 575 | "symfony/http-kernel": "^4.4|^5.0", 576 | "symfony/serializer": "^4.4|^5.0" 577 | }, 578 | "type": "library", 579 | "autoload": { 580 | "psr-4": { 581 | "Symfony\\Component\\ErrorHandler\\": "" 582 | }, 583 | "exclude-from-classmap": [ 584 | "/Tests/" 585 | ] 586 | }, 587 | "notification-url": "https://packagist.org/downloads/", 588 | "license": [ 589 | "MIT" 590 | ], 591 | "authors": [ 592 | { 593 | "name": "Fabien Potencier", 594 | "email": "fabien@symfony.com" 595 | }, 596 | { 597 | "name": "Symfony Community", 598 | "homepage": "https://symfony.com/contributors" 599 | } 600 | ], 601 | "description": "Symfony ErrorHandler Component", 602 | "homepage": "https://symfony.com", 603 | "time": "2020-10-28T21:46:03+00:00" 604 | }, 605 | { 606 | "name": "symfony/event-dispatcher", 607 | "version": "v5.2.0", 608 | "source": { 609 | "type": "git", 610 | "url": "https://github.com/symfony/event-dispatcher.git", 611 | "reference": "aa13a09811e6d2ad43f8fb336bebdb7691d85d3c" 612 | }, 613 | "dist": { 614 | "type": "zip", 615 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/aa13a09811e6d2ad43f8fb336bebdb7691d85d3c", 616 | "reference": "aa13a09811e6d2ad43f8fb336bebdb7691d85d3c", 617 | "shasum": "" 618 | }, 619 | "require": { 620 | "php": ">=7.2.5", 621 | "symfony/deprecation-contracts": "^2.1", 622 | "symfony/event-dispatcher-contracts": "^2", 623 | "symfony/polyfill-php80": "^1.15" 624 | }, 625 | "conflict": { 626 | "symfony/dependency-injection": "<4.4" 627 | }, 628 | "provide": { 629 | "psr/event-dispatcher-implementation": "1.0", 630 | "symfony/event-dispatcher-implementation": "2.0" 631 | }, 632 | "require-dev": { 633 | "psr/log": "~1.0", 634 | "symfony/config": "^4.4|^5.0", 635 | "symfony/dependency-injection": "^4.4|^5.0", 636 | "symfony/error-handler": "^4.4|^5.0", 637 | "symfony/expression-language": "^4.4|^5.0", 638 | "symfony/http-foundation": "^4.4|^5.0", 639 | "symfony/service-contracts": "^1.1|^2", 640 | "symfony/stopwatch": "^4.4|^5.0" 641 | }, 642 | "suggest": { 643 | "symfony/dependency-injection": "", 644 | "symfony/http-kernel": "" 645 | }, 646 | "type": "library", 647 | "autoload": { 648 | "psr-4": { 649 | "Symfony\\Component\\EventDispatcher\\": "" 650 | }, 651 | "exclude-from-classmap": [ 652 | "/Tests/" 653 | ] 654 | }, 655 | "notification-url": "https://packagist.org/downloads/", 656 | "license": [ 657 | "MIT" 658 | ], 659 | "authors": [ 660 | { 661 | "name": "Fabien Potencier", 662 | "email": "fabien@symfony.com" 663 | }, 664 | { 665 | "name": "Symfony Community", 666 | "homepage": "https://symfony.com/contributors" 667 | } 668 | ], 669 | "description": "Symfony EventDispatcher Component", 670 | "homepage": "https://symfony.com", 671 | "time": "2020-11-01T16:14:45+00:00" 672 | }, 673 | { 674 | "name": "symfony/event-dispatcher-contracts", 675 | "version": "v2.2.0", 676 | "source": { 677 | "type": "git", 678 | "url": "https://github.com/symfony/event-dispatcher-contracts.git", 679 | "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" 680 | }, 681 | "dist": { 682 | "type": "zip", 683 | "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", 684 | "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", 685 | "shasum": "" 686 | }, 687 | "require": { 688 | "php": ">=7.2.5", 689 | "psr/event-dispatcher": "^1" 690 | }, 691 | "suggest": { 692 | "symfony/event-dispatcher-implementation": "" 693 | }, 694 | "type": "library", 695 | "extra": { 696 | "branch-alias": { 697 | "dev-master": "2.2-dev" 698 | }, 699 | "thanks": { 700 | "name": "symfony/contracts", 701 | "url": "https://github.com/symfony/contracts" 702 | } 703 | }, 704 | "autoload": { 705 | "psr-4": { 706 | "Symfony\\Contracts\\EventDispatcher\\": "" 707 | } 708 | }, 709 | "notification-url": "https://packagist.org/downloads/", 710 | "license": [ 711 | "MIT" 712 | ], 713 | "authors": [ 714 | { 715 | "name": "Nicolas Grekas", 716 | "email": "p@tchwork.com" 717 | }, 718 | { 719 | "name": "Symfony Community", 720 | "homepage": "https://symfony.com/contributors" 721 | } 722 | ], 723 | "description": "Generic abstractions related to dispatching event", 724 | "homepage": "https://symfony.com", 725 | "keywords": [ 726 | "abstractions", 727 | "contracts", 728 | "decoupling", 729 | "interfaces", 730 | "interoperability", 731 | "standards" 732 | ], 733 | "time": "2020-09-07T11:33:47+00:00" 734 | }, 735 | { 736 | "name": "symfony/filesystem", 737 | "version": "v5.2.0", 738 | "source": { 739 | "type": "git", 740 | "url": "https://github.com/symfony/filesystem.git", 741 | "reference": "bb92ba7f38b037e531908590a858a04d85c0e238" 742 | }, 743 | "dist": { 744 | "type": "zip", 745 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/bb92ba7f38b037e531908590a858a04d85c0e238", 746 | "reference": "bb92ba7f38b037e531908590a858a04d85c0e238", 747 | "shasum": "" 748 | }, 749 | "require": { 750 | "php": ">=7.2.5", 751 | "symfony/polyfill-ctype": "~1.8" 752 | }, 753 | "type": "library", 754 | "autoload": { 755 | "psr-4": { 756 | "Symfony\\Component\\Filesystem\\": "" 757 | }, 758 | "exclude-from-classmap": [ 759 | "/Tests/" 760 | ] 761 | }, 762 | "notification-url": "https://packagist.org/downloads/", 763 | "license": [ 764 | "MIT" 765 | ], 766 | "authors": [ 767 | { 768 | "name": "Fabien Potencier", 769 | "email": "fabien@symfony.com" 770 | }, 771 | { 772 | "name": "Symfony Community", 773 | "homepage": "https://symfony.com/contributors" 774 | } 775 | ], 776 | "description": "Symfony Filesystem Component", 777 | "homepage": "https://symfony.com", 778 | "time": "2020-11-12T09:58:18+00:00" 779 | }, 780 | { 781 | "name": "symfony/finder", 782 | "version": "v5.2.0", 783 | "source": { 784 | "type": "git", 785 | "url": "https://github.com/symfony/finder.git", 786 | "reference": "fd8305521692f27eae3263895d1ef1571c71a78d" 787 | }, 788 | "dist": { 789 | "type": "zip", 790 | "url": "https://api.github.com/repos/symfony/finder/zipball/fd8305521692f27eae3263895d1ef1571c71a78d", 791 | "reference": "fd8305521692f27eae3263895d1ef1571c71a78d", 792 | "shasum": "" 793 | }, 794 | "require": { 795 | "php": ">=7.2.5" 796 | }, 797 | "type": "library", 798 | "autoload": { 799 | "psr-4": { 800 | "Symfony\\Component\\Finder\\": "" 801 | }, 802 | "exclude-from-classmap": [ 803 | "/Tests/" 804 | ] 805 | }, 806 | "notification-url": "https://packagist.org/downloads/", 807 | "license": [ 808 | "MIT" 809 | ], 810 | "authors": [ 811 | { 812 | "name": "Fabien Potencier", 813 | "email": "fabien@symfony.com" 814 | }, 815 | { 816 | "name": "Symfony Community", 817 | "homepage": "https://symfony.com/contributors" 818 | } 819 | ], 820 | "description": "Symfony Finder Component", 821 | "homepage": "https://symfony.com", 822 | "time": "2020-11-18T09:42:36+00:00" 823 | }, 824 | { 825 | "name": "symfony/framework-bundle", 826 | "version": "v5.2.0", 827 | "source": { 828 | "type": "git", 829 | "url": "https://github.com/symfony/framework-bundle.git", 830 | "reference": "c5eedac1a2a07419d1d35f81a6b63cfccd91ea1d" 831 | }, 832 | "dist": { 833 | "type": "zip", 834 | "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c5eedac1a2a07419d1d35f81a6b63cfccd91ea1d", 835 | "reference": "c5eedac1a2a07419d1d35f81a6b63cfccd91ea1d", 836 | "shasum": "" 837 | }, 838 | "require": { 839 | "ext-xml": "*", 840 | "php": ">=7.2.5", 841 | "symfony/cache": "^5.2", 842 | "symfony/config": "^5.0", 843 | "symfony/dependency-injection": "^5.2", 844 | "symfony/error-handler": "^4.4.1|^5.0.1", 845 | "symfony/event-dispatcher": "^5.1", 846 | "symfony/filesystem": "^4.4|^5.0", 847 | "symfony/finder": "^4.4|^5.0", 848 | "symfony/http-foundation": "^5.2", 849 | "symfony/http-kernel": "^5.2", 850 | "symfony/polyfill-mbstring": "~1.0", 851 | "symfony/polyfill-php80": "^1.15", 852 | "symfony/routing": "^5.2" 853 | }, 854 | "conflict": { 855 | "doctrine/persistence": "<1.3", 856 | "phpdocumentor/reflection-docblock": "<3.0", 857 | "phpdocumentor/type-resolver": "<0.2.1", 858 | "phpunit/phpunit": "<5.4.3", 859 | "symfony/asset": "<5.1", 860 | "symfony/browser-kit": "<4.4", 861 | "symfony/console": "<5.2", 862 | "symfony/dom-crawler": "<4.4", 863 | "symfony/dotenv": "<5.1", 864 | "symfony/form": "<5.2", 865 | "symfony/http-client": "<4.4", 866 | "symfony/lock": "<4.4", 867 | "symfony/mailer": "<5.2", 868 | "symfony/messenger": "<4.4", 869 | "symfony/mime": "<4.4", 870 | "symfony/property-access": "<5.2", 871 | "symfony/property-info": "<4.4", 872 | "symfony/serializer": "<5.2", 873 | "symfony/stopwatch": "<4.4", 874 | "symfony/translation": "<5.0", 875 | "symfony/twig-bridge": "<4.4", 876 | "symfony/twig-bundle": "<4.4", 877 | "symfony/validator": "<5.2", 878 | "symfony/web-profiler-bundle": "<4.4", 879 | "symfony/workflow": "<5.2" 880 | }, 881 | "require-dev": { 882 | "doctrine/annotations": "~1.7", 883 | "doctrine/cache": "~1.0", 884 | "paragonie/sodium_compat": "^1.8", 885 | "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", 886 | "symfony/asset": "^5.1", 887 | "symfony/browser-kit": "^4.4|^5.0", 888 | "symfony/console": "^5.2", 889 | "symfony/css-selector": "^4.4|^5.0", 890 | "symfony/dom-crawler": "^4.4|^5.0", 891 | "symfony/dotenv": "^5.1", 892 | "symfony/expression-language": "^4.4|^5.0", 893 | "symfony/form": "^5.2", 894 | "symfony/http-client": "^4.4|^5.0", 895 | "symfony/lock": "^4.4|^5.0", 896 | "symfony/mailer": "^5.2", 897 | "symfony/messenger": "^5.2", 898 | "symfony/mime": "^4.4|^5.0", 899 | "symfony/polyfill-intl-icu": "~1.0", 900 | "symfony/process": "^4.4|^5.0", 901 | "symfony/property-info": "^4.4|^5.0", 902 | "symfony/security-bundle": "^5.1", 903 | "symfony/security-csrf": "^4.4|^5.0", 904 | "symfony/security-http": "^4.4|^5.0", 905 | "symfony/serializer": "^5.2", 906 | "symfony/stopwatch": "^4.4|^5.0", 907 | "symfony/string": "^5.0", 908 | "symfony/translation": "^5.0", 909 | "symfony/twig-bundle": "^4.4|^5.0", 910 | "symfony/validator": "^5.2", 911 | "symfony/web-link": "^4.4|^5.0", 912 | "symfony/workflow": "^5.2", 913 | "symfony/yaml": "^4.4|^5.0", 914 | "twig/twig": "^2.10|^3.0" 915 | }, 916 | "suggest": { 917 | "ext-apcu": "For best performance of the system caches", 918 | "symfony/console": "For using the console commands", 919 | "symfony/form": "For using forms", 920 | "symfony/property-info": "For using the property_info service", 921 | "symfony/serializer": "For using the serializer service", 922 | "symfony/validator": "For using validation", 923 | "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", 924 | "symfony/yaml": "For using the debug:config and lint:yaml commands" 925 | }, 926 | "type": "symfony-bundle", 927 | "autoload": { 928 | "psr-4": { 929 | "Symfony\\Bundle\\FrameworkBundle\\": "" 930 | }, 931 | "exclude-from-classmap": [ 932 | "/Tests/" 933 | ] 934 | }, 935 | "notification-url": "https://packagist.org/downloads/", 936 | "license": [ 937 | "MIT" 938 | ], 939 | "authors": [ 940 | { 941 | "name": "Fabien Potencier", 942 | "email": "fabien@symfony.com" 943 | }, 944 | { 945 | "name": "Symfony Community", 946 | "homepage": "https://symfony.com/contributors" 947 | } 948 | ], 949 | "description": "Symfony FrameworkBundle", 950 | "homepage": "https://symfony.com", 951 | "support": { 952 | "source": "https://github.com/symfony/framework-bundle/tree/v5.2.0" 953 | }, 954 | "funding": [ 955 | { 956 | "url": "https://symfony.com/sponsor", 957 | "type": "custom" 958 | }, 959 | { 960 | "url": "https://github.com/fabpot", 961 | "type": "github" 962 | }, 963 | { 964 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 965 | "type": "tidelift" 966 | } 967 | ], 968 | "time": "2020-11-28T11:24:18+00:00" 969 | }, 970 | { 971 | "name": "symfony/http-client-contracts", 972 | "version": "v2.3.1", 973 | "source": { 974 | "type": "git", 975 | "url": "https://github.com/symfony/http-client-contracts.git", 976 | "reference": "41db680a15018f9c1d4b23516059633ce280ca33" 977 | }, 978 | "dist": { 979 | "type": "zip", 980 | "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33", 981 | "reference": "41db680a15018f9c1d4b23516059633ce280ca33", 982 | "shasum": "" 983 | }, 984 | "require": { 985 | "php": ">=7.2.5" 986 | }, 987 | "suggest": { 988 | "symfony/http-client-implementation": "" 989 | }, 990 | "type": "library", 991 | "extra": { 992 | "branch-version": "2.3", 993 | "branch-alias": { 994 | "dev-main": "2.3-dev" 995 | }, 996 | "thanks": { 997 | "name": "symfony/contracts", 998 | "url": "https://github.com/symfony/contracts" 999 | } 1000 | }, 1001 | "autoload": { 1002 | "psr-4": { 1003 | "Symfony\\Contracts\\HttpClient\\": "" 1004 | } 1005 | }, 1006 | "notification-url": "https://packagist.org/downloads/", 1007 | "license": [ 1008 | "MIT" 1009 | ], 1010 | "authors": [ 1011 | { 1012 | "name": "Nicolas Grekas", 1013 | "email": "p@tchwork.com" 1014 | }, 1015 | { 1016 | "name": "Symfony Community", 1017 | "homepage": "https://symfony.com/contributors" 1018 | } 1019 | ], 1020 | "description": "Generic abstractions related to HTTP clients", 1021 | "homepage": "https://symfony.com", 1022 | "keywords": [ 1023 | "abstractions", 1024 | "contracts", 1025 | "decoupling", 1026 | "interfaces", 1027 | "interoperability", 1028 | "standards" 1029 | ], 1030 | "time": "2020-10-14T17:08:19+00:00" 1031 | }, 1032 | { 1033 | "name": "symfony/http-foundation", 1034 | "version": "v5.2.0", 1035 | "source": { 1036 | "type": "git", 1037 | "url": "https://github.com/symfony/http-foundation.git", 1038 | "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6" 1039 | }, 1040 | "dist": { 1041 | "type": "zip", 1042 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e4576271ee99123aa59a40564c7b5405f0ebd1e6", 1043 | "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6", 1044 | "shasum": "" 1045 | }, 1046 | "require": { 1047 | "php": ">=7.2.5", 1048 | "symfony/deprecation-contracts": "^2.1", 1049 | "symfony/polyfill-mbstring": "~1.1", 1050 | "symfony/polyfill-php80": "^1.15" 1051 | }, 1052 | "require-dev": { 1053 | "predis/predis": "~1.0", 1054 | "symfony/cache": "^4.4|^5.0", 1055 | "symfony/expression-language": "^4.4|^5.0", 1056 | "symfony/mime": "^4.4|^5.0" 1057 | }, 1058 | "suggest": { 1059 | "symfony/mime": "To use the file extension guesser" 1060 | }, 1061 | "type": "library", 1062 | "autoload": { 1063 | "psr-4": { 1064 | "Symfony\\Component\\HttpFoundation\\": "" 1065 | }, 1066 | "exclude-from-classmap": [ 1067 | "/Tests/" 1068 | ] 1069 | }, 1070 | "notification-url": "https://packagist.org/downloads/", 1071 | "license": [ 1072 | "MIT" 1073 | ], 1074 | "authors": [ 1075 | { 1076 | "name": "Fabien Potencier", 1077 | "email": "fabien@symfony.com" 1078 | }, 1079 | { 1080 | "name": "Symfony Community", 1081 | "homepage": "https://symfony.com/contributors" 1082 | } 1083 | ], 1084 | "description": "Symfony HttpFoundation Component", 1085 | "homepage": "https://symfony.com", 1086 | "time": "2020-11-27T06:13:25+00:00" 1087 | }, 1088 | { 1089 | "name": "symfony/http-kernel", 1090 | "version": "v5.2.14", 1091 | "source": { 1092 | "type": "git", 1093 | "url": "https://github.com/symfony/http-kernel.git", 1094 | "reference": "2c3b9af1047c477c527504a3509ab59e4fae0689" 1095 | }, 1096 | "dist": { 1097 | "type": "zip", 1098 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2c3b9af1047c477c527504a3509ab59e4fae0689", 1099 | "reference": "2c3b9af1047c477c527504a3509ab59e4fae0689", 1100 | "shasum": "" 1101 | }, 1102 | "require": { 1103 | "php": ">=7.2.5", 1104 | "psr/log": "^1|^2", 1105 | "symfony/deprecation-contracts": "^2.1", 1106 | "symfony/error-handler": "^4.4|^5.0", 1107 | "symfony/event-dispatcher": "^5.0", 1108 | "symfony/http-client-contracts": "^1.1|^2", 1109 | "symfony/http-foundation": "^4.4|^5.0", 1110 | "symfony/polyfill-ctype": "^1.8", 1111 | "symfony/polyfill-php73": "^1.9", 1112 | "symfony/polyfill-php80": "^1.16" 1113 | }, 1114 | "conflict": { 1115 | "symfony/browser-kit": "<4.4", 1116 | "symfony/cache": "<5.0", 1117 | "symfony/config": "<5.0", 1118 | "symfony/console": "<4.4", 1119 | "symfony/dependency-injection": "<5.1.8", 1120 | "symfony/doctrine-bridge": "<5.0", 1121 | "symfony/form": "<5.0", 1122 | "symfony/http-client": "<5.0", 1123 | "symfony/mailer": "<5.0", 1124 | "symfony/messenger": "<5.0", 1125 | "symfony/translation": "<5.0", 1126 | "symfony/twig-bridge": "<5.0", 1127 | "symfony/validator": "<5.0", 1128 | "twig/twig": "<2.13" 1129 | }, 1130 | "provide": { 1131 | "psr/log-implementation": "1.0|2.0" 1132 | }, 1133 | "require-dev": { 1134 | "psr/cache": "^1.0|^2.0|^3.0", 1135 | "symfony/browser-kit": "^4.4|^5.0", 1136 | "symfony/config": "^5.0", 1137 | "symfony/console": "^4.4|^5.0", 1138 | "symfony/css-selector": "^4.4|^5.0", 1139 | "symfony/dependency-injection": "^5.1.8", 1140 | "symfony/dom-crawler": "^4.4|^5.0", 1141 | "symfony/expression-language": "^4.4|^5.0", 1142 | "symfony/finder": "^4.4|^5.0", 1143 | "symfony/process": "^4.4|^5.0", 1144 | "symfony/routing": "^4.4|^5.0", 1145 | "symfony/stopwatch": "^4.4|^5.0", 1146 | "symfony/translation": "^4.4|^5.0", 1147 | "symfony/translation-contracts": "^1.1|^2", 1148 | "twig/twig": "^2.13|^3.0.4" 1149 | }, 1150 | "suggest": { 1151 | "symfony/browser-kit": "", 1152 | "symfony/config": "", 1153 | "symfony/console": "", 1154 | "symfony/dependency-injection": "" 1155 | }, 1156 | "type": "library", 1157 | "autoload": { 1158 | "psr-4": { 1159 | "Symfony\\Component\\HttpKernel\\": "" 1160 | }, 1161 | "exclude-from-classmap": [ 1162 | "/Tests/" 1163 | ] 1164 | }, 1165 | "notification-url": "https://packagist.org/downloads/", 1166 | "license": [ 1167 | "MIT" 1168 | ], 1169 | "authors": [ 1170 | { 1171 | "name": "Fabien Potencier", 1172 | "email": "fabien@symfony.com" 1173 | }, 1174 | { 1175 | "name": "Symfony Community", 1176 | "homepage": "https://symfony.com/contributors" 1177 | } 1178 | ], 1179 | "description": "Provides a structured process for converting a Request into a Response", 1180 | "homepage": "https://symfony.com", 1181 | "support": { 1182 | "source": "https://github.com/symfony/http-kernel/tree/v5.2.14" 1183 | }, 1184 | "funding": [ 1185 | { 1186 | "url": "https://symfony.com/sponsor", 1187 | "type": "custom" 1188 | }, 1189 | { 1190 | "url": "https://github.com/fabpot", 1191 | "type": "github" 1192 | }, 1193 | { 1194 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1195 | "type": "tidelift" 1196 | } 1197 | ], 1198 | "time": "2021-07-29T06:52:15+00:00" 1199 | }, 1200 | { 1201 | "name": "symfony/polyfill-ctype", 1202 | "version": "v1.20.0", 1203 | "source": { 1204 | "type": "git", 1205 | "url": "https://github.com/symfony/polyfill-ctype.git", 1206 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" 1207 | }, 1208 | "dist": { 1209 | "type": "zip", 1210 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", 1211 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", 1212 | "shasum": "" 1213 | }, 1214 | "require": { 1215 | "php": ">=7.1" 1216 | }, 1217 | "suggest": { 1218 | "ext-ctype": "For best performance" 1219 | }, 1220 | "type": "library", 1221 | "extra": { 1222 | "branch-alias": { 1223 | "dev-main": "1.20-dev" 1224 | }, 1225 | "thanks": { 1226 | "name": "symfony/polyfill", 1227 | "url": "https://github.com/symfony/polyfill" 1228 | } 1229 | }, 1230 | "autoload": { 1231 | "psr-4": { 1232 | "Symfony\\Polyfill\\Ctype\\": "" 1233 | }, 1234 | "files": [ 1235 | "bootstrap.php" 1236 | ] 1237 | }, 1238 | "notification-url": "https://packagist.org/downloads/", 1239 | "license": [ 1240 | "MIT" 1241 | ], 1242 | "authors": [ 1243 | { 1244 | "name": "Gert de Pagter", 1245 | "email": "BackEndTea@gmail.com" 1246 | }, 1247 | { 1248 | "name": "Symfony Community", 1249 | "homepage": "https://symfony.com/contributors" 1250 | } 1251 | ], 1252 | "description": "Symfony polyfill for ctype functions", 1253 | "homepage": "https://symfony.com", 1254 | "keywords": [ 1255 | "compatibility", 1256 | "ctype", 1257 | "polyfill", 1258 | "portable" 1259 | ], 1260 | "time": "2020-10-23T14:02:19+00:00" 1261 | }, 1262 | { 1263 | "name": "symfony/polyfill-mbstring", 1264 | "version": "v1.20.0", 1265 | "source": { 1266 | "type": "git", 1267 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1268 | "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" 1269 | }, 1270 | "dist": { 1271 | "type": "zip", 1272 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", 1273 | "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", 1274 | "shasum": "" 1275 | }, 1276 | "require": { 1277 | "php": ">=7.1" 1278 | }, 1279 | "suggest": { 1280 | "ext-mbstring": "For best performance" 1281 | }, 1282 | "type": "library", 1283 | "extra": { 1284 | "branch-alias": { 1285 | "dev-main": "1.20-dev" 1286 | }, 1287 | "thanks": { 1288 | "name": "symfony/polyfill", 1289 | "url": "https://github.com/symfony/polyfill" 1290 | } 1291 | }, 1292 | "autoload": { 1293 | "psr-4": { 1294 | "Symfony\\Polyfill\\Mbstring\\": "" 1295 | }, 1296 | "files": [ 1297 | "bootstrap.php" 1298 | ] 1299 | }, 1300 | "notification-url": "https://packagist.org/downloads/", 1301 | "license": [ 1302 | "MIT" 1303 | ], 1304 | "authors": [ 1305 | { 1306 | "name": "Nicolas Grekas", 1307 | "email": "p@tchwork.com" 1308 | }, 1309 | { 1310 | "name": "Symfony Community", 1311 | "homepage": "https://symfony.com/contributors" 1312 | } 1313 | ], 1314 | "description": "Symfony polyfill for the Mbstring extension", 1315 | "homepage": "https://symfony.com", 1316 | "keywords": [ 1317 | "compatibility", 1318 | "mbstring", 1319 | "polyfill", 1320 | "portable", 1321 | "shim" 1322 | ], 1323 | "time": "2020-10-23T14:02:19+00:00" 1324 | }, 1325 | { 1326 | "name": "symfony/polyfill-php73", 1327 | "version": "v1.20.0", 1328 | "source": { 1329 | "type": "git", 1330 | "url": "https://github.com/symfony/polyfill-php73.git", 1331 | "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" 1332 | }, 1333 | "dist": { 1334 | "type": "zip", 1335 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", 1336 | "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", 1337 | "shasum": "" 1338 | }, 1339 | "require": { 1340 | "php": ">=7.1" 1341 | }, 1342 | "type": "library", 1343 | "extra": { 1344 | "branch-alias": { 1345 | "dev-main": "1.20-dev" 1346 | }, 1347 | "thanks": { 1348 | "name": "symfony/polyfill", 1349 | "url": "https://github.com/symfony/polyfill" 1350 | } 1351 | }, 1352 | "autoload": { 1353 | "psr-4": { 1354 | "Symfony\\Polyfill\\Php73\\": "" 1355 | }, 1356 | "files": [ 1357 | "bootstrap.php" 1358 | ], 1359 | "classmap": [ 1360 | "Resources/stubs" 1361 | ] 1362 | }, 1363 | "notification-url": "https://packagist.org/downloads/", 1364 | "license": [ 1365 | "MIT" 1366 | ], 1367 | "authors": [ 1368 | { 1369 | "name": "Nicolas Grekas", 1370 | "email": "p@tchwork.com" 1371 | }, 1372 | { 1373 | "name": "Symfony Community", 1374 | "homepage": "https://symfony.com/contributors" 1375 | } 1376 | ], 1377 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 1378 | "homepage": "https://symfony.com", 1379 | "keywords": [ 1380 | "compatibility", 1381 | "polyfill", 1382 | "portable", 1383 | "shim" 1384 | ], 1385 | "time": "2020-10-23T14:02:19+00:00" 1386 | }, 1387 | { 1388 | "name": "symfony/polyfill-php80", 1389 | "version": "v1.20.0", 1390 | "source": { 1391 | "type": "git", 1392 | "url": "https://github.com/symfony/polyfill-php80.git", 1393 | "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" 1394 | }, 1395 | "dist": { 1396 | "type": "zip", 1397 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", 1398 | "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", 1399 | "shasum": "" 1400 | }, 1401 | "require": { 1402 | "php": ">=7.1" 1403 | }, 1404 | "type": "library", 1405 | "extra": { 1406 | "branch-alias": { 1407 | "dev-main": "1.20-dev" 1408 | }, 1409 | "thanks": { 1410 | "name": "symfony/polyfill", 1411 | "url": "https://github.com/symfony/polyfill" 1412 | } 1413 | }, 1414 | "autoload": { 1415 | "psr-4": { 1416 | "Symfony\\Polyfill\\Php80\\": "" 1417 | }, 1418 | "files": [ 1419 | "bootstrap.php" 1420 | ], 1421 | "classmap": [ 1422 | "Resources/stubs" 1423 | ] 1424 | }, 1425 | "notification-url": "https://packagist.org/downloads/", 1426 | "license": [ 1427 | "MIT" 1428 | ], 1429 | "authors": [ 1430 | { 1431 | "name": "Ion Bazan", 1432 | "email": "ion.bazan@gmail.com" 1433 | }, 1434 | { 1435 | "name": "Nicolas Grekas", 1436 | "email": "p@tchwork.com" 1437 | }, 1438 | { 1439 | "name": "Symfony Community", 1440 | "homepage": "https://symfony.com/contributors" 1441 | } 1442 | ], 1443 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 1444 | "homepage": "https://symfony.com", 1445 | "keywords": [ 1446 | "compatibility", 1447 | "polyfill", 1448 | "portable", 1449 | "shim" 1450 | ], 1451 | "time": "2020-10-23T14:02:19+00:00" 1452 | }, 1453 | { 1454 | "name": "symfony/polyfill-php81", 1455 | "version": "v1.24.0", 1456 | "source": { 1457 | "type": "git", 1458 | "url": "https://github.com/symfony/polyfill-php81.git", 1459 | "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" 1460 | }, 1461 | "dist": { 1462 | "type": "zip", 1463 | "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", 1464 | "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", 1465 | "shasum": "" 1466 | }, 1467 | "require": { 1468 | "php": ">=7.1" 1469 | }, 1470 | "type": "library", 1471 | "extra": { 1472 | "branch-alias": { 1473 | "dev-main": "1.23-dev" 1474 | }, 1475 | "thanks": { 1476 | "name": "symfony/polyfill", 1477 | "url": "https://github.com/symfony/polyfill" 1478 | } 1479 | }, 1480 | "autoload": { 1481 | "files": [ 1482 | "bootstrap.php" 1483 | ], 1484 | "psr-4": { 1485 | "Symfony\\Polyfill\\Php81\\": "" 1486 | }, 1487 | "classmap": [ 1488 | "Resources/stubs" 1489 | ] 1490 | }, 1491 | "notification-url": "https://packagist.org/downloads/", 1492 | "license": [ 1493 | "MIT" 1494 | ], 1495 | "authors": [ 1496 | { 1497 | "name": "Nicolas Grekas", 1498 | "email": "p@tchwork.com" 1499 | }, 1500 | { 1501 | "name": "Symfony Community", 1502 | "homepage": "https://symfony.com/contributors" 1503 | } 1504 | ], 1505 | "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", 1506 | "homepage": "https://symfony.com", 1507 | "keywords": [ 1508 | "compatibility", 1509 | "polyfill", 1510 | "portable", 1511 | "shim" 1512 | ], 1513 | "support": { 1514 | "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0" 1515 | }, 1516 | "funding": [ 1517 | { 1518 | "url": "https://symfony.com/sponsor", 1519 | "type": "custom" 1520 | }, 1521 | { 1522 | "url": "https://github.com/fabpot", 1523 | "type": "github" 1524 | }, 1525 | { 1526 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1527 | "type": "tidelift" 1528 | } 1529 | ], 1530 | "time": "2021-09-13T13:58:11+00:00" 1531 | }, 1532 | { 1533 | "name": "symfony/routing", 1534 | "version": "v5.2.0", 1535 | "source": { 1536 | "type": "git", 1537 | "url": "https://github.com/symfony/routing.git", 1538 | "reference": "130ac5175ad2fd417978baebd8062e2e6b2bc28b" 1539 | }, 1540 | "dist": { 1541 | "type": "zip", 1542 | "url": "https://api.github.com/repos/symfony/routing/zipball/130ac5175ad2fd417978baebd8062e2e6b2bc28b", 1543 | "reference": "130ac5175ad2fd417978baebd8062e2e6b2bc28b", 1544 | "shasum": "" 1545 | }, 1546 | "require": { 1547 | "php": ">=7.2.5", 1548 | "symfony/deprecation-contracts": "^2.1", 1549 | "symfony/polyfill-php80": "^1.15" 1550 | }, 1551 | "conflict": { 1552 | "symfony/config": "<5.0", 1553 | "symfony/dependency-injection": "<4.4", 1554 | "symfony/yaml": "<4.4" 1555 | }, 1556 | "require-dev": { 1557 | "doctrine/annotations": "^1.7", 1558 | "psr/log": "~1.0", 1559 | "symfony/config": "^5.0", 1560 | "symfony/dependency-injection": "^4.4|^5.0", 1561 | "symfony/expression-language": "^4.4|^5.0", 1562 | "symfony/http-foundation": "^4.4|^5.0", 1563 | "symfony/yaml": "^4.4|^5.0" 1564 | }, 1565 | "suggest": { 1566 | "doctrine/annotations": "For using the annotation loader", 1567 | "symfony/config": "For using the all-in-one router or any loader", 1568 | "symfony/expression-language": "For using expression matching", 1569 | "symfony/http-foundation": "For using a Symfony Request object", 1570 | "symfony/yaml": "For using the YAML loader" 1571 | }, 1572 | "type": "library", 1573 | "autoload": { 1574 | "psr-4": { 1575 | "Symfony\\Component\\Routing\\": "" 1576 | }, 1577 | "exclude-from-classmap": [ 1578 | "/Tests/" 1579 | ] 1580 | }, 1581 | "notification-url": "https://packagist.org/downloads/", 1582 | "license": [ 1583 | "MIT" 1584 | ], 1585 | "authors": [ 1586 | { 1587 | "name": "Fabien Potencier", 1588 | "email": "fabien@symfony.com" 1589 | }, 1590 | { 1591 | "name": "Symfony Community", 1592 | "homepage": "https://symfony.com/contributors" 1593 | } 1594 | ], 1595 | "description": "Symfony Routing Component", 1596 | "homepage": "https://symfony.com", 1597 | "keywords": [ 1598 | "router", 1599 | "routing", 1600 | "uri", 1601 | "url" 1602 | ], 1603 | "time": "2020-11-27T00:39:34+00:00" 1604 | }, 1605 | { 1606 | "name": "symfony/service-contracts", 1607 | "version": "v2.2.0", 1608 | "source": { 1609 | "type": "git", 1610 | "url": "https://github.com/symfony/service-contracts.git", 1611 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" 1612 | }, 1613 | "dist": { 1614 | "type": "zip", 1615 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", 1616 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", 1617 | "shasum": "" 1618 | }, 1619 | "require": { 1620 | "php": ">=7.2.5", 1621 | "psr/container": "^1.0" 1622 | }, 1623 | "suggest": { 1624 | "symfony/service-implementation": "" 1625 | }, 1626 | "type": "library", 1627 | "extra": { 1628 | "branch-alias": { 1629 | "dev-master": "2.2-dev" 1630 | }, 1631 | "thanks": { 1632 | "name": "symfony/contracts", 1633 | "url": "https://github.com/symfony/contracts" 1634 | } 1635 | }, 1636 | "autoload": { 1637 | "psr-4": { 1638 | "Symfony\\Contracts\\Service\\": "" 1639 | } 1640 | }, 1641 | "notification-url": "https://packagist.org/downloads/", 1642 | "license": [ 1643 | "MIT" 1644 | ], 1645 | "authors": [ 1646 | { 1647 | "name": "Nicolas Grekas", 1648 | "email": "p@tchwork.com" 1649 | }, 1650 | { 1651 | "name": "Symfony Community", 1652 | "homepage": "https://symfony.com/contributors" 1653 | } 1654 | ], 1655 | "description": "Generic abstractions related to writing services", 1656 | "homepage": "https://symfony.com", 1657 | "keywords": [ 1658 | "abstractions", 1659 | "contracts", 1660 | "decoupling", 1661 | "interfaces", 1662 | "interoperability", 1663 | "standards" 1664 | ], 1665 | "time": "2020-09-07T11:33:47+00:00" 1666 | }, 1667 | { 1668 | "name": "symfony/var-dumper", 1669 | "version": "v5.2.0", 1670 | "source": { 1671 | "type": "git", 1672 | "url": "https://github.com/symfony/var-dumper.git", 1673 | "reference": "173a79c462b1c81e1fa26129f71e41333d846b26" 1674 | }, 1675 | "dist": { 1676 | "type": "zip", 1677 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/173a79c462b1c81e1fa26129f71e41333d846b26", 1678 | "reference": "173a79c462b1c81e1fa26129f71e41333d846b26", 1679 | "shasum": "" 1680 | }, 1681 | "require": { 1682 | "php": ">=7.2.5", 1683 | "symfony/polyfill-mbstring": "~1.0", 1684 | "symfony/polyfill-php80": "^1.15" 1685 | }, 1686 | "conflict": { 1687 | "phpunit/phpunit": "<5.4.3", 1688 | "symfony/console": "<4.4" 1689 | }, 1690 | "require-dev": { 1691 | "ext-iconv": "*", 1692 | "symfony/console": "^4.4|^5.0", 1693 | "symfony/process": "^4.4|^5.0", 1694 | "twig/twig": "^2.4|^3.0" 1695 | }, 1696 | "suggest": { 1697 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", 1698 | "ext-intl": "To show region name in time zone dump", 1699 | "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" 1700 | }, 1701 | "bin": [ 1702 | "Resources/bin/var-dump-server" 1703 | ], 1704 | "type": "library", 1705 | "autoload": { 1706 | "files": [ 1707 | "Resources/functions/dump.php" 1708 | ], 1709 | "psr-4": { 1710 | "Symfony\\Component\\VarDumper\\": "" 1711 | }, 1712 | "exclude-from-classmap": [ 1713 | "/Tests/" 1714 | ] 1715 | }, 1716 | "notification-url": "https://packagist.org/downloads/", 1717 | "license": [ 1718 | "MIT" 1719 | ], 1720 | "authors": [ 1721 | { 1722 | "name": "Nicolas Grekas", 1723 | "email": "p@tchwork.com" 1724 | }, 1725 | { 1726 | "name": "Symfony Community", 1727 | "homepage": "https://symfony.com/contributors" 1728 | } 1729 | ], 1730 | "description": "Symfony mechanism for exploring and dumping PHP variables", 1731 | "homepage": "https://symfony.com", 1732 | "keywords": [ 1733 | "debug", 1734 | "dump" 1735 | ], 1736 | "time": "2020-11-27T00:39:34+00:00" 1737 | }, 1738 | { 1739 | "name": "symfony/var-exporter", 1740 | "version": "v5.2.0", 1741 | "source": { 1742 | "type": "git", 1743 | "url": "https://github.com/symfony/var-exporter.git", 1744 | "reference": "fbc3507f23d263d75417e09a12d77c009f39676c" 1745 | }, 1746 | "dist": { 1747 | "type": "zip", 1748 | "url": "https://api.github.com/repos/symfony/var-exporter/zipball/fbc3507f23d263d75417e09a12d77c009f39676c", 1749 | "reference": "fbc3507f23d263d75417e09a12d77c009f39676c", 1750 | "shasum": "" 1751 | }, 1752 | "require": { 1753 | "php": ">=7.2.5", 1754 | "symfony/polyfill-php80": "^1.15" 1755 | }, 1756 | "require-dev": { 1757 | "symfony/var-dumper": "^4.4.9|^5.0.9" 1758 | }, 1759 | "type": "library", 1760 | "autoload": { 1761 | "psr-4": { 1762 | "Symfony\\Component\\VarExporter\\": "" 1763 | }, 1764 | "exclude-from-classmap": [ 1765 | "/Tests/" 1766 | ] 1767 | }, 1768 | "notification-url": "https://packagist.org/downloads/", 1769 | "license": [ 1770 | "MIT" 1771 | ], 1772 | "authors": [ 1773 | { 1774 | "name": "Nicolas Grekas", 1775 | "email": "p@tchwork.com" 1776 | }, 1777 | { 1778 | "name": "Symfony Community", 1779 | "homepage": "https://symfony.com/contributors" 1780 | } 1781 | ], 1782 | "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", 1783 | "homepage": "https://symfony.com", 1784 | "keywords": [ 1785 | "clone", 1786 | "construct", 1787 | "export", 1788 | "hydrate", 1789 | "instantiate", 1790 | "serialize" 1791 | ], 1792 | "time": "2020-10-28T21:31:18+00:00" 1793 | }, 1794 | { 1795 | "name": "tweedegolf/prometheus-client", 1796 | "version": "v0.4.0", 1797 | "source": { 1798 | "type": "git", 1799 | "url": "https://github.com/tweedegolf/prometheus-client.git", 1800 | "reference": "f97fc95fc82c2d62d8553c75d0211514e5e1aaf3" 1801 | }, 1802 | "dist": { 1803 | "type": "zip", 1804 | "url": "https://api.github.com/repos/tweedegolf/prometheus-client/zipball/f97fc95fc82c2d62d8553c75d0211514e5e1aaf3", 1805 | "reference": "f97fc95fc82c2d62d8553c75d0211514e5e1aaf3", 1806 | "shasum": "" 1807 | }, 1808 | "require": { 1809 | "ext-json": "*", 1810 | "php": ">=7.0" 1811 | }, 1812 | "require-dev": { 1813 | "ext-redis": "*", 1814 | "phpunit/phpunit": "6.5.*|7.5.*", 1815 | "predis/predis": "^1.1" 1816 | }, 1817 | "type": "library", 1818 | "autoload": { 1819 | "psr-4": { 1820 | "TweedeGolf\\PrometheusClient\\": "src/" 1821 | } 1822 | }, 1823 | "notification-url": "https://packagist.org/downloads/", 1824 | "license": [ 1825 | "MIT" 1826 | ], 1827 | "authors": [ 1828 | { 1829 | "name": "Ruben Nijveld", 1830 | "email": "ruben@tweedegolf.com" 1831 | } 1832 | ], 1833 | "description": "A PHP Prometheus client library", 1834 | "support": { 1835 | "issues": "https://github.com/tweedegolf/prometheus-client/issues", 1836 | "source": "https://github.com/tweedegolf/prometheus-client/tree/v0.4.0" 1837 | }, 1838 | "time": "2022-01-10T21:21:47+00:00" 1839 | } 1840 | ], 1841 | "packages-dev": [], 1842 | "aliases": [], 1843 | "minimum-stability": "stable", 1844 | "stability-flags": [], 1845 | "prefer-stable": false, 1846 | "prefer-lowest": false, 1847 | "platform": { 1848 | "php": ">=7.1.3" 1849 | }, 1850 | "platform-dev": [], 1851 | "plugin-api-version": "2.3.0" 1852 | } 1853 | -------------------------------------------------------------------------------- /src/Controller/MetricsController.php: -------------------------------------------------------------------------------- 1 | registry = $registry; 25 | } 26 | 27 | /** 28 | * @return Response 29 | */ 30 | public function metricsAction() 31 | { 32 | $formatter = new TextFormatter(); 33 | return new Response($formatter->format($this->registry->collect()), 200, [ 34 | 'Content-Type' => $formatter->getMimeType(), 35 | ]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DependencyInjection/CollectorCompilerPass.php: -------------------------------------------------------------------------------- 1 | has(CollectorRegistry::class)) { 15 | return; 16 | } 17 | 18 | $definition = $container->findDefinition(CollectorRegistry::class); 19 | $taggedServices = $container->findTaggedServiceIds('tweede_golf_prometheus.collector'); 20 | 21 | foreach ($taggedServices as $id => $tags) { 22 | $definition->addMethodCall('register', [new Reference($id)]); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | getRootNode() 26 | ->children() 27 | ->scalarNode('metrics_path')->defaultValue('/metrics')->end() 28 | ->scalarNode('register_defaults')->defaultValue(true)->end() 29 | ->scalarNode('make_memory_adapter')->defaultValue(true)->end() 30 | ->scalarNode('storage_adapter_service')->defaultValue(new Reference(ApcuAdapter::class))->end() 31 | ->arrayNode('collectors') 32 | ->useAttributeAsKey('name') 33 | ->prototype('array') 34 | ->children() 35 | ->arrayNode('counter') 36 | ->treatNullLike(['active' => true]) 37 | ->treatTrueLike(['active' => true]) 38 | ->treatFalseLike(['active' => false]) 39 | ->children() 40 | ->booleanNode('active')->defaultTrue()->end() 41 | ->arrayNode('labels')->prototype('scalar')->end()->end() 42 | ->scalarNode('help')->defaultNull()->end() 43 | ->scalarNode('storage')->defaultValue(CollectorRegistry::DEFAULT_STORAGE)->end() 44 | ->end() 45 | ->end() 46 | ->arrayNode('gauge') 47 | ->treatNullLike(['active' => true]) 48 | ->treatTrueLike(['active' => true]) 49 | ->treatFalseLike(['active' => false]) 50 | ->children() 51 | ->booleanNode('active')->defaultTrue()->end() 52 | ->arrayNode('labels')->prototype('scalar')->end()->end() 53 | ->scalarNode('help')->defaultNull()->end() 54 | ->scalarNode('storage')->defaultValue(CollectorRegistry::DEFAULT_STORAGE)->end() 55 | ->variableNode('initializer')->defaultNull()->end() 56 | ->end() 57 | ->end() 58 | ->arrayNode('histogram') 59 | ->treatNullLike(['active' => true]) 60 | ->treatTrueLike(['active' => true]) 61 | ->treatFalseLike(['active' => false]) 62 | ->children() 63 | ->booleanNode('active')->defaultTrue()->end() 64 | ->arrayNode('labels')->prototype('scalar')->end()->end() 65 | ->scalarNode('help')->defaultNull()->end() 66 | ->scalarNode('storage')->defaultValue(CollectorRegistry::DEFAULT_STORAGE)->end() 67 | ->arrayNode('buckets')->prototype('float')->end()->end() 68 | ->end() 69 | ->end() 70 | ->end() 71 | ->validate() 72 | ->ifTrue(function (array $data) { 73 | $alreadyActive = false; 74 | foreach ($data as $item) { 75 | if ($alreadyActive && $item['active']) { 76 | return true; 77 | } 78 | $alreadyActive = $alreadyActive || $item['active']; 79 | } 80 | 81 | return !$alreadyActive; 82 | }) 83 | ->thenInvalid('A collector must have exactly one type (counter, gauge, histogram) activated') 84 | ->end() 85 | ->end() 86 | ->end() 87 | ->end() 88 | ; 89 | 90 | return $treeBuilder; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/DependencyInjection/StorageAdapterCompilerPass.php: -------------------------------------------------------------------------------- 1 | has(CollectorRegistry::class)) { 15 | return; 16 | } 17 | 18 | $definition = $container->findDefinition(CollectorRegistry::class); 19 | $taggedServices = $container->findTaggedServiceIds('tweede_golf_prometheus.storage_adapter'); 20 | 21 | foreach ($taggedServices as $id => $tags) { 22 | foreach ($tags as $tag) { 23 | if (!isset($tag['alias'])) { 24 | throw new \RuntimeException("No alias specified for prometheus storage adapter with id '{$id}'"); 25 | } 26 | $definition->addMethodCall('registerStorageAdapter', [$tag['alias'], new Reference($id)]); 27 | } 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/DependencyInjection/TweedeGolfPrometheusExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 27 | 28 | $container->setParameter('tweede_golf_prometheus.metrics_path', $config['metrics_path']); 29 | $registry = new Definition(CollectorRegistry::class, [ 30 | new Reference($config['storage_adapter_service']), 31 | $config['make_memory_adapter'], 32 | $config['register_defaults'], 33 | ]); 34 | $container->setDefinition(CollectorRegistry::class, $registry); 35 | 36 | foreach ($config['collectors'] as $name => $collector) { 37 | if (isset($collector['counter']) && $collector['counter']['active']) { 38 | $registry->addMethodCall('createCounter', [ 39 | $name, 40 | $collector['counter']['labels'], 41 | $collector['counter']['help'], 42 | $collector['counter']['storage'], 43 | true, 44 | ]); 45 | } elseif (isset($collector['gauge']) && $collector['gauge']['active']) { 46 | $registry->addMethodCall('createGauge', [ 47 | $name, 48 | $collector['gauge']['labels'], 49 | $this->makeInitializer($collector['gauge']['initializer'], $container), 50 | $collector['gauge']['help'], 51 | $collector['gauge']['storage'], 52 | true, 53 | ]); 54 | } elseif (isset($collector['histogram']) && $collector['histogram']['active']) { 55 | $buckets = count($collector['histogram']['buckets']) === 0 ? null : $collector['histogram']['buckets']; 56 | 57 | $registry->addMethodCall('createHistogram', [ 58 | $name, 59 | $collector['histogram']['labels'], 60 | $buckets, 61 | $collector['histogram']['help'], 62 | $collector['histogram']['storage'], 63 | true, 64 | ]); 65 | } else { 66 | throw new \InvalidArgumentException("Collector without any active type found"); 67 | } 68 | } 69 | 70 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 71 | $loader->load('services.yml'); 72 | } 73 | 74 | /** 75 | * @param mixed $init 76 | * @param ContainerBuilder $container 77 | * @return callable|float 78 | */ 79 | private function makeInitializer($init, ContainerBuilder $container) 80 | { 81 | if ($init !== null) { 82 | if (is_float($init) || is_int($init)) { 83 | return $init; 84 | } elseif (is_array($init) && count($init) === 2 && substr($init[0], 0, 1) === '@') { 85 | $ref = new Reference(substr($init[0], 1)); 86 | return [$ref, $init[1]]; 87 | } elseif (is_string($init)) { 88 | $init = $container->getParameterBag()->resolveValue($init); 89 | if (is_numeric($init)) { 90 | return floatval($init); 91 | } elseif (is_callable($init, false)) { 92 | return $init; 93 | } else { 94 | throw new \RuntimeException("Cannot use string as default value"); 95 | } 96 | } else { 97 | throw new \RuntimeException("Unknown type for initializer"); 98 | } 99 | } 100 | 101 | return null; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Resources/config/routing.yml: -------------------------------------------------------------------------------- 1 | tweede_golf_prometheus_metrics: 2 | path: "%tweede_golf_prometheus.metrics_path%" 3 | defaults: { _controller: TweedeGolf\PrometheusBundle\Controller\MetricsController::metricsAction } 4 | -------------------------------------------------------------------------------- /src/Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | TweedeGolf\PrometheusClient\Storage\ApcuAdapter: 3 | class: TweedeGolf\PrometheusClient\Storage\ApcuAdapter 4 | 5 | TweedeGolf\PrometheusClient\Storage\ApcAdapter: 6 | class: TweedeGolf\PrometheusClient\Storage\ApcAdapter 7 | 8 | TweedeGolf\PrometheusBundle\Controller\MetricsController: 9 | class: Tweedegolf\PrometheusBundle\Controller\MetricsController 10 | arguments: 11 | - '@TweedeGolf\PrometheusClient\CollectorRegistry' 12 | -------------------------------------------------------------------------------- /src/TweedeGolfPrometheusBundle.php: -------------------------------------------------------------------------------- 1 | addCompilerPass(new CollectorCompilerPass()); 17 | $container->addCompilerPass(new StorageAdapterCompilerPass()); 18 | } 19 | 20 | } 21 | --------------------------------------------------------------------------------