Zjištění dynamických veličin serveru pomocí PHP
Na webových stránkách Free WoW serverů je užitečné zobrazit různé dynamické údaje o běhu. Ty lze s často jednoduše získat přímo pomocí jazyku PHP.
Linux
Většina informací o systému je dostupná a snadno přístupná ve virtuálním souborovém systému připojeném do adresáře /proc.
Zatížení procesoru
Tato funkce zjišťuje společné zatížení všech jader procesoru v procentech.
function CpuUsage()
{
global $cpuIDLEprev, $cpuSYSTprev, $cpuUSERprev;
// get processor usage seconds for pct stats ###
$File = fopen('/proc/stat', 'r');
$Row = fgets($File);
fclose($File);
$Parts = explode(' ', $Row);
$cpuUSER = $Parts[2] + $Parts[3];
$cpuSYST = $Parts[4];
$cpuIDLE = $Parts[5];
$cpuUSERdiff = ($cpuUSER - $cpuUSERprev);
$cpuSYSTdiff = ($cpuSYST - $cpuSYSTprev);
$cpuIDLEdiff = ($cpuIDLE - $cpuIDLEprev);
$cpuIDLEdiffTOTAL = (($cpuUSERdiff + $cpuSYSTdiff) + $cpuIDLEdiff);
if ($cpuIDLEdiffTOTAL > 0)
{
$cpuUSERcent = ($cpuUSERdiff / $cpuIDLEdiffTOTAL) * 100;
$cpuSYSTcent = ($cpuSYSTdiff / $cpuIDLEdiffTOTAL) * 100;
$cpuIDLEcent = ($cpuIDLEdiff / $cpuIDLEdiffTOTAL * 100);
} else
{
$cpuUSERcent = 0;
$cpuSYSTcent = 0;
$cpuIDLEcent = 0;
}
$cpuUSERprev = $cpuUSER;
$cpuSYSTprev = $cpuSYST;
$cpuIDLEprev = $cpuIDLE;
return(100 - round($cpuIDLEcent * 100) / 100); // Truncate to two decimals
}
Využití paměti
Zjišťuje celkové využití paměti včetně stránkované paměti v odkládacím oddílu swap. Funkci je možné také upravit, aby četla pouze obsazení fyzické paměti. Výsledek je vrácen v bajtech.
function MemoryUsage()
{
$Output = array();
exec('free -b', $Output);
$Row = $Output[2];
while(strpos($Row, ' ') !== false) $Row = str_replace(' ', ' ', $Row);
$RowParts = explode(' ', $Row);
$Row = $Output[3];
while(strpos($Row, ' ') !== false) $Row = str_replace(' ', ' ', $Row);
$RowParts2 = explode(' ', $Row);
return($RowParts[2] + $RowParts2[2]);
}
Zatížení disku
Tato funkce zjišťuje zatížení pevného disku v procentech. Funkce využívá programu iostat obsaženého v balíčku sysstat. Parametrem funkce je označení sledovaného disku (sda, sdb, sdc, atd.).
function DiskUtilization($Disk = 'sda')
{
$Output = array();
exec('iostat -d '.$Disk.' -x -m 2 2', $Output); // 2 second measure delay
$Row = $Output[6];
while(strpos($Row, ' ') !== false) $Row = str_replace(' ', ' ', $Row); // Remove redundant spaces
$Parts = explode(' ', $Row);
$Value = str_replace(',', '.', $Parts[11]);
return($Value);
}
Zatížení sítě
Vrácená hodnota je pole dostupných síťových rozhraní. Každá položka obsahuje dále údaje Down, Up, DownAverage, UpAvegage. Hodnoty jsou v bajtech za sekundu.
function GetNetworkState()
{
global $LastNetworkState;
if(!isset($LastNetworkState)) $LastNetworkState = array();
$NetworkState = array('Time' => time());
$Output = array();
exec('cat /proc/net/dev', $Output);
array_shift($Output); // Skip header
array_shift($Output); // Skip header
foreach($Output as $Item)
{
while(strpos($Item, ' ') !== false) $Item = str_replace(' ', ' ', $Item); // Rrmove multiple spaces
$Item = explode(':', $Item);
$Interface = trim($Item[0]);
$Item = explode(' ', trim($Item[1]));
$NetworkState[$Interface] = array('Down' => $Item[0], 'Up' => $Item[8]);
if(array_key_exists($Interface, $LastNetworkState))
{
$Period = time() - $LastNetworkState['Time'];
$NetworkState[$Interface]['DownAverage'] = round(($NetworkState[$Interface]['Down'] - $LastNetworkState[$Interface]['Down']) / $Period);
$NetworkState[$Interface]['UpAverage'] = round(($NetworkState[$Interface]['Up'] - $LastNetworkState[$Interface]['Up']) / $Period);
} else
{
$NetworkState[$Interface]['DownAverage'] = 0;
$NetworkState[$Interface]['UpAverage'] = 0;
}
if($NetworkState[$Interface]['DownAverage'] < 0) $NetworkState[$Interface]['DownAverage'] = 0;
if($NetworkState[$Interface]['UpAverage'] < 0) $NetworkState[$Interface]['UpAverage'] = 0;
}
$LastNetworkState = $NetworkState;
return($NetworkState);
}
Pro zobrazení pak použijeme:
$NetworkState = GetNetworkState();
echo('Odchozí data: '.$NetworkState['eth0']['Up'].' B/s');
Počet připojení síťovým službám
Tato funkce sleduje počet navázaných připojení na určitý port. K tomuto účelu se využívá systémový výpis všech síťových spojeních a jeho filtrace podle žádaného portu s vyloučením lokálních spojení. Sledovat lze např. počtu lidí připojených na TeamSpeak, který využívá port 8767.
function NetworkServiceConnectionCount($Port)
{
$HostIP = gethostbyname(trim(`hostname`));
$Output = array();
exec('cat /proc/net/nf_conntrack|grep "dst='.$HostIP.' "|grep "dport='.$Port.' "|grep "ASSURED"', $Output);
return(count($Output));
}
Volné místo na disku
Tento údaj lze zjistit přímo pomocí PHP a funkce disk_free_space. Např.
echo(disk_free_space('/'));
Odezva sítě
Odezvu(anglicky latency) nejčastěji měříme vůči českému peeringovému centru NIX.CZ, které sdružuje v jednom bodě mnoho různých poskytovatelů. Na odezvě sítě a tedy době, za jak dlouho doputují data tam i zpět, přímo závisí plynulost reakcí ve hře. Z časového grafu latence je pak možné vypozorovat také stabilitu sítě a zatížení sítě. Funkce vrací výsledek v milisekundách.
function Ping()
{
exec('ping nix.cz -c 1 -W 1|grep time=', $Row); // W - timeout in seconds, c - ping count
$Parts = explode(' ', $Row[0]);
if(count($Parts) > 6)
{
$Time = $Parts[7];
$TimeParts = explode('=', $Time);
return($TimeParts[1]);
} else return(0);
}
Stav síťového portu
Funkce pro zjištění zda je na dané ip otevřený určitý port.
function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
}
function CheckPortStatus($Ip, $Port, $Timeout = 0.5)
{
set_error_handler('ErrorHandler'); // Disable failed connection warning
//error_reporting(0);
if($Fp1 = fsockopen($Ip, $Port, $ERROR_NO, $ERROR_STR, (float)$Timeout))
{
fclose($Fp1);
return(TRUE);
} else
{
//echo($ERROR_NO.','.$ERROR_STR);
return(FALSE);
}
restore_error_handler();
}
Klasicky se používá k zobrazení stavu serveru:
if(CheckPortStatus('localhost', 8085) echo('Online'); else echo('Offline');
Ale pomocí tohoto údaje lze také sledovat dostupnost emulátoru v procentech, pokud stav TRUE prohlásíme za 100 % a FALSE za 0 % a tyto hodnoty v průběhu času budeme průměrovat.
Doba běhu serveru
Vrací dobu od startu počítače v sekundách.
function SystemUptime()
{
$File = fopen('/proc/uptime', 'r');
$Uptime = fgets($File);
fclose($File);
$UptimeParts = explode(' ', $Uptime);
return($UptimeParts[0]);
}
Systémová teplota
K zjištění teploty ze systémových snímačů se používá balík lm_sensors. Konkrétně pak program sensors pro určení aktuálních teplot a program sensors_detect pro provedení detekce přítomných měřicích obvodů většinou připojených přes sběrnici I2C.
function ProcessorTemperature($Sensor)
{
$Output = array();
exec('/usr/bin/sensors', $Output);
foreach($Output as $Line)
{
if(substr($Line, 0, strlen($Sensor)) == $Sensor)
{
$Line = substr($Line, strpos($Line, '+') + 1);
$Line = substr($Line, 0, strpos($Line, '°'));
return($Line);
}
}
return(0);
}
Windows
Doplnit varianty systémových skriptů pro Windows.
Volné místo na disku
Tento údaj lze zjistit přímo pomocí PHP a funkce disk_free_space. Např.
echo(disk_free_space('C:\'));
Údaje z databáze
Nejprve je nutné inicializovat databázové spojení před třídu mysqli.
$Database = new mysqli("localhost", "user", "password", "database");
Tyto funkce jsou vytvořeny pro emulátor MaNGOS. Pro ostatní emulátory je potřeba provést patřičné úpravy pro výběr data z databáze.
Počet hráčů online
function WoWPlayersOnline()
{
global $Database;
$Database->select_db('characters');
$DbResult = $Database->query('SELECT COUNT(*) FROM characters WHERE online=1');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Počet GM online
function WoWGMOnline()
{
global $Database;
$Database->select_db('realmd');
$DbResult = $Database->query('SELECT COUNT(*) FROM account WHERE online=1 AND gmlevel > 0');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Počet účtů
function WoWAccountCount()
{
global $Database;
$Database->select_db('realmd');
$DbResult = $Database->query('SELECT COUNT(*) FROM account');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Počet guild
function WoWGuildCount()
{
global $Database;
$Database->select_db('characters');
$DbResult = $Database->query('SELECT COUNT(*) FROM guild');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Počet postav
function WoWCharacterCount()
{
global $Database;
$Database->select_db('characters');
$DbResult = $Database->query('SELECT COUNT(*) FROM `characters`');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Počet restartů
function WoWEmulatorRestartCount()
{
global $Database;
$Database->select_db('mangos');
$DbResult = $Database->query('SELECT COUNT(*) FROM uptime');
$Row = $DbResult->fetch_array();
return($Row[0]);
}
Doba běhu emulátoru
Funkce vrací dobu běhu od posledního startu emulátoru.
function MangosUptime()
{
global $Database;
$Database->select_db('mangos');
$DbResult = $Database->query('SELECT `starttime`, `uptime` FROM `uptime` ORDER BY `starttime` DESC LIMIT 1');
$Row = $DbResult->fetch_array();
return($Row['uptime']);
}
Pokud je potřeba zobrazit informaci v čitelné podobě pro člověka, lze použít navíc tuto funkci. Ta zobrazí samostatně počet dní a k tomu hodiny a minuty.
funcion HumanReadableMangosUptime()
{
$Uptime = MangosUptime();
$Days = floor($Uptime / 3600 / 24);
if($Days == 0) $DaysText = '';
else if($Days == 1) $DaysText = $Days.' den';
else if(($Days > 1) and ($Days < 5)) $DaysText = $Days.' dny';
else if(($Days > 5)) $DaysText = $Days.' dnů';
$Seconds = $Uptime - 3600; // Korekce jedné hodiny, může se lišit
return($DaysText.' '.date('G:i', $Seconds));
}
Počet běžících eventů
Funkce vrací počet aktuálně běžících MaNGOS in-game eventů.
function RunningEventCount()
{
global $Database;
$Count = 0;
$Database->select_db('mangos');
$DbResult = $Database->query('SELECT *, UNIX_TIMESTAMP(start_time) as start FROM game_event WHERE end_time > NOW() AND start_time < NOW()');
while($Row = $DbResult->fetch_array())
{
$Start = (floor((time() - $Row['start']) / ($Row['occurence'] * 60))) * $Row['occurence'] * 60 + $Row['start'];
$End = $Start + $Row['length'] * 60;
if((time() > $Start) and (time() < $End)) $Count++;
}
return($Count);
}
Externí odkazy
- MRTG - Zaznamenávání grafů stavů routerů. Vyžaduje Perl a Linux.
- phpSysInfo - Skript pro zobrazení informací o serveru.
- Dokumentace PHP Manual - Dokumentace k programovacím jazyku [[PHP].