Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
32.98% covered (danger)
32.98%
31 / 94
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SystemUtils
32.98% covered (danger)
32.98%
31 / 94
20.00% covered (danger)
20.00%
1 / 5
382.01
0.00% covered (danger)
0.00%
0 / 1
 __construct
n/a
0 / 0
n/a
0 / 0
1
 getRAM
80.00% covered (warning)
80.00%
12 / 15
0.00% covered (danger)
0.00%
0 / 1
6.29
 getRAMUsage
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getCpuUsage
64.29% covered (warning)
64.29%
9 / 14
0.00% covered (danger)
0.00%
0 / 1
6.14
 getHostname
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 runProc
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
210
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\System
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\System;
16
17/**
18 * System utils
19 *
20 * @package phpOMS\System
21 * @license OMS License 2.0
22 * @link    https://jingga.app
23 * @since   1.0.0
24 */
25final class SystemUtils
26{
27    /**
28     * Constructor.
29     *
30     * @since 1.0.0
31     * @codeCoverageIgnore
32     */
33    private function __construct()
34    {
35    }
36
37    /**
38     * Get system RAM.
39     *
40     * @return int
41     *
42     * @since 1.0.0
43     */
44    public static function getRAM() : int
45    {
46        $mem = 0;
47
48        if (\stristr(\PHP_OS, 'WIN')) {
49            $memArr = [];
50            \exec('wmic memorychip get capacity', $memArr);
51
52            $mem = \array_sum($memArr) / 1024;
53        } elseif (\stristr(\PHP_OS, 'LINUX')) {
54            $fh = \fopen('/proc/meminfo', 'r');
55
56            if ($fh === false) {
57                return $mem; // @codeCoverageIgnore
58            }
59
60            while ($line = \fgets($fh)) {
61                $pieces = [];
62                if (\preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces)) {
63                    $mem = (int) ($pieces[1] ?? 0) * 1024;
64                    break;
65                }
66            }
67
68            \fclose($fh);
69        }
70
71        return (int) $mem;
72    }
73
74    /**
75     * Get RAM usage.
76     *
77     * @return int
78     *
79     * @since 1.0.0
80     */
81    public static function getRAMUsage() : int
82    {
83        $memUsage = 0;
84
85        if (\stristr(\PHP_OS, 'LINUX')) {
86            $free = \shell_exec('free');
87
88            if ($free === null || $free === false) {
89                return $memUsage; // @codeCoverageIgnore
90            }
91
92            $free     = \trim($free);
93            $freeArr  = \explode("\n", $free);
94            $mem      = \explode(' ', $freeArr[1]);
95            $mem      = \array_values(\array_filter($mem));
96            $memUsage = ((float) ($mem[2] ?? 0.0)) / ((float) ($mem[1] ?? 1.0)) * 100;
97        }
98
99        return (int) $memUsage;
100    }
101
102    /**
103     * Get cpu usage.
104     *
105     * @return int
106     *
107     * @since 1.0.0
108     */
109    public static function getCpuUsage() : int
110    {
111        $cpuUsage = 0;
112
113        if (\stristr(\PHP_OS, 'WIN') !== false) {
114            $cpuUsage = null;
115            \exec('wmic cpu get LoadPercentage', $cpuUsage);
116            $cpuUsage = (int) ($cpuUsage[1] ?? -1);
117        } elseif (\stristr(\PHP_OS, 'LINUX') !== false) {
118            $loadavg = \sys_getloadavg();
119
120            if ($loadavg === false) {
121                return -1;
122            }
123
124            $nproc = (int) \exec('nproc');
125            if ($nproc === 0) {
126                return -1;
127            }
128
129            $cpuUsage = ((float) ($loadavg[0] ?? 0.0)) * 100 / $nproc;
130        }
131
132        return (int) $cpuUsage;
133    }
134
135    /**
136     * Get the server hostname.
137     *
138     * @return string
139     *
140     * @since 1.0.0
141     */
142    public static function getHostname() : string
143    {
144        if (isset($_SERVER['SERVER_NAME'])) {
145            return $_SERVER['SERVER_NAME'];
146        } elseif (($result = \gethostname()) !== false) {
147            return $result;
148        } elseif (!empty($hostname = \php_uname('n'))) {
149            return $hostname;
150        }
151
152        return 'localhost.localdomain';
153    }
154
155    /**
156     * Execute a command
157     *
158     * @param string $executable Path or name of the executable
159     * @param string $cmd        Command to execute
160     * @param bool   $async      Execute async
161     *
162     * @return array
163     *
164     * @throws \Exception
165     *
166     * @since 1.0.0
167     */
168    public static function runProc(string $executable, string $cmd, bool $async = false) : array
169    {
170        if (\strtolower((string) \substr(\PHP_OS, 0, 3)) === 'win') {
171            $cmd = 'cd ' . \escapeshellarg(\dirname($executable))
172                . ' && ' . \basename($executable)
173                . ' '
174                . $cmd;
175
176            if ($async) {
177                $cmd .= ' > nul 2>&1 &';
178            }
179        } else {
180            $cmd = \escapeshellarg($executable)
181                . ' '
182                . $cmd;
183
184            if ($async) {
185                $cmd .= ' > /dev/null 2>&1 &';
186            }
187        }
188
189        $pipes = [];
190        $desc  = [
191            1 => ['pipe', 'w'],
192            2 => ['pipe', 'w'],
193        ];
194
195        $resource = \proc_open($cmd, $desc, $pipes, null, null);
196
197        if ($resource === false) {
198            throw new \Exception();
199        }
200
201        $stdout = '';
202        $stderr = '';
203
204        if ($async) {
205            \stream_set_blocking($pipes[1], false);
206            \stream_set_blocking($pipes[2], false);
207        } else {
208            $stdout = \stream_get_contents($pipes[1]);
209            $stderr = \stream_get_contents($pipes[2]);
210        }
211
212        foreach ($pipes as $pipe) {
213            \fclose($pipe);
214        }
215
216        $status = \proc_close($resource);
217
218        if ($status == -1) {
219            throw new \Exception((string) $stderr);
220        }
221
222        $lines = \trim(
223            $stdout === false
224                ? ''
225                : (empty($stdout)
226                    ? ($stderr === false ? '' : $stderr)
227                    : $stdout)
228            );
229
230        $lineArray = \preg_split('/\r\n|\n|\r/', $lines);
231        $lines     = [];
232
233        if ($lineArray === false) {
234            return $lines;
235        }
236
237        foreach ($lineArray as $line) {
238            $temp = \preg_replace('/\s+/', ' ', \trim($line, ' '));
239
240            if (!empty($temp)) {
241                $lines[] = $temp;
242            }
243        }
244
245        return $lines;
246    }
247}