LINUX.ORG.RU
ФорумAdmin

Мониторинг сервисов на Windows с выгрузкой на сайт Batch + VBS + PHP

 , , , ,


0

1

Здравствуйте! Наблюдать за работой сервера, на котором работают базы данных и другие сервисы (службы), используемые локальной сетью, можно так.

Скрипт проверяет работу трёх сервисов, имена которых заданы в массиве srv, формирует GET-запрос и отправляет на сайт.

Листинг файла netstart.bat

:: Batch-script put info about services to a web-server
@echo off
setlocal

net start > C:\my-services\netstart.txt

"C:\Program Files (x86)\GnuWin32\bin\iconv.exe" -f IBM866 -t UTF-8 C:\my-services\netstart.txt > C:\my-services\netstart-utf8.txt


::Массив служб name- имя службы, stat - статус (unknown, error, ok)
set len=3
set srv[0].name=Диспетчер печати
set srv[0].stat=unknown
set srv[1].name=Защитник Windows
set srv[1].stat=unknown
set srv[2].name=Служба автонастройки WLAN
set srv[2].stat=unknown


:: Check services work
set i=0
:SrvLoop
if %i% equ %len% goto :elSrv
set cur.name=
set cur.stat=
for /f "usebackq delims==. tokens=1-3" %%j in (`set srv[%i%]`) do (
  set cur.%%k=%%l
)
::echo Проверяется работа службы %cur.name%
SET status=error
findstr /m "%cur.name%" netstart.txt
if %errorlevel%==0 (
  SET status=ok
)
SET srv[%i%].stat=%status%
set /a i=%i%+1
goto SrvLoop
:elSrv

::echo Все службы проверены.


:: Display services statuses
::set i=0
::SDLoop
::if %i% equ %len% goto :elSD
::set cur.name=
::set cur.stat=
::for /f "usebackq delims==. tokens=1-3" %%j in (`set srv[%i%]`) do (
::  set cur.%%k=%%l
::)
::echo Служба %cur.name%
::echo Статус %cur.stat%
::set /a i=%i%+1
::goto SDLoop
::elSD



:: Create get request
set req=?line=
set i=0
:ReqLoop
if %i% equ %len% goto :elReq
set cur.name=
set cur.stat=
for /f "usebackq delims==. tokens=1-3" %%j in (`set srv[%i%]`) do (
  set cur.%%k=%%l
)
SET req=%req%service%i%--%cur.name%-ampersand-status%i%--%cur.stat%-ampersand-
set /a i=%i%+1
goto ReqLoop
:elReq



SET url=http://server-status.online/win1/set.php%req%
SET "url=%url: =+%"
::echo "url - \n" "%url%"


:: Send pull request to web-server
C:\my-services\curl\bin\curl.exe "%url%"

::echo ''
endlocal

В Windows файл должен быть сохранён с кодировкой OEM 866, чтобы корректно работали русские названия сервисов. Можно указать имена нужных сервисов (типа Oracle, IIS и прочее).

Для работы скрипта и отправки информации на сайт, нужно указать путь к curl. Строка C:\my-services\curl\bin\curl.exe «%url%»

В Планировщик задач Windows добавлено задание, которое регулярно (раз в минуту) запускает этот скрипт. Чтобы задание не открывало окно Командной строки, добавлено через vbs.

Листинг файла netstart.vbs

Set WshShell = CreateObject("WScript.Shell") 
WshShell.Run chr(34) & "C:\my-services\netstart.bat" & Chr(34), 0
Set WshShell = Nothing

На стороне сервера размещены три скрипта: set.php - добавить строку, get.php - отобразать все записи, del.php - удалить все записи. Также файл базы данных - db.txt.

Листинг файла set.php

<?php

// full path to db file
define("DB_FILE", "db.txt");

$line=iconv("WINDOWS-1251","UTF-8",$_GET["line"]);

echo $line;

$f=fopen(DB_FILE, "a");
fwrite($f, $line."--".time()."\n");

echo "<br>done!";

?>

Так как Командная строка Windows работает в кодировке OEM866, декодируется в UTF-8, добавляется timestamp и записывается в db.txt.

Просмотр состояния сервисов реализован в файле get.php, который отображает последнюю строку. Если находит слово 'error', то ставит бэкграунд странцы красным. Если информация давно не поступала от сервера - серый фон.

Листинг файла get.php

<?php

// full path to db file
define("DB_FILE", "db.txt");
//seconds between messages to check server online
define("PERIOD", 80);
 
 
function read_tail($file, $lines) {
    //global $fsize;
    $handle = fopen($file, "r");
    $linecounter = $lines;
    $pos = -2;
    $beginning = false;
    $text = array();
    while ($linecounter > 0) {
        $t = " ";
        while ($t != "\n") {
            if(fseek($handle, $pos, SEEK_END) == -1) {
                $beginning = true; 
                break; 
            }
            $t = fgetc($handle);
            $pos --;
        }
        $linecounter --;
        if ($beginning) {
            rewind($handle);
        }
        $text[$lines-$linecounter-1] = fgets($handle);
        if ($beginning) break;
    }
    fclose ($handle);
    return array_reverse($text);
}
 

// main start
if (isset($_GET["mode"]) && $_GET["mode"]=="full") {
	$f=file_get_contents(DB_FILE);
	echo "<pre>".$f."</pre>";

} elseif (isset($_GET["n"]) && is_numeric($_GET["n"])) {
	$fsize = round(filesize(DB_FILE)/1024,2);
	echo "File size is {$fsize} Kb\n\n<br>";
	echo "Last ".$_GET["n"]." lines of the file:\n\n<br><br>";
	echo "<pre>\n";
	$lines = read_tail(DB_FILE, $_GET["n"]);
	foreach ($lines as $line) {
		echo $line;
	}
	echo "</pre>\n";

} else {
	//readl last line
	$f=fopen(DB_FILE, "r");
	$cursor = -1;
	fseek($f, $cursor, SEEK_END);
	$char = fgetc($f);
	// Trim trailing newline chars of the file
	while ($char === "\n" || $char === "\r") {
		fseek($f, $cursor--, SEEK_END);
		$char = fgetc($f);
	}
	// Read until the start of file or first newline char
	while ($char !== false && $char !== "\n" && $char !== "\r") {
		//Prepend the new char
		$line = $char . $line;
		fseek($f, $cursor--, SEEK_END);
		$char = fgetc($f);
	}
	
	preg_match("/error/", $line, $matches);
	$c = count($matches);
	// check errors and on-line status
	if (count($matches) > 0 ) { 
		echo "<body bgcolor=red>\n"; 
	} else { 
		//get time from line and compare with current time
		preg_match("/--(\d\d\d\d\d\d\d+)/", $line, $match_time);
		//print_r($match_time);
		$diff = intval(time()) - intval($match_time[1]);
		//echo "diff = $diff ";
		if ($diff > PERIOD) {
			//set grey background if time differs more than PERIOD seconds
			echo "<body bgcolor=grey>\n";
		} else {
			//set green background if ok
			echo "<body bgcolor=green>\n"; 
		}
	}
	
	echo $line;
}

echo "<br>done!";

?>

Мониторить в браузере можно по ссылке server-status.online/win1/get.php. По умолчанию отображается только последняя зпись, то есть server-status.online/win1/get.php?n=1, можно также вывести несколько записей server-status.online/win1/get.php?n=12 или все записи server-status.online/win1/get.php?mode=full .

Обнуление базы данных (файла db.txt) - файл del.php

Листинг файла del.php

<?php


// full path to db file
define("DB_FILE", "db.txt");

file_put_contents(DB_FILE, "");

echo "<br>clear!";

?>
★★