Server Monitor


Autor: Krzysztof Kozłowski
e-mail: k.kozlowski [at] iem.pw.edu.pl
k.kozlowski [at] acn.waw.pl
WWW: http://acn.waw.pl/koziol (http://www.koziol.prv.pl)


Wersja: 1.0.1
Data: 14.01.2006


  1. Opis i cel zadania


    Celem projektu było stworzenie aplikacji do zbierania danych o działaniu serwerów (monitorowania ich). W jej skład wchodzą :
    - klient - uruchamiany cyklicznie na każdym serwerze, kontaktuje się z serwerem centralnym i zdaje informacje o działaniu danego serwera
    - serwer centralny - aplikacja internetowa, która zbiera dane z klientów i pozwala administratorowi przeglądać je

    Monitorowanie danego serwera może obejmować :
    - działanie wybranych usług (np. Apache'a)
    - obciążenie serwera i użycie systemowych zasobów
    - stan sprzętu (dyski z technologią SMART, temperatura podzespołów)
    - problemy związane z bezpieczeństwem (np. nieudane próby logowania)

  2. Opis działania

    Aplikacja kliencka samodzielnie realizuje tylko niektóre z tych "testów". Do wykonania innych potrzebuje zewnętrznych programów (np. hddtmp, mbmon).

    Cała komunikacja pomiędzy klientami, a serwerem centralnym jest szyfrowana, ale odbywa się poprzez protokół HTTP. Daje to prostotę (nie trzeba instalować jakiś demonów do obsługi połączeń od klientów), wygodę i bardzo małe wymagania przy instalacji. Listę serwerów dopuszczonych do komunikacji określa się w aplikacji na serwerze centralnym.

  3. Opis działania kodu

    Aplikacja kliencka została napisana w Pythonie i składa się z krótkiego skryptu (genkey) do wygenerowania kluczy oraz właściwego skryptu (sm), który komunikuje się z serwerem centralnym. sm wczytuje konfigurację z pliku config.py oraz następnie po kolei ładuje testy do wykonania z katalogu tests/. Wykonuje każdy z zaplanowanych testów i wysyła wyniki do centralnego serwera.

    Część serwerowa napisana w PHP składa się z interfejsu WWW dla administratora, ze skryptu (report.php) do przyjmowania połączeń od klientów oraz ze skryptu (check_results.php) do okresowego sprawdzania czy klienci nadesłali wyniki.

    Interfejs WWW został specjalnie zaprojektowany z myślą o łatwej rozbudowie o kolejne elementy.
  4. Opis użytej struktury danych

    Baza danych wykorzystywana jest na serwerze centralnym do przechowywania : Struktura nie jest skomplikowana i całkowicie spełnia wymagania aplikacji. Tabele utworzyć można wykonując ten skrypt SQL.
  5. Wymagania


    a) Serwer centralny.
    - serwer WWW (Apache) z obsługą PHP (>=4.3.0)
    - baza MySQL (testowany na >=4.1)
    - OpenSSL
    lub
    - rozszerzenie "mcrypt" w PHP oraz biblioteka libmcrypt (>=2.4.x)


    b) Klient.
    - Python (testowane tylko na >=2.4), używane moduły:
    - urlib
    - sys
    - os
    - time
    - stat
    - OpenSSL
    - xmbmon (opcjonalnie)
    - hddtemp (opcjonalnie)


  6. Instalacja


    a) Serwer centralny.

    - Wypakuj źródła serwera do katalogu ze stronami WWW.
    - Ustaw konfigurację w pliku "inc/config.php".
    - Utwórz tabele w bazie MySQL (skrypt "mysql_install.sql").
    - Pamiętaj o założeniu tabel dla wszystkich niestandardowych testów (niedołączonych do pakietu). Tabele standardowych testów są uwzględnione w skrypcie instalacyjnym.
    - Ustaw grupę katalogu "keys/" na twój serwer WWW, np.:
    # chgrp www keys
    # chmod o-rwx keys
    - Jeśli chcesz być powiadamiany o braku raportu z danej maszyny
    (np. z powodu jej zawieszenia itp.), to dodaj do crona wpis uruchamiający "check_tests.php" zawsze po spodziewanym czasie zdania raportu od klientów. Przykładowo :
    */5 * * * * /sm/check_tests.php
    lub gdy klienci komunikują się w "zerowej" i 30-tej minucie godziny :
    5,35 * * * * /sm/check_tests.php
    - Reszta przez WWW - dodanie hostów i konfiguracja ich testów.


    b) Klient.

    - Wypakuj źródła klienta do jakiegoś katalogu.
    - Skonfiguruj go edytując plik "config.py".
    - Wygeneruj klucze :
    # ./genkey
    Aktualnie obsługiwany jest tylko 3DES w trybie CBC.
    - Prześlij plik ".iv" oraz ".key" do katalogu "keys/" na serwerze centralnym ustawiając im nazwę na hostname danej maszyny-klienta (nie kasuj rozszerzenia). Pamiętaj też o odpowiednich uprawnieniach, np.:
    # chgrp www keys/*
    # chmod o-rwx keys/*
    - Dodaj maszynę w konfiguracji poprzez WWW na serwerze centralnym. Tam też możesz sprecyzować oczekiwany czas wykonania testu (co ile minut mają być nadsyłane wyniki) oraz same testy.
    - Skonfiguruj każdy z używanych testów w katalogu "tests/", np.:
    - Wyłącz nieużywane poddtesty (jako wartość 'echo "' + TEST_NOT_USED + '"').
    - Dostosuj niuanse systemowe (np. różne komendy dla BSD i Linuksa).
    - Uruchom "sm" i jeśli nie będzie problemów, to dodaj do crona. Pamiętaj, że przy uruchamianiu zadań przez crona nie ma zazwyczaj ustawianej zmiennej PATH, więc przykładowe polecenie może wyglądać tak :
    0,30 * * * * PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin" /sm_client/sm


  7. Dodanie całkowicie nowych testów


    a) Serwer.
    - W katalogu "tests/" tworzymy wedle szablonu "tests/test_template.php" plik do obsługi testu, np. "xxx.php". Musimy ustawić koniecznie :
    - odpowiedni kod SQL do utworzenia tabeli (bardzo istotne są nazwy i typy kolumn odpowiadające podtestom)
    - "$name = 'xxx' ;"
    - tablicę "fields_desc" z długimi opisami poddtestów
    - tablicę "fields" z typami kolumn (zgodne z bazą, ale zamiast VARCHAR należy użyć "string")
    - tablicę "limits" z domyślnymi ograniczeniami dla wyników testu (można zostawić puste - wtedy nie ma ograniczenia).
    - W pliku konfiguracyjnym "inc/config.php" dodajemy test do tablicy "$installed_tests" (klucz - nazwa krótka "xxx", wartość - nazwa długa).

    b) Klient.
    - W katalogu "tests/" tworzymy plik testu z roszerzeniem py, np. "xxx.py".
    Jego zawartość, to minimum :
    from config import *
    TEST_NAME = 'xxx'
    TESTS[TEST_NAME] = {}
    TESTS[TEST_NAME]['test1'] = 'komenda do wykonania'
    - W pliku "config.py" za linią "TESTS_LIST = []" dopisujemy :
    TESTS_LIST.append('xxx')
    - W pliku "sm" za linią :
    "# Dodawanie testow, zaimportuj wszystkie interesujace ciebie testy :"
    dopisujemy :
    from xxx import *