Test Failed
Push — PHP-8.x ( 1002b3...895d01 )
by Biao
16:54 queued 11:57
created

HttpRequestCollector::__construct()   C

Complexity

Conditions 12
Paths 40

Size

Total Lines 32
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 12
eloc 23
c 2
b 0
f 0
nc 40
nop 1
dl 0
loc 32
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Hhxsv5\LaravelS\Components\Prometheus\Collectors;
4
5
use Closure;
6
use Hhxsv5\LaravelS\Components\MetricCollector;
7
use Illuminate\Http\Request;
0 ignored issues
show
Bug introduced by
The type Illuminate\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
9
class HttpRequestCollector extends MetricCollector
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class HttpRequestCollector
Loading history...
10
{
11
    const MAX_ROUND = 10;
12
    protected $routes          = [];
13
    protected $routesByUses    = [];
14
    protected $routesByClosure = [];
15
16
    public function __construct(array $config)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
17
    {
18
        parent::__construct($config);
19
        
20
        if (!isset($this->config['max_duration_time_window'])) {
21
            $this->config['max_duration_time_window'] = 60;
22
        }
23
24
        $routes = method_exists(app(), 'getRoutes') ? app()->getRoutes() : app('router')->getRoutes();
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

24
        $routes = method_exists(/** @scrutinizer ignore-call */ app(), 'getRoutes') ? app()->getRoutes() : app('router')->getRoutes();
Loading history...
25
        if ($routes instanceof \Illuminate\Routing\RouteCollection) { // Laravel
0 ignored issues
show
Bug introduced by
The type Illuminate\Routing\RouteCollection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
            foreach ($routes->getRoutes() as $route) {
27
                $method = $route->methods()[0];
28
                $uri = '/' . ltrim($route->uri(), '/');
29
                $this->routes[$method . $uri] = $uri;
30
31
                $action = $route->getAction();
32
                if (is_string($action['uses'])) { // Uses
33
                    $this->routesByUses[$method . $action['uses']] = $uri;
34
                } elseif ($action['uses'] instanceof Closure) {  // Closure
35
                    $objectId = spl_object_hash($action['uses']);
36
                    $this->routesByClosure[$method . $objectId] = $uri;
37
                }
38
            }
39
        } elseif (is_array($routes)) { // Lumen
40
            $this->routes = $routes;
41
            foreach ($routes as $route) {
42
                if (isset($route['action']['uses'])) { // Uses
43
                    $this->routesByUses[$route['method'] . $route['action']['uses']] = $route['uri'];
44
                }
45
                if (isset($route['action'][0]) && $route['action'][0] instanceof Closure) { // Closure
46
                    $objectId = spl_object_hash($route['action'][0]);
47
                    $this->routesByClosure[$route['method'] . $objectId] = $route['uri'];
48
                }
49
            }
50
        }
51
    }
52
53
    public function collect(array $params = [])
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function collect()
Loading history...
54
    {
55
        if (!$this->config['enable']) {
56
            return;
57
        }
58
59
        /**@var \Illuminate\Http\Request $request */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
60
        /**@var \Illuminate\Http\Response $response */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
61
        list($request, $response) = $params;
62
63
        $status = $response->getStatusCode();
64
        if (isset($this->config['ignored_http_codes'][$status])) {
65
            // Ignore the requests.
66
            return;
67
        }
68
69
        $uri = $this->findRouteUri($request);
70
        $cost = (int)round((microtime(true) - $request->server('REQUEST_TIME_FLOAT')) * 1000000); // Time unit: μs
71
72
        // Http Request Stats
73
        $requestLabels = http_build_query([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
74
            'method' => $request->getMethod(),
75
            'uri'    => $uri,
76
            'status' => $status,
77
        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
78
79
        // Key Format: prefix+metric_name+metric_type+metric_labels
80
        $countKey = implode($this->config['apcu_key_separator'], [$this->config['apcu_key_prefix'], 'http_server_requests_seconds_count', 'summary', $requestLabels]);
81
        $sumKey = implode($this->config['apcu_key_separator'], [$this->config['apcu_key_prefix'], 'http_server_requests_seconds_sum', 'summary', $requestLabels]);
82
        $maxKey = implode($this->config['apcu_key_separator'], [$this->config['apcu_key_prefix'], 'http_server_requests_seconds_max', 'gauge', $requestLabels]);
83
        apcu_inc($countKey, 1, $success, $this->config['apcu_key_max_age']);
84
        apcu_inc($sumKey, $cost, $success, $this->config['apcu_key_max_age']);
85
86
        $round = 0;
87
        do {
88
            $round++;
89
            $lastCost = apcu_fetch($maxKey);
90
            if ($lastCost === false) {
91
                if (!apcu_add($maxKey, $cost, $this->config['max_duration_time_window'])) {
92
                    continue;
93
                }
94
                break;
95
            }
96
            if ($cost <= $lastCost) {
97
                break;
98
            }
99
            if (apcu_cas($maxKey, $lastCost, $cost)) {
100
                break;
101
            }
102
        } while ($round <= self::MAX_ROUND);
103
    }
104
105
    protected function findRouteUri(Request $request)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function findRouteUri()
Loading history...
106
    {
107
        $method = $request->getMethod();
108
        $uri = $request->getPathInfo();
109
        $key = $method . $uri;
110
        if (isset($this->routes[$key])) {
111
            return $uri;
112
        }
113
114
        $route = $request->route();
115
        if ($route instanceof \Illuminate\Routing\Route) { // Laravel
0 ignored issues
show
Bug introduced by
The type Illuminate\Routing\Route was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
116
            $uri = $route->uri();
117
        } elseif (is_array($route)) { // Lumen
118
            if (isset($route[1]['uses'])) {
119
                $key = $method . $route[1]['uses'];
120
                if (isset($this->routesByUses[$key])) {
121
                    $uri = $this->routesByUses[$key];
122
                }
123
            } elseif (isset($route[1][0]) && $route[1][0] instanceof Closure) {
124
                $key = $method . spl_object_hash($route[1][0]);
125
                if (isset($this->routesByClosure[$key])) {
126
                    $uri = $this->routesByClosure[$key];
127
                }
128
            }
129
        }
130
        return $uri;
131
    }
132
}