Passed
Pull Request — master (#2)
by Tim
04:28
created

MemcacheMonitor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\memcacheMonitor;
6
7
use Exception;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\Locale\Translate;
11
use SimpleSAML\Logger;
12
use SimpleSAML\Memcache;
13
use SimpleSAML\XHTML\Template;
14
15
/**
16
 * Handles interactions with SSP's memcacheMonitor system.
17
 */
18
class MemcacheMonitor
19
{
20
    /**
21
     * The configuration that holds the memcache configuration
22
     * @var \SimpleSAML\Configuration
23
     */
24
    private $config;
25
26
    /**
27
     * An associative array with keys matching the stats, and values pointing to the formatting function for that key
28
     * @var array
29
     */
30
    private $formats = [
0 ignored issues
show
introduced by
The private property $formats is not used, and could be removed.
Loading history...
31
        'bytes' => [self::class, 'humanreadable'],
32
        'bytes_read' => [self::class, 'humanreadable'],
33
        'bytes_written' => [self::class, 'humanreadable'],
34
        'limit_maxbytes' => [self::class, 'humanreadable'],
35
        'time' => [self::class, 'tdate'],
36
        'uptime' => [self::class, 'hours'],
37
    ];
38
39
40
    /**
41
     * @param \SimpleSAML\Configuration $config The configuration to use.
42
     */
43
    public function __construct(Configuration $config)
44
    {
45
        $this->config = $config;
46
    }
47
48
49
    /**
50
     * Retrieve stats, render them into a human readable page
51
     */
52
    public function renderStats(): Template
53
    {
54
        $statsraw = Memcache::getStats();
55
        $stats = $statsraw;
56
57
        foreach ($stats as $key => &$entry) {
58
            if (array_key_exists($key, $formats)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $formats seems to be never defined.
Loading history...
59
                $func = $formats[$key];
60
                foreach ($entry as $k => $val) {
61
                    $entry[$k] = call_user_func($func, $val);
62
                }
63
            }
64
        }
65
66
        $t = new Template($this->config, 'memcacheMonitor:memcachestat.twig');
67
        $rowTitles = [
68
            'accepting_conns' => Translate::noop('{memcacheMonitor:memcachestat:accepting_conns}'),
69
            'auth_cmds' => Translate::noop('{memcacheMonitor:memcachestat:auth_cmds}'),
70
            'auth_errors' => Translate::noop('{memcacheMonitor:memcachestat:auth_errors}'),
71
            'bytes' => Translate::noop('{memcacheMonitor:memcachestat:bytes}'),
72
            'bytes_read' => Translate::noop('{memcacheMonitor:memcachestat:bytes_read}'),
73
            'bytes_written' => Translate::noop('{memcacheMonitor:memcachestat:bytes_written}'),
74
            'cas_badval' => Translate::noop('{memcacheMonitor:memcachestat:cas_badval}'),
75
            'cas_hits' => Translate::noop('{memcacheMonitor:memcachestat:cas_hits}'),
76
            'cas_misses' => Translate::noop('{memcacheMonitor:memcachestat:cas_misses}'),
77
            'cmd_flush' => Translate::noop('{memcacheMonitor:memcachestat:cmd_flush}'),
78
            'cmd_get' => Translate::noop('{memcacheMonitor:memcachestat:cmd_get}'),
79
            'cmd_set' => Translate::noop('{memcacheMonitor:memcachestat:cmd_set}'),
80
            'cmd_touch' => Translate::noop('{memcacheMonitor:memcachestat:cmd_touch}'),
81
            'connection_structures' => Translate::noop('{memcacheMonitor:memcachestat:connection_structures}'),
82
            'conn_yields' => Translate::noop('{memcacheMonitor:memcachestat:conn_yields}'),
83
            'curr_connections' => Translate::noop('{memcacheMonitor:memcachestat:curr_connections}'),
84
            'curr_items' => Translate::noop('{memcacheMonitor:memcachestat:curr_items}'),
85
            'decr_hits' => Translate::noop('{memcacheMonitor:memcachestat:decr_hits}'),
86
            'decr_misses' => Translate::noop('{memcacheMonitor:memcachestat:decr_misses}'),
87
            'delete_hits' => Translate::noop('{memcacheMonitor:memcachestat:delete_hits}'),
88
            'delete_misses' => Translate::noop('{memcacheMonitor:memcachestat:delete_misses}'),
89
            'expired_unfetched' => Translate::noop('{memcacheMonitor:memcachestat:expired_unfetched}'),
90
            'evicted_unfetched' => Translate::noop('{memcacheMonitor:memcachestat:evicted_unfetched}'),
91
            'evictions' => Translate::noop('{memcacheMonitor:memcachestat:evictions}'),
92
            'get_hits' => Translate::noop('{memcacheMonitor:memcachestat:get_hits}'),
93
            'get_misses' => Translate::noop('{memcacheMonitor:memcachestat:get_misses}'),
94
            'hash_bytes' => Translate::noop('{memcacheMonitor:memcachestat:hash_bytes}'),
95
            'hash_is_expanding' => Translate::noop('{memcacheMonitor:memcachestat:hash_is_expanding}'),
96
            'hash_power_level' => Translate::noop('{memcacheMonitor:memcachestat:hash_power_level}'),
97
            'incr_hits' => Translate::noop('{memcacheMonitor:memcachestat:incr_hits}'),
98
            'incr_misses' => Translate::noop('{memcacheMonitor:memcachestat:incr_misses}'),
99
            'libevent' => Translate::noop('{memcacheMonitor:memcachestat:libevent}'),
100
            'limit_maxbytes' => Translate::noop('{memcacheMonitor:memcachestat:limit_maxbytes}'),
101
            'listen_disabled_num' => Translate::noop('{memcacheMonitor:memcachestat:listen_disabled_num}'),
102
            'pid' => Translate::noop('{memcacheMonitor:memcachestat:pid}'),
103
            'pointer_size' => Translate::noop('{memcacheMonitor:memcachestat:pointer_size}'),
104
            'reclaimed' => Translate::noop('{memcacheMonitor:memcachestat:reclaimed}'),
105
            'reserved_fds' => Translate::noop('{memcacheMonitor:memcachestat:reserved_fds}'),
106
            'rusage_system' => Translate::noop('{memcacheMonitor:memcachestat:rusage_system}'),
107
            'rusage_user' => Translate::noop('{memcacheMonitor:memcachestat:rusage_user}'),
108
            'threads' => Translate::noop('{memcacheMonitor:memcachestat:threads}'),
109
            'time' => Translate::noop('{memcacheMonitor:memcachestat:time}'),
110
            'total_connections' => Translate::noop('{memcacheMonitor:memcachestat:total_connections}'),
111
            'total_items' => Translate::noop('{memcacheMonitor:memcachestat:total_items}'),
112
            'touch_hits' => Translate::noop('{memcacheMonitor:memcachestat:touch_hits}'),
113
            'touch_misses' => Translate::noop('{memcacheMonitor:memcachestat:touch_misses}'),
114
            'uptime' => Translate::noop('{memcacheMonitor:memcachestat:uptime}'),
115
            'version' => Translate::noop('{memcacheMonitor:memcachestat:version}'),
116
        ];
117
118
        // Identify column headings
119
        $colTitles = [];
120
        foreach ($stats as $rowTitle => $rowData) {
121
            foreach ($rowData as $colTitle => $foo) {
122
                if (!in_array($colTitle, $colTitles, true)) {
123
                    $colTitles[] = $colTitle;
124
                }
125
            }
126
        }
127
128
        if (array_key_exists('bytes', $statsraw) && array_key_exists('limit_maxbytes', $statsraw)) {
129
            $usage = [];
130
            $maxpix = 400;
131
            foreach ($statsraw['bytes'] as $key => $row_data) {
132
                $pix = floor($statsraw['bytes'][$key] * $maxpix / $statsraw['limit_maxbytes'][$key]);
133
                $usage[$key] = $pix . 'px';
134
            }
135
            $t->data['maxpix'] = $maxpix . 'px';
136
            $t->data['usage'] = $usage;
137
        }
138
139
        $t->data['title'] = 'Memcache stats';
140
        $t->data['rowTitles'] = $rowTitles;
141
        $t->data['colTitles'] = $colTitles;
142
        $t->data['statsraw'] = $statsraw;
143
        $t->data['table'] = $stats;
144
145
        return $t;
146
    }
147
148
149
    /**
150
     * @param int $input
151
     * @return string
152
     */
153
    private function tdate(int $input): string
154
    {
155
        return date(DATE_RFC822, $input);
156
    }
157
158
159
    /**
160
     * @param int $input
161
     * @return string
162
     */
163
    private function hours(int $input): string
164
    {
165
        if ($input < 60) {
166
            return number_format($input, 2) . ' sec';
167
        }
168
169
        if ($input < 60 * 60) {
170
            return number_format(($input / 60), 2) . ' min';
171
        }
172
173
        if ($input < 24 * 60 * 60) {
174
            return number_format(($input / (60 * 60)), 2) . ' hours';
175
        }
176
177
        return number_format($input / (24 * 60 * 60), 2) . ' days';
178
    }
179
180
181
    /**
182
     * @param int $input
183
     * @return string
184
     */
185
    private function humanreadable(int $input): string
186
    {
187
        $output = "";
188
        $input = abs($input);
189
190
        if ($input >= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 100)) {
191
            $output = sprintf("%5ldEi", $input / (1024 * 1024 * 1024 * 1024 * 1024 * 1024));
192
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 10)) {
193
            $output = sprintf("%5.1fEi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
194
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 1024 * 1024)) {
195
            $output = sprintf("%5.2fEi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
196
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 1024 * 100)) {
197
            $output = sprintf("%5ldPi", $input / (1024 * 1024 * 1024 * 1024 * 1024));
198
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 1024 * 10)) {
199
            $output = sprintf("%5.1fPi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
200
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 1024)) {
201
            $output = sprintf("%5.2fPi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
202
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 100)) {
203
            $output = sprintf("%5ldTi", $input / (1024 * 1024 * 1024 * 1024));
204
        } elseif ($input >= (1024 * 1024 * 1024 * 1024 * 10)) {
205
            $output = sprintf("%5.1fTi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0));
206
        } elseif ($input >= (1024 * 1024 * 1024 * 1024)) {
207
            $output = sprintf("%5.2fTi", $input / (1024.0 * 1024.0 * 1024.0 * 1024.0));
208
        } elseif ($input >= (1024 * 1024 * 1024 * 100)) {
209
            $output = sprintf("%5ldGi", $input / (1024 * 1024 * 1024));
210
        } elseif ($input >= (1024 * 1024 * 1024 * 10)) {
211
            $output = sprintf("%5.1fGi", $input / (1024.0 * 1024.0 * 1024.0));
212
        } elseif ($input >= (1024 * 1024 * 1024)) {
213
            $output = sprintf("%5.2fGi", $input / (1024.0 * 1024.0 * 1024.0));
214
        } elseif ($input >= (1024 * 1024 * 100)) {
215
            $output = sprintf("%5ldMi", $input / (1024 * 1024));
216
        } elseif ($input >= (1024 * 1024 * 10)) {
217
            $output = sprintf("%5.1fM", $input / (1024.0 * 1024.0));
218
        } elseif ($input >= (1024 * 1024)) {
219
            $output = sprintf("%5.2fMi", $input / (1024.0 * 1024.0));
220
        } elseif ($input >= (1024 * 100)) {
221
            $output = sprintf("%5ldKi", $input / 1024);
222
        } elseif ($input >= (1024 * 10)) {
223
            $output = sprintf("%5.1fKi", $input / 1024.0);
224
        } elseif ($input >= (1024)) {
225
            $output = sprintf("%5.2fKi", $input / 1024.0);
226
        } else {
227
            $output = sprintf("%5ld", $input);
228
        }
229
230
        return $output;
231
    }
232
}
233