Completed
Push — master ( b6cd70...9cc556 )
by Yaro
09:14
created

System::cpus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Yaro\Jarboe\Helpers;
4
5
class System
6
{
7
    private $cpus;
8
    private $averageLoadSamples;
9
    private $memoryTotal;
10
    private $memoryFree;
11
    private $swapTotal;
12
    private $swapFree;
13
14
    public function __construct()
15
    {
16
        $this->cpus = $this->cpusCount();
17
        $this->averageLoadSamples = sys_getloadavg();
18
        list($this->memoryTotal, $this->memoryFree, $this->swapTotal, $this->swapFree) = $this->getMemoryData();
19
    }
20
21
    public function memoryTotal()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
22
    {
23
        return $this->memoryTotal;
24
    }
25
26
    public function memoryFree()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
27
    {
28
        return $this->memoryFree;
29
    }
30
31
    public function memoryUsed()
32
    {
33
        if (is_null($this->memoryTotal())) {
34
            return null;
35
        }
36
37
        return $this->memoryTotal() - $this->memoryFree();
38
    }
39
40
    public function swapTotal()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
41
    {
42
        return $this->swapTotal;
43
    }
44
45
    public function swapFree()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
46
    {
47
        return $this->swapFree;
48
    }
49
50
    public function swapUsed()
51
    {
52
        if (is_null($this->swapTotal())) {
53
            return null;
54
        }
55
56
        return $this->swapTotal() - $this->swapFree();
57
    }
58
59
    public function cpus(): int
60
    {
61
        return $this->cpus;
62
    }
63
64
    public function systemLoadSamples(): array
65
    {
66
        return $this->averageLoadSamples;
67
    }
68
69
    public function systemLoadSamplesInPercentages(): array
70
    {
71
        $samples = $this->systemLoadSamples();
72
        array_walk($samples, function (&$load) {
73
            $load = round(($load * 100) / $this->cpus,2);
74
        });
75
76
        return $samples;
77
    }
78
79
    private function cpusCount(): int
80
    {
81
        $cores = 1;
82
        if ($this->isLinux() || $this->isMacOS()) {
83
            $cores = shell_exec('getconf _NPROCESSORS_ONLN');
84
        } elseif ($this->isBSD()) {
85
            $cores = shell_exec('getconf NPROCESSORS_ONLN');
86
        } elseif ($this->isWindows()) {
87
            $stdout = shell_exec('wmic computersystem get NumberOfLogicalProcessors');
88
            $cores = array_sum(explode("\n", $stdout));
89
        }
90
91
        return (int) $cores;
92
    }
93
94
    public function isWindows(): bool
95
    {
96
        return PHP_OS_FAMILY == 'Windows';
97
    }
98
99
    public function isLinux(): bool
100
    {
101
        return PHP_OS_FAMILY == 'Linux';
102
    }
103
104
    public function isMacOS(): bool
105
    {
106
        return PHP_OS_FAMILY == 'Darwin';
107
    }
108
109
    public function isBSD(): bool
110
    {
111
        return PHP_OS_FAMILY == 'BSD';
112
    }
113
114
    public function readableSize($size, $precision = 2)
115
    {
116
        $units = [
117
            'B',
118
            'kB',
119
            'MB',
120
            'GB',
121
            'TB',
122
            'PB',
123
            'EB',
124
            'ZB',
125
            'YB',
126
        ];
127
        $step = 1024;
128
        $i = 0;
129
        while (($size / $step) > 0.9) {
130
            $size = $size / $step;
131
            $i++;
132
        }
133
        return sprintf('%s %s', round($size, $precision), $units[$i]);
134
    }
135
136
    private function getMemoryData(): array
137
    {
138
        $default = [
139
            null,
140
            null,
141
            null,
142
            null,
143
        ];
144
        if (!$this->isLinux()) {
145
            return $default;
146
        }
147
148
        exec('cat /proc/meminfo', $output, $errorCode);
149
        if ($errorCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errorCode of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
150
            return $default;
151
        }
152
153
        $memoryTotal = preg_replace('~[^\d]~', '', $output[0]); // kb
154
        $memoryFree = preg_replace('~[^\d]~', '', $output[1]);
155
        $swapTotal = preg_replace('~[^\d]~', '', $output[14]);
156
        $swapFree = preg_replace('~[^\d]~', '', $output[15]);
157
158
        return [
159
            $memoryTotal * 1024,
160
            $memoryFree * 1024,
161
            $swapTotal * 1024,
162
            $swapFree * 1024,
163
        ];
164
    }
165
166
    public function memoryPercentage(): int
167
    {
168
        if (!$this->memoryTotal()) {
169
            return 0;
170
        }
171
172
        return $this->memoryUsed() / ($this->memoryTotal() / 100);
173
    }
174
175
    public function swapPercentage(): int
176
    {
177
        if (!$this->swapTotal()) {
178
            return 0;
179
        }
180
181
        return $this->swapUsed() / ($this->swapTotal() / 100);
182
    }
183
}
184