Completed
Push — master ( 182cf9...dcef90 )
by Philip
02:08
created

Slim3Setup   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 5
c 1
b 0
f 1
lcom 0
cbo 3
dl 0
loc 81
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A setupMiddleware() 0 21 1
A getPathWithMethods() 0 9 2
A setupAndGetMetricsRoute() 0 17 2
1
<?php
2
3
/*
4
 * This file is part of the PHPProm package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace PHPProm\Integration;
13
14
use \Psr\Http\Message\ServerRequestInterface as Request;
15
use \Psr\Http\Message\ResponseInterface as Response;
16
use \Slim\App;
17
use PHPProm\PrometheusExport;
18
use PHPProm\Storage\AbstractStorage;
19
use PHPProm\StopWatch;
20
use Slim\Route;
21
22
/**
23
 * Class Slim3Setup
24
 * Setups Slim applications to measure:
25
 * - the time of each route
26
 * - the used memory of each route
27
 * - the amount of requests of each route
28
 * It also offers an function to be used for a Prometheus scrapable endpoint.
29
 * @package PHPProm\Integration
30
 */
31
class Slim3Setup {
32
33
34
    /**
35
     * Sets up the Slim middleware where the actual measurements happen.
36
     *
37
     * @param App $app
38
     * the Silex application
39
     * @param AbstractStorage $storage
40
     * the storage for the measurements
41
     */
42
    protected function setupMiddleware(App $app, AbstractStorage $storage) {
43
        $storage->addAvailableMetric('route_time', 'name', 'request times per route in seconds', 'gauge', 'Nan');
44
        $storage->addAvailableMetric('route_memory', 'name', 'request memory per route in bytes', 'gauge', 'Nan');
45
        $storage->addAvailableMetric('route_requests_total', 'name', 'total requests per route', 'counter', 0);
46
47
        $app->add(function(Request $request, Response $response, App $next) use ($storage) {
48
49
            $method = $request->getMethod();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
50
            $pattern = str_replace('/', '_', $request->getAttribute('route')->getPattern());
51
            $route = $method.$pattern;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
52
53
            $routeTime = new StopWatch($storage);
54
            $routeTime->start();
55
            $response = $next($request, $response);
56
            $routeTime->stop('route_time', $route);
57
            $storage->storeMeasurement('route_memory', $route, memory_get_peak_usage(true));
58
            $storage->incrementMeasurement('route_requests_total', $route);
59
60
            return $response;
61
        });
62
    }
63
64
    /**
65
     * Gets the path with all methods from a route.
66
     *
67
     * @param Route $route
68
     * the route to get the path and methods from
69
     * @return array
70
     * the pathes with methods
71
     */
72
    protected function getPathWithMethods(Route $route) {
73
        $routes   = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 3 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
74
        $pattern  = str_replace('/', '_', $route->getPattern());
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 1 space but found 2 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
75
        $methods  = $route->getMethods();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 1 space but found 2 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
76
        foreach($methods as $method) {
77
            $routes[] = $method.$pattern;
78
        }
79
        return $routes;
80
    }
81
82
    /**
83
     * Sets up the Slim middlewares where the actual measurements happen
84
     * and returns a function to be used for a Prometheus scrapable endpoint.
85
     *
86
     * @param App $app
87
     * the Slim application
88
     * @param AbstractStorage $storage
89
     * the storage for the measurements
90
     *
91
     * @return \Closure
92
     * the function to be used for a Prometheus scrapable endpoint
93
     */
94
    public function setupAndGetMetricsRoute(App $app, AbstractStorage $storage) {
95
        $this->setupMiddleware($app, $storage);
96
        $self = $this;
97
        return function (Request $request, Response $response) use ($app, $storage, $self) {
98
            $routes          = [];
99
            $availableRoutes = $app->getContainer()->get('router')->getRoutes();
100
            foreach ($availableRoutes as $route) {
101
                $routes = array_merge($routes, $self->getPathWithMethods($route));
102
            }
103
            $export       = new PrometheusExport();
104
            $responseBody = $export->getExport($storage, $routes);
105
106
            $response = $response->withHeader('Content-type', 'text/plain; version=0.0.4');
107
            $response->getBody()->write($responseBody);
108
109
        };
110
    }
111
}
112