Yra kalnas prirašytų skriptų, renkančių statistiką į RRD. Bėda ta, kad jie nėra nei pakankamai lankstūs (kas dar nėra didelė problema, nes skriptus galima lanksčiai koreguoti), bet tame kad jie valgo per daug sistemos resursų. Tame tarpe galima paminėti cacti su savo cactid polleriu (kas yra php perrašytas su C, bet dar nelabai korektiškai veikiantis) - labai jau kreivas DEF/CDEF reguliavimas, output formato nelankstumas, lokaliai skriptai renkantys statistiką yr stabdys, o per SNMP reikia lipdytis savo MIB'us; galima paminėti rrd.cgi kas irgi yra stabdys šiuo požiūriu, taipogi ir Serverstats - kas yra tik php skriptų kratinys...
Dažniausiai sakyčiau reikalingi du variantai - vienas, kai visa statistika centralizuotai surinkinėjama ir graphinama viename hostekuris jau per snmp ar scp nusirenka duomenis iš kitų hostų (tada ir cacti daugiau mažiau tinka, nors yra ir kalnas kitų alternatyvų), arba reikia simple mažo ir greito būdo nupiešt konkrečius grafikus konkrečiam kompui. Tas hostas nebūtinai turi pats hostinti grafikus, bet statistiką reikia nurinkti būtent iš jo. Greit ir paprastai. Be kilometrinių awk'o skriptų, nesinaudojant dešimties aukštų grep'ais ir kitu stufu...
Nemanau kad reta situacija, kai koks nors tikrai busy hostas, kuriam reikia "fine tuning" (o tuo pačiu ir grafikų tam tikslui) dar vargs su statistikos piešimu, leisdamas tam pora minučių kas penkias minutes - tai būtų visai nelogiška. Lygiai taip pat nelogiškas ir variantas kai koks nors statistikos surinkimo skriptas kiekvienam hostui atskirai paleidžia kokius tris binarnykus - rrdtool, awk ir grep. Jei turim tris šimtus hostų, tai paskaičiuokit kiek reikės stufo paleist kas kiekvienas 5 minutes. Na gerai, tegu ir nestabdo DABAR tai, tegu ten kompas stovi tik tam tikslui, bet....
Tarkim reikia mysql statistikos. Viskas yra gan paprasta - tarkim skiptas, kuris jungiasi vartotojo, turinčio tik USAGE teises prie duomenų bazės, pasiima "SHOW STATUS;" (ar netgi SHOW STATUS LIKE 'handler%'; - jei tiksliai žinoma ko reikia ir nieko daugiau neimsim) ir atsijungia. Po to su awk'u atsirenkam tik skaičiukus ar reikšmes kurių tikrai reikia, iškviečiam rrdtool ir update'inam duomenis RRA. O jei reikia daugiau duomenų? Dirbt bash'e su array? Palikt visą darbą awk'ui? O jei dar tie duomenys gan išsibarstę? Tada ir skriptas gaunas ratais zigzagais, ir rrdtool kviečiamas ne vieną kartą... Kitaip sakant - yra toks dalykas kaip mysqlard - realizacija miniatiūrinio daemono su C, linkintas su libmysqlclient bei rrd lib'ais; tik renka per mažai duomenų (ir šiaip, jis šiek tiek senokas pagal viską) - pavyzdžiui com_select ir questions santykis - visai ne tas pats kai enablinamas qcache. Paprasčiau - reikia jį papildyti, kad rinktų kur kas daugiau statistikos nei kad dabar renka.
Analogiška situacija ir su sistemos statistika. Tarkim visai nesunku pakišti top'ui atitinkamą .toprc ir leist jį batch mode (ar su -n 1 ir mažu delay) bei nusirinkti duomenis iš jo. Po to pakišus kokiam awk'ui viską suskaičiuoti ir gauti tai ko reikia. Galima parsinti /proc/stat ir gauti panašų rezultatą. Bet vėlgi - jei jau sukas tarkim skriptas mysql statistikai, kokiai nors network statistikai, dar + šitas - gaunam kalną rrdtool binarniko iškvietimų, krūvą darbo awk'ui, kuris irgi kviečiamas xxx kartų ir galutiniam rezultate gaunam kad statistika jau įtakoja ir realų darbą.
Galutinis rezultatas - vienas binarnykas, daemonas kuris sukasi backgrounde, nevalgo daug RAM, neleakina ir nurinkinėja duomenis nevalgydamas per daug resursų
Reikia gauti tokius duomenis :
Mysql:
Query cache statistika
Qcache_queries_in_cache
Qcache_inserts
Qcache_hits
Qcache_lowmem_prunes
Qcache_not_cached
Qcache_free_memory
Qcache_free_blocks
Handlerių statistika
Handler_read_key
Handler_read_next
Handler_read_rnd
Handler_read_rnd_next
Handler_write
Query statistika
Com_change_db
Com_delete
Com_insert
Com_select
Com_update
Bendra statistika
Aborted_clients
Aborted_connects
Bytes_received
Bytes_sent
Connections
Created_tmp_disk_tables
Created_tmp_tables
Created_tmp_files
Key_read_requests
Key_reads
Key_write_requests
Key_writes
Max_used_connections
Open_tables
Open_files
Opened_tables
Questions
Select_full_range_join
Select_range_check
Select_scan
Slow_queries
Sort_merge_passes
Table_locks_immediate
Table_locks_waited
Threads_cached
Threads_created
Dauguma iš šių duomenų yra tiesiog COUNTER ar netgi DERIVE tipo, tik reikia turėt omenyje, kad jie wrapinami šiek tiek kitaip nei kad normalūs counteriai, tarkim interfeiso - sulig kiekvienu mysqld restartu gausim reikšmes nuo nulio. Tas nėra problema, DERIVE su min=0 sutvarkys reikalą. Kai kurie iš duomenų reikalingi tik labai ilgalaikei statistikai (kaipo slow_queries ar Aborted_clients), kai kurie turi reikšmę tik trumpalaikėje statistikoje; bet bet kuriuo atveju - viskas reikalinga. Kadangi naudojamas beveik visas show status; outputas - galbūt galima išsiversti be kažkokio regexpo reikšmių paieškai, ir imti visas reikšmes, tik atmetinėti nereikalingas. Čia jau reikia eksperimento - kas yra greičiau.
Šita dalis neturi nusifailinti, jei kuris nors kintamasis nerastas, tokiu atveju arba turi būt prilyginama nuliui, arba tiesiog gražinamas NaN rrdtool'sui. Reikalinga galimybė be ypatingo galvos skausmo pridėti naujus kintamuosius stebėjimui (su kiekvienu didesniu mysql release'u atsiranda krūva variablų ir status reikšmių, kai kurios iš jų - gan reikšmingos).
Sistemos statistika
CPU statistika
Bendras sistemos load average
Kiekvieno CPU (jei SMP) idle, system, user, nice reikšmes
Procesų skaičius su state - running, sleeping, total
Atmintis - used, cached, free, buffers
Swap - used, cached, free
I/O statistika - disko read/write
Tinklo statistika
Bendras srautas baitais IN kiekvienam interfeisui
Bendras srautas baitais OUT kiekvienam interfeisui
Bendras srautas paketais IN kiekvienam interfeisui
Bendras srautas paketais OUT kiekvienam interfeisui
Klaidų skaičius ant interfeiso
Log parseris
ipfm log parseris - neapibrėžtas hostų skaičius, gaunamas runtime. Yra gatavi awk skriptai, reiktų konvertuoti....
postfix log parseris - savi counteriai jau daemono viduje, nes reiktų realtime tailinti logus ir skaičiuoti sėkmingų/failed delivery skaičių
webserverio log parseris - analogiškai postfixo - optional
Daemonas gali neturėti savo konfigūracinio failo, galų gale, neskirta newbie, kuriems tikrai nereikia tokios statistikos, ir kurie už minutės paklaus "ką reiškia 'make - command not found'". Visa konfigūracija gali būt tvarkome kokiais nors #define paties kodo viduje, ir kompiliuojama pagal poreikius. Reikalui esant turi būti galimybė atjungti bet kurį modulį be problemų - pvz man nereikia mysql statistikos - išmetu laukan jos surinkinėjimą, ir iš karto atkrinta libmysqlclientXX-dev problema, kartu ir kodas mažesnis. Bet kokiu atveju daemonas neturi "susipakuoti" pamatęs ką nors neįprasto - t.y. turi būti nors primityvus error handlinimas. Jei logfaile atsirado eilutė kurios jis nesupranta - neturi būt segfaulto. Gali būt warningas, gali gražinti NaN, bet neturi lūžti.
Reikalavimai :
Mažas atminties ir CPU resursų suvartojimas
Bent jau minimalus portability - t.y. turi veikt ant linuxo 2.4.x bei 2.6.x kernelio. Kadangi kita nei linux turi kitokią /proc struktūrą, tai ten neapsimoka per daug vargintis mėginant suderint viską kad veiktų dar ir kokiam FreeBSD, nors... Tarkim interfeiso statistiką imant iš /proc/net/dev, CPU ir mem - iš /proc/stat, disko... (reik pasižiūrėt iš kur vmstat'as ima) - nemanau kad sunku būtų rasti analogus. Vienok čia - jau trečiaeilis reikalas belieka.
Galimybė suktis nurodyto vartotojo teisėmis. Kadangi tokiu atveju gan sudėtinga su logais - reiktų naudot /dev/log interfeisą bei nurodytus numeric UID/GID (pvz grsec atveju paprastas vartotojas kurio UID neapibrėžtas neturi teisės brouzint po /proc , taigis atitinkamai, dauguma statistikos nusifailintų). Vėlgi, tema diskusijai ;-)
Vienas procesas. Daemonas neturi creatinti RRA, neturi piešti grafikų. Jo darbas - greit ir efektyviai rinkti statistiką bei updatinti RRA
RRA updatinimas - visas vienu metu. T.y. surenkama statistika, praėjus nustatytam timeout (turėtų būti soft ir hard limitai timeout'ui - t.y. max laikas tarkim 10sec. po kurių duomenys laikomi NaN, + konfigūruojamas laikas surinkimui, kuris negali viršyti max), sudėliojami nuliai ar NaN vietoje duomenų kurių negauta ir updatinama vienas didelis masyvas.