Passed
Push — master ( 685c75...93fbb7 )
by Biao
14:29 queued 10:37
created

PrometheusExporter   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Importance

Changes 8
Bugs 2 Features 2
Metric Value
eloc 115
c 8
b 2
f 2
dl 0
loc 191
rs 10
wmc 19

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getSystemLoadAvgMetrics() 0 21 1
A observeRequest() 0 20 2
A render() 0 21 4
B getSwooleMetrics() 0 67 7
A __construct() 0 3 1
A getApcuMetrics() 0 34 4
1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Hhxsv5\LaravelS\Components\Prometheus;
4
5
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...
6
use Symfony\Component\HttpFoundation\Response;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\Response 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...
7
8
class PrometheusExporter
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class PrometheusExporter
Loading history...
9
{
10
    const REDNER_MIME_TYPE = 'text/plain; version=0.0.4';
11
12
    private $config;
0 ignored issues
show
Coding Style introduced by
Private member variable "config" must be prefixed with an underscore
Loading history...
13
14
    private static $secondsMetrics = [
0 ignored issues
show
Coding Style introduced by
Private member variable "secondsMetrics" must be prefixed with an underscore
Loading history...
15
        'http_server_requests_seconds_sum' => 'http_server_requests_seconds_sum',
16
    ];
17
18
    public function __construct(array $config)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
19
    {
20
        $this->config = $config;
21
    }
22
23
    public function observeRequest(Request $request, Response $response)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function observeRequest()
Loading history...
24
    {
25
        $cost = microtime(true) - $request->server('REQUEST_TIME_FLOAT');
26
        $status = $response->getStatusCode();
27
        if (isset($this->config['ignored_http_codes'][$status])) {
28
            // Ignore the requests.
29
            return;
30
        }
31
32
        $labels = 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...
33
            'method' => $request->getMethod(),
34
            'uri'    => $request->getPathInfo(),
35
            'status' => $status,
36
        ]);
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...
37
        // prefix+metric_name+metric_type+metric_labels
38
        $countKey = implode($this->config['apcu_key_separator'], [$this->config['apcu_key_prefix'], 'http_server_requests_seconds_count', 'summary', $labels]);
39
        $sumKey = implode($this->config['apcu_key_separator'], [$this->config['apcu_key_prefix'], 'http_server_requests_seconds_sum', 'summary', $labels]);
40
        apcu_inc($countKey, 1, $success, $this->config['apcu_key_max_age']);
41
        // $cost to ms
42
        apcu_inc($sumKey, round($cost * 1000), $success, $this->config['apcu_key_max_age']);
0 ignored issues
show
Bug introduced by
round($cost * 1000) of type double is incompatible with the type integer expected by parameter $step of apcu_inc(). ( Ignorable by Annotation )

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

42
        apcu_inc($sumKey, /** @scrutinizer ignore-type */ round($cost * 1000), $success, $this->config['apcu_key_max_age']);
Loading history...
43
    }
44
45
    public function getSystemLoadAvgMetrics()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getSystemLoadAvgMetrics()
Loading history...
46
    {
47
        $load = sys_getloadavg();
48
        return [
49
            [
50
                'name'  => 'system_load_average_1m',
51
                'help'  => '',
52
                'type'  => 'gauge',
53
                'value' => $load[0],
54
            ],
55
            [
56
                'name'  => 'system_load_average_5m',
57
                'help'  => '',
58
                'type'  => 'gauge',
59
                'value' => $load[1],
60
            ],
61
            [
62
                'name'  => 'system_load_average_15m',
63
                'help'  => '',
64
                'type'  => 'gauge',
65
                'value' => $load[2],
66
            ],
67
        ];
68
    }
69
70
    public function getSwooleMetrics()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getSwooleMetrics()
Loading history...
71
    {
72
        /**@var \Swoole\Http\Server $swoole */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
73
        $swoole = app('swoole');
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

73
        $swoole = /** @scrutinizer ignore-call */ app('swoole');
Loading history...
74
        $stats = $swoole->stats();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $stats is correct as $swoole->stats() targeting Swoole\Server::stats() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
75
        // Get worker_num/task_worker_num from setting for the old Swoole.
76
        $setting = $swoole->setting;
77
        if (!isset($stats['worker_num'])) {
78
            $stats['worker_num'] = $setting['worker_num'];
79
        }
80
        if (!isset($stats['task_worker_num'])) {
81
            $stats['task_worker_num'] = isset($setting['task_worker_num']) ? $setting['task_worker_num'] : 0;
82
        }
83
        return [
84
            [
85
                'name'  => 'swoole_start_time',
86
                'help'  => '',
87
                'type'  => 'gauge',
88
                'value' => $stats['start_time'],
89
            ],
90
            [
91
                'name'  => 'swoole_connection_num',
92
                'help'  => '',
93
                'type'  => 'gauge',
94
                'value' => $stats['connection_num'],
95
            ],
96
            [
97
                'name'  => 'swoole_request_count',
98
                'help'  => '',
99
                'type'  => 'gauge',
100
                'value' => $stats['request_count'],
101
            ],
102
            [
103
                'name'  => 'swoole_worker_num',
104
                'help'  => '',
105
                'type'  => 'gauge',
106
                'value' => $stats['worker_num'],
107
            ],
108
            [
109
                'name'  => 'swoole_idle_worker_num',
110
                'help'  => '',
111
                'type'  => 'gauge',
112
                'value' => isset($stats['idle_worker_num']) ? $stats['idle_worker_num'] : 0,
113
            ],
114
            [
115
                'name'  => 'swoole_task_worker_num',
116
                'help'  => '',
117
                'type'  => 'gauge',
118
                'value' => $stats['task_worker_num'],
119
            ],
120
            [
121
                'name'  => 'swoole_task_idle_worker_num',
122
                'help'  => '',
123
                'type'  => 'gauge',
124
                'value' => isset($stats['task_idle_worker_num']) ? $stats['task_idle_worker_num'] : 0,
125
            ],
126
            [
127
                'name'  => 'swoole_tasking_num',
128
                'help'  => '',
129
                'type'  => 'gauge',
130
                'value' => $stats['tasking_num'],
131
            ],
132
            [
133
                'name'  => 'swoole_coroutine_num',
134
                'help'  => '',
135
                'type'  => 'gauge',
136
                'value' => isset($stats['coroutine_num']) ? $stats['coroutine_num'] : 0,
137
            ],
138
        ];
139
    }
140
141
    public function getApcuMetrics()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getApcuMetrics()
Loading history...
142
    {
143
        $apcSmaInfo = apcu_sma_info(true);
144
        $metrics = [
145
            [
146
                'name'  => 'apcu_seg_size',
147
                'help'  => '',
148
                'type'  => 'gauge',
149
                'value' => $apcSmaInfo['seg_size'],
150
            ],
151
            [
152
                'name'  => 'apcu_avail_mem',
153
                'help'  => '',
154
                'type'  => 'gauge',
155
                'value' => $apcSmaInfo['avail_mem'],
156
            ],
157
        ];
158
        foreach (new \APCuIterator('/^' . $this->config['apcu_key_prefix'] . $this->config['apcu_key_separator'] . '/') as $item) {
159
            $value = apcu_fetch($item['key'], $success);
160
            if (!$success) {
161
                continue;
162
            }
163
164
            $parts = explode($this->config['apcu_key_separator'], $item['key']);
165
            parse_str($parts[3], $labels);
166
            $metrics[] = [
167
                'name'   => $parts[1],
168
                'help'   => '',
169
                'type'   => $parts[2],
170
                'value'  => isset(self::$secondsMetrics[$parts[1]]) ? $value / 1000 : $value,
171
                'labels' => $labels,
172
            ];
173
        }
174
        return $metrics;
175
176
    }
177
178
    public function render()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function render()
Loading history...
179
    {
180
        $defaultLabels = ['application' => $this->config['application']];
181
        $metrics = array_merge($this->getSystemLoadAvgMetrics(), $this->getSwooleMetrics(), $this->getApcuMetrics());
182
        $lines = [];
183
        foreach ($metrics as $metric) {
184
            $lines[] = "# HELP " . $metric['name'] . " {$metric['help']}";
185
            $lines[] = "# TYPE " . $metric['name'] . " {$metric['type']}";
186
187
            $metricLabels = isset($metric['labels']) ? $metric['labels'] : [];
188
            $labels = ['{'];
189
            $allLabels = array_merge($defaultLabels, $metricLabels);
190
            foreach ($allLabels as $key => $value) {
191
                $value = addslashes($value);
192
                $labels[] = "{$key}=\"{$value}\",";
193
            }
194
            $labels[] = '}';
195
            $labelStr = implode('', $labels);
196
            $lines[] = $metric['name'] . "$labelStr {$metric['value']}";
197
        }
198
        return implode("\n", $lines);
199
    }
200
}