Raketenwilli: Neue Version

Beitrag lesen

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…