RRDTool

A Unix/Linux szerverek üzemeltetése wikiből

Az RRDTool egy meghatározott időszakról képes adatokat tárolni és ezeket grafikonon megjeleníteni. A tárolt adatok körbeforgó adatbázisban tárolódnak (RRD: Round Robin Database), ahol a legrégebbi adatot írja felül a legújabb. Így az adatbázis mindig ugyanakkora.

Fontos tudni, hogy az RRDTool nem képes összegyűjteni az adatokat. Az információt bizonyos időközönként kell beletölteni, ez történhet Cron-ból vagy akár a munin-nal. Viszont, ha nem sok gépet szeretnénk monitorozni, vagy csak kevés jellemzőt figyelünk, akkor érdemesebb szkriptelni, mert így kevesebb erőforrást használunk fel.

Az erőforrás-gazdálkodás szempontjából fontos lehet az is, hogy ha gyakran és egyszerre többen nézzük a grafikonokat, akkor érdemes bizonyos időközönként ismételve generáltatni a képeket, egyéb esetben akár a php oldal is előállíthatja nekünk, amikor éppen szükség van rá.

A program egyszerű és ebből kifolyólag robusztus, de nem árt rendszeresen mentéseket készíteni az adatbázis állományokról.

A mentéseken kívül a program egyetlen kimeneti megjelenése a grafikon.

Tartalomjegyzék

1 Telepítés és használat

Jelenleg az RRDTool csomagját a legtöbb disztribúció tartalmazza. Így telepítése egyszerű:

$ apt-get install rrdtool

További részletes információ a manpage és a [1] link segítségével kapható.

2 RRD adatbázis állomány elkészítése

Először alaposan át kell gondolni, hogy mit szeretnénk tárolni. Egy létező adatbázist kibővíteni jelenleg még nem lehet.

Hozzunk létre egy adatbázist, amiben a gépünk egyik ethernet interfészének ki- és bemenő forgalmát rögzítjük.

$ rrdtool create localpc_traffic_eth0.rrd \
--step 300 \
DS:traffic_in:COUNTER:600:U:U \
DS:traffic_out:COUNTER:600:U:U \
RRA:AVERAGE:0.5:1:288 \
RRA:AVERAGE:0.5:288:365 \
RRA:MAX:0.5:1:288 \
RRA:MAX:0.5:288:365

Az első paraméter a create, tehát létrehozás.

A második az rrd adatbázis állomány neve, amely 1-19 karakter hosszú lehet és [a-zA-Z0-9_] karaktereket tartalmazhat.

A --step értéke a legkisebb kezelt lépésközt adja másodpercben. Ez a feladattól függ, nekünk most elég az 5 perces lépésköz.

A DS (Data Source) vezeti be az adatforrásokat, paraméterei kettősponttal elválasztva. Az első az adatforrás neve, a második a típusa, a többi argumentum jelentése pedig a típustól függően változik. A típusok:

  • GAUGE: egyszerű szám pl hőmérséklet, létszám, jel-zaj viszony... Paraméterei: heartbeat:min:max
  • COUNTER: számláló, olyan folyamatosan növekvő értékek, amelyek csak a számláló túlcsordulása esetén csökkenhetnek. pl adatforgalom. Az értékek mennyiség/sec formában tárolódnak. Paraméterei: heartbeat:min:max
  • DERIVE: Hasonló a counter-hez, de nincs túlcsordulás ellenőrzés. Paraméterei: heartbeat:min:max
  • ABSOLUTE: A gyorsan túlcsorduló számlálók részére, amelyeket minden kiolvasás után nullázunk. Paraméterei: heartbeat:min:max
  • COMPUTE: Házi feladat.

A típusoktól függő paraméterek magyarázata:

  • Heartbeat: Két adabázis-frissítés között eltelt idő maximuma másodpercben. A heartbeat általában kétszerese a step-nek. Ha ennyi idő elteltével sem érkezik adat, akkor ismeretlen (Unknown) érték lesz letárolva, a grafikonon ez kihagyásként jelentkezik. Ha két adatfeltöltés között több lépésköz is kimaradt, de a heartbeat még nem telt le, akkor a program az előző és a legfrissebb adatból interpolál. Ezért úgy érdemes megválasztani az értéket, hogy a kisebb hibákat elfedje, de a nagy hibák kiderüljenek.
  • Min: A minimális érték. U=Unknown
  • Max: A maximális érték. U=Unknown . Ha min/max esetén a beírandó érték a megadott határokon kívül esik, akkor ismeretlen (Unknown) érték lesz letárolva. Pl forgalomszámlálásnál a szélsőértékek lehetnek a hálózati eszköz vagy kapcsolat által megszabott határok. A min és max értékek segítenek az RRDTool-nak ellenőrizni a friss értékek valósságát.

DS blokkból több is lehet, egymástól szóközzel elválasztva. Esetünkben kettő adatforrást tárolunk. A DS blokkok után következnek az RRA blokkok, amelyek az adatok eltárolását határozzák meg.


Az adatok tárolás előtti előfeldolgozására az alábbi függvények használhatóak (CF, Consolidation Function):

  • AVERAGE: az adott lépésközben beírt adatok átlagát tárolja (nagyobb léptékű megjelenítés esetén is "szép" grafikont ad)
  • MIN: az adott lépésközben beírt adatok maximumát tárolja
  • MAX: az adott lépésközben beírt adatok minimumát tárolja
  • LAST: az adott lépésközben beírt adatok utolsó értékét tárolja

A mód megadása után következik három érték:

  • xff: A lépésközben bevitt adatok ekkora része lehet maximum ismeretlen (UNKNOWN) érték, különben a teljes intervallum értéke UNKNOWN lesz. Értéke általában 0.5.
  • steps: a lépésköz (--step) szorzója, ennyi időközönként tárolunk le egy adatot. Érdemes hozzáigazítani a grafikonhoz.
  • rows: sorok száma, azaz a tárolt rekordok száma.

A mi esetünkben tároljuk az átlagot és a maximumot, 5*1 percenként 288 sort (5min*288=1 nap) és 5*288 percenként 365 sort (1nap*365=1 év). Természetesen a 365 érték nem fog szép éves grafikont adni pl 800 képpont szélesség esetén, ezért érdemes lehet gyakrabban és több sort tárolni, pl 0.5:100:1100. A két utolsó paraméter és a lépésköz szorzata adja az adatbázis körbefordulási idejét. Tehát 100*1100*300sec=382nap.

3 Adatok írása az adatbázisba

$ rrdtool update localpc_traffic_eth0.rrd N:784812356:2697070943

Látható,hogy az update opcióval írunk az adatbázisba. A parancsban látható számok a beírandó értékek, amelyek jelen esetben az RX bytes és TX bytes mezők. A beírandó értékek száma mindig egyezzen meg az adatforrások számával, különben nem történik beírás.

Az parancsban látható N (now) az aktuális idő szerinti beszúrást adja. N a UNIX időszámítás szerinti érték, amit 'date +%s' paranccsal nézhetünk meg.

Több adatot is megadhatunk egyszerre, ilyenkor az időt is meg kell adni:

$ rrdtool update localpc_traffic_eth0.rrd 1198866281:102:880 1198866285:150:1040 1198866290:198:1211

4 Mentés (backup)

Érdemes időközönként mentést készíteni az rrd állományainkról. A mentés kimenete XML formátumú.

$ rrdtool dump localpc_traffic_eth0.rrd  > 20071228_localpc_traffic_eth0_rrd.xml

5 Visszaállítás (restore)

$ rrdtool restore 20071228_localpc_traffic_eth0_rrd.xml localpc_traffic_eth0.rrd

Létező adatbázist nem tudunk így felülírni.

6 Grafikon készítése

Az RRDTool egyik fő feladata, hogy grafikonokat készítsünk vele, amelyeket akár távolról, webes felületen i ki tudunk értékelni. Most egy statikus parancson keresztül mutatom be a képgenerálás opcióit. Természetesen az opciók paramétereit php-ból átadva, az igényeinknek megfelelő felbontású képet kaphatunk a kívánt időszakról.

Kezdjük egy egyszerű képgenerálással:

$ rrdtool graph localpc_traffic_eth0.png \
--imgformat=PNG \
--start=-86400 \
--end=now \
--title="Forgalom : eth0" \
--rigid \
--base=1000 \
--height=96 \
--width=400 \
--upper-limit=2000000 \
--lower-limit=0 \
--vertical-label="bits per second" \
--slope-mode \
--color "BACK#4095FF" \
DEF:a=localpc_traffic_eth0.rrd:traffic_in:AVERAGE \
DEF:b=localpc_traffic_eth0.rrd:traffic_out:AVERAGE \
AREA:cdefa#00CF00:"Inbound" \
LINE1:cdefe#002A97:"Outbound" \

Az eredmény a következő:

Fájl:traffic bytes.png

A parancs így épül fel:

rrdtool graph állománynév [--opciók] [adatforrások (DEF)] [számított adatok] [változók definiálása] [ábrázolási elemek (AREA, LINE ...)] [egyéb szöveges információk]

Ha az állománynév helyére "-" kerül, akko a stdout-ra kerül a kép.

6.1 Grafikai paraméterek

  • Az ábrázolt időszak paraméterei (ezek nélkül az elmúlt 1 nap lesz ábrázolva)
    • --start: az ábrázolás idejének kezdete a jelenhez viszonyítva másodpercekben
    • --end: az ábrázolás idejének vége a jelenhez viszonyítva másodpercekben. A "now" paraméter a jelenlegi időpont.
    • --step: a grafikon felbontását állítja. Alapvetően az RRDTool a pixelek számához igazítja a felbontást. Ha pl a step értéket 3600-ra állítjuk, óránkénti felbontást kapunk.
  • Feliratok (Betűtípus váltást eddig nem találtam...)
    • --title: A kép címe, vízszintes felirat
    • --vertical-label: A függőleges tengely felirata
  • A kép mérete
    • --height: a koordináta rendszer magasságát határozza meg (tehát minden csak a nettó grafikon rész mérete)
    • --width: a koordináta rendszer szélességét határozza meg
    • --only-graph: csak a koordináta rendszer és a grafikonok ábrázolása (minden felirat és szegély nélkül)
  • Limitek (default esetben autoscaling érvényes a grafikonra)
    • --upper-limit: felső határ (nem ismeri a k M és a többi prefixet)
    • --lower-limit: alsó határ (nem ismeri a k M és a többi prefixet)
    • --rigid: Ha ez bevan állítva, akkor a felső és alsó határok szigorúan érvényesülnek. Ha nincs beállítva, akkor a limiteken kívül eső értékekhez méretez az autoscale.
    • --alt-autoscale: a legkisebb és a legnagyobb értékhez méretez (kis változású, de nagy offszettel rendelkező értékek esetén jó lehet)
    • --alt-autoscale-max: a legnagyobb értékhez méretez, az alsó határ 0 lesz, ha máshogy nem rendelkezünk
    • --no-gridfit: a segédrácsot nem illeszti az "egész-pixelekhez". Logaritmikus ábrázolásnál hasznos lehet.
  • Rácsozás
    • --x-grid: a függőleges rácsozás sűrűségét lehet állítani, egész bonyolultan és tetszőlegesen
      • példa: --x-grid MINUTE:10:HOUR:1:HOUR:4:0:%X : vonalak 10 percenként, fő vonalak óránként, felirat 4 óránként, feliratok a fővonalak alatt és pontos időt ábrázolnak
      • példa: --x-grid HOUR:8:DAY:1:DAY:1:0:%A : vonalak 8 óránként, fő vonalak naponta, feliratok naponta, feliratok a fő vonalak alatt és a napok neveit adják
    • --x-grid none : nincs függőleges rácsozás
    • --y-grid gridstep:labelfactor: a vzszintes rácsozás
    • --y-grid none : nincs vízszintes rácsozás
    • --alt-y-grid : automatikus rácsozás, nem túl sűrű, de jól informál
    • --logarithmic: log rácsozás (y rács)
    • --units-exponent <érték> : 10 hatványainál rácsoz. Az érték 3 többszöröse legyen -18 és 18 között (y rács)
    • --units-legth <érték>: Az értékek pontosságának ábrázolása
    • --units=si : Logaritmikus ábrázolás esetén a k,M,stb értékekhez rajzol vonalat. Lineáris ábrázolásnál automatikusan így tesz...
  • További opciók
    • --lazy : Csak akkor generál új képet, ha a meglévő elavult
    • --imginfo 'info': A stdout-ra írja az utána lévő stringet. Mivel a stringbe változókat is képes behelyettesíteni, így például a weboldal számára értelmezhető sort is kiírathatunk vele.
      • Példa: --imginfo '<IMG SRC="/img/%s" WIDTH="%lu" HEIGHT="%lu" ALT="Demo">'
    • --color TAG#rrggbb : A képet színezhetjük vele. A TAG lehet: BACK (háttér), CANVAS (grafikon háttere), SHADEA (bal és felső szegély), SHADEB (jobb és alsó szegély), GRID (rács), MGRID (rács fő vonlak), FONT (felirat), AXIS (tengelyek), FRAME (magyarázó jelek szegélye), ARROW (tengelyvégek). Az #rrggbb színmeghatározás a html-ben ismert kód, ami hexadecimális értékben adja meg az RGB színeket, egyenként 0-255 közötti számmal (fehér: #FFFFFF, fekete: #000000).
    • --zoom <érték>: Nagyítja a képet. Az érték nagyobb legyen, mint 0.
    • --font TAG:méret:[font] : A feliratok stílusát és méretét állítja. TAG lehet:DEFAULT (az összes elem default érték lesz), TITLE, AXIS (tengelyek), UNIT (függőleges mértékegység), LEGEND (jelmagyarázat). A default font az RRD_DEFAULT_FONT környezeti változóban van tárolva. A TrueType font-ok csak PNG esetén támogatottak.
      • Példa: --font TITLE:13:/usr/lib/fonts/times.ttf
      • Példa: --font DEFAULT:0:/usr/lib/fonts/times.ttf , ez nem állítja a méretet
      • Példa: --font TITLE:13: , csak a méretet állítja
    • --font-render-mode {normal,light,mono} : Betűk finomsága
    • --slope-mode: Csökkenti a "lépcsőzetes" megjelenést, ezáltal szebb, de hamisabb ábrázolást kapunk.
    • --imgformat: A kimenet formátuma. Lehet PNG, SVG, PDF, EPS. Nem támogat jpg-t. A vektoros formátumokhoz a Postscript fontok közül válogathatunk: Courier-Bold, Courier-BoldOblique, Courier-Oblique, Courier, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, Helvetica, Symbol, Times-Bold, Times-BoldItalic, Times-Italic, Times-Roman, ZapfDingbats.
    • --interlaced : Gyorsabb megjelenítést tesz lehetővé a böngészők számára.
    • --no-legend : Nincs jelmagyarázat
    • --watermark szöveg: Vízjelezi a képet

6.2 Adatforrások, számított adatok, változók definiálása

Az RRDTool képes a tárolt adatokból újabb értékeket számítani és azokat ábrázolni. Így akár a hálózati forgalom megoszlását is ábrázolhatjuk, akár IP-k szerint, akár a csomagok tartalma szerint. Ehhez a képességhez változókat kell bevezetnünk és használnunk. A számítás az ún. inverz lengyel logika (RPN=Reverse Polish Notation) alapján történik.

6.2.1 DEF:Adatforrások meghatározása:

DEF:<vname>=<rrdfile>:<ds-name>:<CF>[:step=<step>][:start=<time>][:end=<time>][:reduce=<CF>]
    • vname: egy változónév, 255 karakter hosszú lehet és [A-Za-z0-9-_] karaktereket tartalmazhat. A továbbiakban ezzel névvel hivatkozunk az adatra.
    • rrdfile: a forrásfájl
    • ds-name: a létrehozáskor (create) megadott DS név
    • CF: alapvetően a legmegfelelőbb tárolt adatsor (RRA sorok a create-nél) lesz kiválasztva
    • step,start,end,reduce: ismét felülbírálhatjuk az említett paramétereket

6.2.2 VDEF, CDEF: Számítások

6.2.2.1 Az inverz lengyel logika (RPN)

A számítások során az RPN logikát használjuk, melynek lényege röviden, hogy először a művelet tényezői vannak felsorolva, majd utána a műveleti jelek. A feldolgozás során a program vesziaz első műveleti jelet, majd elveszi a tényezőket hozzá a sor elejéről. Az eredményt a helyükre teszi. Példák:

  • var0=a,b,5,+,+ > var0=a+b+5
  • var1=a,b,+,5,/ > var1=(a+b)/5

További RPN lehetőségek: [2]

6.2.2.2 VDEF

A VDEF a megjelenített tartomány értékeit kezeli. Képes megkeresni az értékek átlagát, maximumát, minimumát stb.

VDEF:vname=RPN expression

  • Példák:
    • VDEF:in_avg=in,AVERAGE (ahol az inváltozóba egy DEF sorban tettük bele a adatokat)
    • VDEF:in_min=in,MINIMUM
    • VDEF:in_max=in,MAXIMUM
6.2.2.3 CDEF

A CDEF új adatsort számít a tárolt adatsorokból,de ezeket csak a memóriában tárolja, a képgenerálás idejéig.

CDEF:vname=RPN expression

  • Példa:
    • CDEF:bitek=bajtok,8,* > A bájtokban számlált csomagokat bitekkéalakíthatjuk, hogy bps-ben ábrázoljuk a forgalmat

6.3 Ábrázolási elemek, egyéb szöveges információk

  • PRINT:vname:format : Az stdout-ra ír, a c nyelv printf függvényéhez hasonló formázott kiratást tesz lehetővé. Bővebben: [3]
  • GPRINT:vname:format : Min a PRINT, csak a generált képre ír.
  • VRULE:time#color[:legend] : Függőleges vonalat húz a megadott időpontnál a megadott színnel
  • HRULE:value#color[:legend] : Vízszintes vonalat rajzol a megadott értékhez
  • LINE[width]:value[#color][:[legend][:STACK]] : Vonalgörbét rajzol. A vonal vastagsága a lebegőpontos szám.
  • AREA:value[#color][:[legend][:STACK]] : A görbepontok étékei és az X tengely közötti részt színnel kitölti
  • TICK:vname#rrggbb[aa][:fraction[:legend]] : ...
  • SHIFT:vname:offset : Időben eltolva jelenít meg. Az offset másodpercekben értendő. Régebbi adatokat ábrázolhatunk vele (pl előző hét)

7 Példák az alkalmazásra

Tulajdonképpen bármit ábrázolhatunk, amit pl a /proc könyvtárból ki tudunk hámozni, vagy akár snmp-ben, xml-ben vagy bármilyen más szöveges formátumban elő tudunk állítani.

Nézzünk néhány példát, hogy hogyan állítsuk elő a megfelelő információkat (ez hasonló, mint munin-hoz plugin-t rni, így akár a munin kész plugin-jeiből is vehetünk ötleteket, ha ismerjük a perl nyelvet)

  • Saját gépünk paramétereinek monitorozása
    • Hálózati forgalom
    • Terhelés, átlagterhelés
  • Más, linuxos gépek monitorozása
  • "Szép" grafikonok előállítása
  • Trend számítása és ábrázolása a gyűjtött adatokból
rrdtool graph trend.png --start='-1 month' --end now
DEF:ds0a=adat.rrd:value:AVERAGE \
LINE1:ds0a#0000FF:"Adat" 
VDEF:H=ds0a,LSLINT \
VDEF:D=ds0a,LSLSLOPE \
VDEF:C=ds0a,LSLCORREL \
CDEF:Proj=ds0a,POP,D,COUNT,*,H,+ \
LINE1:Proj#FF0000:"Trend" \
GPRINT:C:"Korrelacio: %6.2f"

A CDEF-ben megfigyelhető, hogy az aktuális értéket egyből ki is vesszük a veremből, nem használjuk fel. Erre azért van szükség, mert az rrdtool nem enged CDEF-et DEF-ben vagy CDEF-ben definiált változó nélkül, nekünk azonban ilyen értékre nincs szükségünk a trendbecsléshez.

Ha azt szeretnénk, hogy a trendbecslő a jövőre vonatkozó becsült értékeket is kirajzoljon, --end now helyett írjunk valami olyasmit, hogy --end now + 1 day.


Személyes eszközök