Dank Eurer Unterstützung und ein paar Fundstellen im Netz habe ich eine neue Version zusammengekratzt.
Das Problem, dass virtuelle Maschinen und etliche andere Umgebungen die Daten aus /sys
gar nicht erst bekommen ist auch nicht behebbar, sondern mindestens teilweise die Absicht der Erschaffer dieser Umgebungen. Immerhin kann man in etliche der Dateien unter sys
auch direkt schreiben.
<?php
class cpufreq {
protected $governor;
protected $minfreq;
protected $curfreq;
protected $maxfreq;
protected $calcstates;
protected $sysruntime;
protected $cpuTimefactor = 100;
protected $hmFactor = 1000000;
protected $hmString = 'GHz';
protected $path;
function __construct() {
if ( is_dir( '/sys/devices/system/cpu/cpu0/cpufreq/' ) ) {
$this -> path = '/sys/devices/system/cpu/cpu0/cpufreq/';
} elseif ( is_dir( '/sys/devices/system/cpu/cpufreq/' ) ) {
$this -> path = '/sys/devices/system/cpu/cpufreq/';
}
$this -> read_from_system();
}
function read_from_system() {
if ( is_file( $this -> path . 'scaling_governor' ) ) {
$this -> governor = trim( file_get_contents( $this -> path . 'scaling_governor' ) );
$this -> minfreq = trim( file_get_contents( $this -> path . 'scaling_min_freq' ) );
$this -> curfreq = trim( file_get_contents( $this -> path . 'scaling_cur_freq' ) );
$this -> maxfreq = trim( file_get_contents( $this -> path . 'scaling_max_freq' ) );
} elseif( is_file( $this -> path . 'cpuinfo_min_freq' ) ) {
$this -> governor = false;
$this -> minfreq = trim( file_get_contents( $this -> path . 'cpuinfo_min_freq' ) );
$this -> maxfreq = trim( file_get_contents( $this -> path . 'cpuinfo_max_freq' ) );
if ( is_file( $this -> path . 'cpuinfo_curr_freq' ) ) {
$this -> curfreq = trim( file_get_contents( $this -> path . 'cpuinfo_cur_freq' ) );
} elseif ( $this -> maxfreq == $this -> minfreq ) {
$this -> curfreq = $this -> minfreq;
} else {
$this -> curfreq = 0;
}
} else {
http_response_code( 507 );
echo 'Leider wird Ihr System nicht unterstützt. Ende.';
trigger_error( 'System wird vom Skript nicht unterstützt.', E_USER_NOTICE );
$this -> governor = false;
$this -> minfreq = 0;
$this -> curfreq = 0;
$this -> maxfreq = trim( file_get_contents( $this -> path . 'cpuinfo_max_freq' ) );
}
if ( is_file( $this -> path . 'stats/time_in_state' ) ) {
$this -> calcstates = $this -> calcTimestates();
} else {
$this -> calcstates = false;
}
}
function human_readble ( $z ) {
$z = $z / $this -> hmFactor;
return sprintf('%0.3f %s', $z, $this -> hmString );
}
private function getFreq ( $v, $hm ) {
if ( $hm ) {
return $this -> human_readble( $v );
} else {
return $v;
}
}
function calcTimestates() {
$lines = file_get_contents( $this -> path . 'stats/time_in_state' );
$lines = explode ( "\n", $lines );
$sum = 0;
$arr = [];
foreach ( $lines as $line ) {
$line = trim( $line );
if ( $line ) {
list( $f, $t ) = explode ( ' ', $line );
$t = floor( $t / $this->cpuTimefactor );
if ( $t != 0 ) {
$sum += $t;
$f = $this -> human_readble( $f);
$arr[$f]['t_abs'] = $t;
$arr[$f]['t_hum'] = Seconds2Human( $t );
}
}
}
$this -> sysruntime = $sum;
foreach ( array_keys( $arr ) as $f ) {
$arr[$f]['t_rel'] = round( $arr[$f]['t_abs'] / $sum , 3 ) ;
$arr[$f]['t_100'] = sprintf( '%2.1f%%', round( $arr[$f]['t_abs'] / $sum * 100 , 1 ) );
}
return $arr;
}
function getMinFreq( $hm = false ) {
return $this -> getFreq ( $this -> minfreq, $hm );
}
function getCurFreq( $hm = false ) {
return $this -> getFreq ( $this -> curfreq, $hm );
}
function getMaxFreq( $hm = false ) {
return $this -> getFreq ( $this -> maxfreq, $hm );
}
function getSysRunTime( $hm = false ) {
if ( $hm ) {
return Seconds2Human( $this -> sysruntime );
} else {
$this -> sysruntime;
}
}
function getCalcstates () {
return $this -> calcstates;
}
function getGovernor () {
return $this -> governor;
}
}
function Seconds2Human( $s, $daystring = 'd' ) {
$s = (int) $s;
# Days
if ( $s > 86400 ) {
$d = floor( $s / 86400 );
$s = $s - $d * 86400;
} else {
$d = 0;
}
# Houres
if ( $s > 3600 ) {
$h = floor( $s / 3600 );
$s = $s - $h * 3600;
} else {
$h = 0;
}
# Minutes
if ( $s > 60 ) {
$m = floor( $s / 60 );
$s = $s - $m * 60;
} else {
$m = 0;
}
return sprintf( '%d%s %02d:%02d:%02d', $d, $daystring, $h, $m, $s );
}
header ( 'Content-Type: text/plain; charset=utf-8' );
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
$cpustat = new cpufreq();
echo 'Governor: ' . $cpustat-> getGovernor( ) . PHP_EOL;
echo 'Geringste Frequenz: ' . $cpustat-> getMinFreq( true ) . PHP_EOL;
echo 'Gegenwärtige Frequenz: ' . $cpustat-> getCurFreq( true ) . PHP_EOL;
echo 'Maximale Frequenz: ' . $cpustat-> getMaxFreq( true ) . PHP_EOL;
echo 'System läuft seit: ' . $cpustat-> getSysRunTime( true ) . PHP_EOL . PHP_EOL;
/*
if ( $a = $cpustat-> getCalcstates() ) {
echo PHP_EOL . 'Zeitliche Frequenznutzung:'. PHP_EOL;
print_r( $cpustat-> getCalcstates() ) ;
}
# */
#/*
if ( $a = $cpustat-> getCalcstates() ) {
echo PHP_EOL . 'Zeitliche Frequenznutzung:' . PHP_EOL;
foreach ( array_keys( $a ) as $freq ) {
echo $freq . ': ' . sprintf( "%5s", $a[$freq]['t_100'] ) . "\n";
}
}
# */
echo PHP_EOL;
Output:
Governor: conservative
Geringste Frequenz: 0.600 GHz
Gegenwärtige Frequenz: 0.600 GHz
Maximale Frequenz: 1.500 GHz
System läuft seit: 1d 20:19:26
Zeitliche Frequenznutzung:
0.600 GHz: 99.4%
0.700 GHz: 0.2%
0.800 GHz: 0.1%
0.900 GHz: 0.1%
1.000 GHz: 0.0%
1.100 GHz: 0.0%
1.200 GHz: 0.1%
1.300 GHz: 0.0%
1.400 GHz: 0.0%
1.500 GHz: 0.0%
Ich schreib das gleich noch mal in Python…