Zbieranie różnych danych statystycznych w OpenWrt
Ostatnia zmiana: 2014-04-09 22:35

Strona projektu: http://collectd.org/

Collectd jest demonem zbierającym dane i zapisującym je w różnorodnej postaci. Sam z siebie nie potrafi rysować wykresów, ale dzięki odpowiednim pluginom można te dane gromadzić i obrabiać w dowolnym programie. Najczęściej wykorzystywane jest zapisywanie danych w plikach RRD, z których można prosto wygenerować wykresy dzięki narzędziu RRDtool.
Siłą tego programu jest duża liczba pluginów pozwalająca na zbieranie danych z dowolnych źródeł. Jeżeli z jakiegoś powodu nie znajdziemy odpowiedniego pluginu, istnieje możliwość wykonania dowolnego programu lub skryptu, dzięki czemu możliwości tego programu stają się nieograniczone. Główne jego zastosowanie to różnorodne zbieranie statystyk w celu późniejszej prezentacji.
Poniższe rozwiązanie sprawdzono w OpenWrt Attitude Adjustment 12.09.



Instalacja



    # opkg update
    # opkg install collectd

Sam program to jeszcze za mało, należy zainstalować wymagane pluginy. W chwili pisania tego opisu w OpenWrt dostępne były następujące:


  • collectd-mod-apache: apache status input plugin
  • collectd-mod-apcups: apcups status input plugin
  • collectd-mod-ascent: ascent status input plugin
  • collectd-mod-bind: BIND server/zone input plugin
  • collectd-mod-conntrack: connection tracking table size input plugin
  • collectd-mod-contextswitch: context switch input plugin
  • collectd-mod-cpu: CPU input plugin
  • collectd-mod-csv: CSV output plugin
  • collectd-mod-curl: cURL input plugin
  • collectd-mod-dbi: relational database input plugin
  • collectd-mod-df: disk space input plugin
  • collectd-mod-disk: disk usage/timing input plugin
  • collectd-mod-dns: DNS traffic input plugin
  • collectd-mod-email: email output plugin
  • collectd-mod-exec: process exec input plugin
  • collectd-mod-filecount: file count input plugin
  • collectd-mod-fscache: file-system based caching framework input plugin
  • collectd-mod-interface: network interfaces input plugin
  • collectd-mod-iptables: iptables status input plugin
  • collectd-mod-irq: interrupt usage input plugin
  • collectd-mod-iwinfo: libiwinfo wireless statistics plugin
  • collectd-mod-load: system load input plugin
  • collectd-mod-logfile: log files output plugin
  • collectd-mod-madwifi: MadWifi status input plugin
  • collectd-mod-memory: physical memory usage input plugin
  • collectd-mod-mysql: MySQL status input plugin
  • collectd-mod-netlink: netlink input plugin
  • collectd-mod-network: network input/output plugin
  • collectd-mod-nginx: nginx status input plugin
  • collectd-mod-ntpd: NTP daemon status input plugin
  • collectd-mod-olsrd: OLSRd status input plugin
  • collectd-mod-openvpn: OpenVPN traffic/compression input plugin
  • collectd-mod-ping: ping status input plugin
  • collectd-mod-postgresql: PostgreSQL status input plugin
  • collectd-mod-powerdns: PowerDNS server status input plugin
  • collectd-mod-processes: process status input plugin
  • collectd-mod-protocols: network protocols input plugin
  • collectd-mod-rrdtool: RRDtool output plugin
  • collectd-mod-snmp: SNMP input plugin
  • collectd-mod-syslog: syslog output plugin
  • collectd-mod-table: table-like structured file input plugin
  • collectd-mod-tail: tail input plugin
  • collectd-mod-tcpconns: TCP connection tracking input plugin
  • collectd-mod-teamspeak2: TeamSpeak2 input plugin
  • collectd-mod-ted: The Energy Detective input plugin
  • collectd-mod-thermal: system temperatures input plugin
  • collectd-mod-unixsock: unix socket output plugin
  • collectd-mod-uptime: uptime status input plugin
  • collectd-mod-users: user logged in status input plugin
  • collectd-mod-vmem: virtual memory usage input plugin
  • collectd-mod-wireless: wireless status input plugin
  • collectd-mod-write-http: HTTP POST output plugin
Mamy więc pluginy zbierające dane z UPS, sprawdzające statusy serwerów dns, baz danych i innych demonów, monitorujące wykorzystanie procesora, przerwań, pamięci dysku, dane statystyczne z systemów plików, interfejsów, dane z czujników, interfejsów bezprzewodowych. Można zbierać dane z SNMP (dzięki czemu można gromadzić dane z innych urządzeń do których można podłączyć się w ten sposób) a także zbierać dane przez wykonanie dowolnego skryptu lub programu. Dostępny jest plugin iptables potrafiący zbierać dane z różnych łańcuchów (więc nic nie stoi na przeszkodzie aby zbierać statystyki dla poszczególnych hostów).

Instalujemy więc kilka z nich:


    # opkg install collectd-mod-cpu collectd-mod-df collectd-mod-interface 
    # opkg install collectd-mod-load collectd-mod-memory collectd-mod-wireless 
    # opkg install collectd-mod-ping collectd-mod-iwinfo

Ten zestaw zapewni nam informacje o obciążeniu i wykorzystaniu procesora, zużyciu pamięci, ilość wolnej przestrzeni na dyskach, ilości przesłanych bajtów przez interfejsy a także np. dostępność łącza internetowego przez wizualizację czasu odpowiedzi pingu.
Pluginy te służą do zbierania danych, a należy jeszcze je gdzieś przechowywać. Można to zrobić instalując plugin CSV zapisujący dane w tym formacie


    # opkg install collectd-mod-csv

lub w plikach RRD niezbędnych w późniejszym czasie do generowania wykresów


    # opkg install collectd-mod-rrdtool

Konfiguracja

Plik konfiguracyjny to /etc/collectd.conf. Jego składnia jest dość prosta: na początku znajdują się opcje globalne dla collectd:


    BaseDir     "/var/lib/collectd"
    PIDFile     "/var/run/collectd.pid"
    Interval    30
    ReadThreads 2

Każdy plugin ładujemy poleceniem LoadPlugin nazwa, np:


    LoadPlugin ping

Jeżeli plugin wymaga jakiś opcji konfiguracyjnych lub chcemy jakieś zmienić należy utworzyć sekcję <Plugin nazwa> </Plugin> i podać parametry. Dla wspomnianego pluginu ping, w przypadku potrzeby pingowania np. DNS Google może to wyglądać następująco:


    <Plugin ping>
        Host "8.8.8.8"
    </Plugin>

Jeżeli nie podamy danych - zostaną przyjęte wartości domyślne. Opcje pluginów są bardzo dobrze udokumentowane, należy więc zapoznać się z odpowiednim fragmentem dokumentacji przy konfiguracji pluginu.

Dla wspomnianego zestawu pluginów plik konfiguracyjny może wyglądać następująco:


    BaseDir     "/var/lib/collectd"
    PIDFile     "/var/run/collectd.pid"
    Interval    30
    ReadThreads 2
    LoadPlugin cpu
    LoadPlugin df
    LoadPlugin interface
    LoadPlugin load
    LoadPlugin memory
    LoadPlugin rrdtool
    LoadPlugin wireless
    LoadPlugin ping
    LoadPlugin iwinfo
    <Plugin ping>
        Host "8.8.8.8"
    </Plugin>
    <Plugin rrdtool>
        DataDir "/mnt/sda1/rrd"
        RRARows 100
        RRASingle 1
        RRATimespan 600
        RRATimespan 3600
        RRATimespan 86400
        RRATimespan 604800
        RRATimespan 2678400
        RRATimespan 31622400
    </Plugin>

Szczegółowo został skonfigurowany plugin rrdtool, wykorzystując katalog /mnt/sda1/rrd do tworzenia pliku danych gromadzonych pomiary w okresie 10 minut, jednej godziny, jednego dnia, jednego tygodnia, jednego miesiąca i jednego roku.

Uruchomienie



    # /etc/init.d/collectd enable
    # /etc/init.d/collectd start

Wcześniej należy zadbać o prawidłowe ustawienie daty i godziny systemowej. Po uruchomieniu demon zbiera dane w katalogu /mnt/sda1/rrd, na podstawie parametrów zdefiniowanych w pliku konfiguracyjnym. Niestety dane wynikowe są w mało czytelnej postaci i warto przekształcić je na wykresy.

Wykresy

Pliki RRD są to bazy danych, w określonym formacie, przechowujące dane wg określonych parametrów podanych podczas ich tworzenia. Obróbką tych danych może zająć się program RRDtool, który pozwala m.in. na wyciąganie danych i generowanie plików graficznych.


    # opkg install rrdtool1

Informacje o pliku

Sprawdźmy jakie dane przechowuje taki plik RRD - np. z danymi od pluginu ping:


    # rrdtool info /mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd
filename = "/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd"
rrd_version = "0001"
step = 30
last_update = 1363598694
ds[ping].type = "GAUGE"
ds[ping].minimal_heartbeat = 60
ds[ping].min = 0.0000000000e+00
ds[ping].max = 6.5535000000e+04
ds[ping].last_ds = "UNKN"
ds[ping].value = 3.9543297360e+03
ds[ping].unknown_sec = 0
rra[0].cf = "AVERAGE"
rra[0].rows = 100
rra[0].pdp_per_row = 1
rra[0].xff = 1.0000000000e-01
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 0
rra[1].cf = "MIN"
rra[1].rows = 100
rra[1].pdp_per_row = 1
rra[1].xff = 1.0000000000e-01
rra[1].cdp_prep[0].value = NaN
rra[1].cdp_prep[0].unknown_datapoints = 0
rra[2].cf = "MAX"
rra[2].rows = 100
rra[2].pdp_per_row = 1
rra[2].xff = 1.0000000000e-01
rra[2].cdp_prep[0].value = NaN
rra[2].cdp_prep[0].unknown_datapoints = 0
rra[3].cf = "AVERAGE"
rra[3].rows = 120
rra[3].pdp_per_row = 1
rra[3].xff = 1.0000000000e-01
rra[3].cdp_prep[0].value = NaN
rra[3].cdp_prep[0].unknown_datapoints = 0
rra[4].cf = "MIN"
rra[4].rows = 120
rra[4].pdp_per_row = 1
rra[4].xff = 1.0000000000e-01
rra[4].cdp_prep[0].value = NaN
rra[4].cdp_prep[0].unknown_datapoints = 0
rra[5].cf = "MAX"
rra[5].rows = 120
rra[5].pdp_per_row = 1
rra[5].xff = 1.0000000000e-01
rra[5].cdp_prep[0].value = NaN
rra[5].cdp_prep[0].unknown_datapoints = 0
rra[6].cf = "AVERAGE"
rra[6].rows = 103
rra[6].pdp_per_row = 28
rra[6].xff = 1.0000000000e-01
rra[6].cdp_prep[0].value = 3.5622209716e+03
rra[6].cdp_prep[0].unknown_datapoints = 0
rra[7].cf = "MIN"
rra[7].rows = 103
rra[7].pdp_per_row = 28
rra[7].xff = 1.0000000000e-01
rra[7].cdp_prep[0].value = 1.1713506000e+02
rra[7].cdp_prep[0].unknown_datapoints = 0
rra[8].cf = "MAX"
rra[8].rows = 103
rra[8].pdp_per_row = 28
rra[8].xff = 1.0000000000e-01
rra[8].cdp_prep[0].value = 2.6052363000e+02
rra[8].cdp_prep[0].unknown_datapoints = 0
rra[9].cf = "AVERAGE"
rra[9].rows = 101
rra[9].pdp_per_row = 201
rra[9].xff = 1.0000000000e-01
rra[9].cdp_prep[0].value = 2.5435662137e+04
rra[9].cdp_prep[0].unknown_datapoints = 0
rra[10].cf = "MIN"
rra[10].rows = 101
rra[10].pdp_per_row = 201
rra[10].xff = 1.0000000000e-01
rra[10].cdp_prep[0].value = 6.2110382600e+01
rra[10].cdp_prep[0].unknown_datapoints = 0
rra[11].cf = "MAX"
rra[11].rows = 101
rra[11].pdp_per_row = 201
rra[11].xff = 1.0000000000e-01
rra[11].cdp_prep[0].value = 2.8323346740e+02
rra[11].cdp_prep[0].unknown_datapoints = 0
rra[12].cf = "AVERAGE"
rra[12].rows = 101
rra[12].pdp_per_row = 892
rra[12].xff = 1.0000000000e-01
rra[12].cdp_prep[0].value = 3.8038554151e+04
rra[12].cdp_prep[0].unknown_datapoints = 308
rra[13].cf = "MIN"
rra[13].rows = 101
rra[13].pdp_per_row = 892
rra[13].xff = 1.0000000000e-01
rra[13].cdp_prep[0].value = 6.2110382600e+01
rra[13].cdp_prep[0].unknown_datapoints = 308
rra[14].cf = "MAX"
rra[14].rows = 101
rra[14].pdp_per_row = 892
rra[14].xff = 1.0000000000e-01
rra[14].cdp_prep[0].value = 2.9323911280e+02
rra[14].cdp_prep[0].unknown_datapoints = 308
rra[15].cf = "AVERAGE"
rra[15].rows = 101
rra[15].pdp_per_row = 10540
rra[15].xff = 1.0000000000e-01
rra[15].cdp_prep[0].value = 3.8038554151e+04
rra[15].cdp_prep[0].unknown_datapoints = 4580
rra[16].cf = "MIN"
rra[16].rows = 101
rra[16].pdp_per_row = 10540
rra[16].xff = 1.0000000000e-01
rra[16].cdp_prep[0].value = 6.2110382600e+01
rra[16].cdp_prep[0].unknown_datapoints = 4580
rra[17].cf = "MAX"
rra[17].rows = 101
rra[17].pdp_per_row = 10540
rra[17].xff = 1.0000000000e-01
rra[17].cdp_prep[0].value = 2.9323911280e+02
rra[17].cdp_prep[0].unknown_datapoints = 4580

(w pliku są już zgromadzone pewne dane).

Generowanie wykresu

Znając możliwości RRDtool można wygenerować na podstawie tych danych odpowiedni plik graficzny, np:


    # rrdtool graph /www/ping-8.8.8.8-1hour.png -t "OpenWrt/ping/ping-8.8.8.8 1hour" --imgformat PNG --width 600 --height 100 --start now-1hour --end now --interlaced  DEF:ping_avg=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:AVERAGE DEF:ping_max=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:MAX  AREA:ping_max#ffe8e8  LINE2:ping_avg#ff7777:ping GPRINT:ping_avg:AVERAGE:%5.1lf%sAvg GPRINT:ping_max:MAX:%5.1lf%sMax >/dev/null 2>&1
    # rrdtool graph /www/ping-8.8.8.8-1day.png -t "OpenWrt/ping/ping-8.8.8.8 1day" --imgformat PNG --width 600 --height 100 --start now-1day --end now --interlaced  DEF:ping_avg=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:AVERAGE DEF:ping_max=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:MAX  AREA:ping_max#ffe8e8  LINE2:ping_avg#ff7777:ping GPRINT:ping_avg:AVERAGE:%5.1lf%sAvg GPRINT:ping_max:MAX:%5.1lf%sMax >/dev/null 2>&1
    # rrdtool graph /www/ping-8.8.8.8-1week.png -t "OpenWrt/ping/ping-8.8.8.8 1week" --imgformat PNG --width 600 --height 100 --start now-1week --end now --interlaced  DEF:ping_avg=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:AVERAGE DEF:ping_max=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:MAX  AREA:ping_max#ffe8e8  LINE2:ping_avg#ff7777:ping GPRINT:ping_avg:AVERAGE:%5.1lf%sAvg GPRINT:ping_max:MAX:%5.1lf%sMax >/dev/null 2>&1
    # rrdtool graph /www/ping-8.8.8.8-1month.png -t "OpenWrt/ping/ping-8.8.8.8 1month" --imgformat PNG --width 600 --height 100 --start now-1month --end now --interlaced  DEF:ping_avg=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:AVERAGE DEF:ping_max=/mnt/sda1/rrd/OpenWrt/ping/ping-8.8.8.8.rrd:ping:MAX  AREA:ping_max#ffe8e8  LINE2:ping_avg#ff7777:ping GPRINT:ping_avg:AVERAGE:%5.1lf%sAvg GPRINT:ping_max:MAX:%5.1lf%sMax >/dev/null 2>&1

Generuje to w katalogu /www cztery pliki PNG będące wykresami średniego czasu ping do hosta 8.8.8.8 (DNS Google) w przedziale 1 godziny, 1 dnia, 1 tygodnia i jednego miesiąca.



Wyświetlanie na stronie WWW

O ile nie mamy zainstalowanego serwera www to należy wykonać to teraz i go uruchomić:


    # opkg install uhttpd
    # /etc/init.d/uhttpd enable
    # /etc/init.d/uhttpd start

A następnie utworzyć stronę zawierającą te wykresy:


    # echo "<html><body><img src=ping-8.8.8.8-1hour.png><br><img src=ping-8.8.8.8-1day.png><br><img src=ping-8.8.8.8-1week.png><br><img src=ping-8.8.8.8-1month.png></body></html>" > /www/wykres.html

Wczytujemy w przeglądarce stronę http://192.168.1.1/wykres.html i oglądamy rezultat naszych działań.

Poniżej zaprezentowane kilka różnych wykresów:

















Generowanie wykresów ze wszystkich plików

Jeżeli zainstalowaliśmy dużo pluginów to plików z danymi RRD jest bardzo dużo (w tym przykładzie: 44). Próba ręcznego utworzenia skryptów tworzących wykresy jest dość pracochłonna i wymaga pewnego nakładu czasu na jego przygotowanie. Można sprawę uprościć uruchamiając odpowiedni skrypt który samodzielnie wygeneruje wszystkie wykresy; taki skrypt jest zawarty w pakiecie źródłowym collectd pod nazwą collectd2html.pl i wymaga do działania perla. Jego instalacja:


    # opkg install perl
    # opkg install perlbase-essential perlbase-fatal
    # opkg install perlbase-file perlbase-getopt
    # wget http://dl.eko.one.pl/projekty/collectd/collectd2html.px -O /bin/collectd2html.pl
    # chmod 777 /bin/collectd2html.pl

Jego uruchomienie w bieżącym katalogu spowoduje wygenerowanie odpowiednich podkatalogów wraz z plikami graficznymi oraz samego pliku indeksu:


    # cd /www
    # collectd2html.pl

Generowany plik indeksu ma nazwę nazwa_hosta.xhtml, wystarczy więc jeszcze zrobić odpowiedni link:


    # ln -s /www/OpenWrt.xhtml /www/wykresy.html

I wczytać w przeglądarce adres http://192.168.1.1/wykresy.html

Domyślny wygląd strony nie należy do najładniejszych, ale generuje za nas wszystkie wymagane pliki. Jeżeli ktoś jest dociekliwy to pod tym linkiem można znaleźć listę poleceń dzięki którym zostały wykresy utworzone. Można więc zrezygnować z perla i tego skryptu, ręcznie generując wykresy wg własnych parametrów.

Cykliczne generowanie wykresów

Mając już skrypt służący do generowania danych można go wykonać cyklicznie w cronie. np.


    # echo "*/10 * * * * collectd2html.pl" >> /etc/crontabs/root
    # /etc/init.d/cron enable
    # /etc/init.d/cron start

Zakończenie

Przy odrobinie znajomości HTML można utworzyć lub przerobić samodzielnie plik indeksu, robić inne tytuły, kolory wykresów, szablon strony itd. Należy pamiętać że generowanie wykresów trwa parę sekund i może obciążać system, szczególnie jeżeli danych do obróbki jest dość dużo.

LuCI

Jeżeli mamy środowisko graficzne LuCI to nie należy zapominać że mamy dostępne statystki bazujące na collectd. Wszystko co musimy zrobić to zainstalować odpowiedni aplet


    # opkg install luci-app-statistics

A następnie zresetować lub uruchomić generator pliku konfiguracyjnego


    # /etc/init.d/luci_statistics start

Same wykresy dostępne są w zakładce Statistics/Graphs i zawierają predefiniowane wykresy dla pamięci, procsora, sieci bezprzewodowej, obciążenia systemu oraz interfejsów.