MASSALYZER 1.0 Felhasználói segédlet V.: 0.9.2.7
Pető Zoltán Last updated.: 2015-08-27
Mi a MASSALYZER? A MASSALYZER egy Linux alatt futó naplóelemző, szövegfeldolgozó program. Szöveges állományok, naplófájlok információtartalmának kinyerésében nyújt segítséget. Egyszerű és összetett minták alapján képes az adott adatmezők felismerésére, és az ezek közötti korrelációk figyelésére. Rugalmassága és teljesítménye miatt könnyen használható a „Big data” jellegű feladatoktól kezdve az real-time felügyeleti rendszerekig. Az egyedi fejlesztésekre jellemző szabadságfok mellett, töredék költséggel és idővel – akár azonnal –, működő megoldásunk lehet. Más logelemző rendszerekhez képest a MASSALYZER-ben elemi lépésenként állítjuk össze a kívánt feladatot. Az elkészült feladatok .ini fájljait sablonként használhatjuk hasonló feladatokhoz, így egyre könnyebbé válik a munka. Mit tud? Miben más? 1, Teljesítmény-központúság: Egyetlen szálon képes másodpercenként több millió sor feldolgozására. (Gyakorlatilag háttértár sebessége a szűk keresztmetszet.) A naplók összegyűjtése önmagában erőforrás igényes feladat, ha emellett még a naplók figyelését is meg akarjuk megoldani, úgy még nagyobb előnyt jelent a maximális erőforrás kihasználás. 2, Egyszerűség: Az „on the fly” végzett előszűrések, konverziók leegyszerűsítik a feladatot. Az összetett feladatot felbonthatjuk egyszerű elemi lépésekre. Az összetett reguláris kifejezések helyett használhatunk egyszerűbb kifejezéseket. 4, Megbízhatóság: Sok szerveroldali rendszer alapul olyan menedzselt kódon, ahol egy meghatározott futtatókörnyezetet is fel kell telepíteni az alkalmazás mellé. Ez plusz üzemeltetési kockázatot jelent. A MASSALYZER fordított natív kód. Nem igényel futtatókörnyezetet. A natív kód garantáltan ugyanúgy – meglepetések nélkül – fut holnap is. 5, Rugalmasság: Log-elemzéssel kapcsolatos projektnél előkerülhetnek egyedi naplóformátumok. Ezek integrálása minden projekt érzékeny pontja. Könnyen előfordulhat, hogy – bár az egyes rendszerek ismernek közel ezer formátumot –, ennek ellenére, pontosan az amire szükségünk lenne nincs közötte. Ennek sokszor drága, egyedi fejlesztés a vége. Az is előfordul, hogy a már ismert naplóformátumok is idővel változnak ami gondot okozhat. A MASSALYZER-rel beállíthatók a legkülönbözőbb egyedi formátumok és változások is egyszerűen követhetők. További fontos tulajdonságai: – – – – – – – – – – –
Real-time és off-line feldolgozás. Egy és többsoros naplóbejegyzések kezelése. Változók, műveletek, „on the fly” konverziók. Beépített elő- és utófeldolgozási lehetőség. Menet közbeni CHECKPOINT-ok. (Systematical events) Log idő és valós idő szerinti esemény generálás/kezelés. A feldolgozásba integrálható SHELL scriptek, parancsok. Integrált TCP és HTTP szerver. Log-forgatást érzékeli, automatikusan kezeli. Programmegszakítás kezelés. (kill -2, ctrl-c) Bővíthető egyedi, saját fejlesztésű függvényekkel.
1
1. A MASSALYZER indítása A MASSALYZER parancssorból indítható. A MASSALYZER-nek szüksége van egy un. ini-fájlra. Ebben a vannak azok a futási paraméterek és az elvégzendő feladat. A működéshez ezt a fájlt kell megadnunk a paraméterben. Ha nem adunk meg ini-fájlt, akkor a massalyzer.ini-t keresi abban a könyvtárban, ahol a parancsot kiadtuk. Ha nem találja, akkor jelenik meg az alábbi üzenet:
Pl. a test.paraméterrel, az alábbiak szerint indíthatjuk: $ massalyzer test.ini
A fenti parancs kiadása után a MASSALYZER elvégzi test.ini által definiált feladatot.
2
2. A MASSALYZER alapok Ahhoz, hogy a részleteket megértsük, szükség van arra, hogy nagy vonalakban áttekintsük a MASSALYZER működését. A MASSALYZER alapvetően kétféle üzemmódra képes:
1. Parancssori működés. Ilyenkor elindítjuk a programot és végigelemez egy már kész log-, vagy egyéb szövegfájlt, és a fájl végere érve befejezi a feldolgozást. Ezután kilép. (RUNNING="ONCE")
2. Real-time vagy démon (daemon) mód. Ilyenkor egy meglévő, folyamatosan bővülő log-fájlra állítjuk be a feldolgozást. A log-fájl végére érve nem fejeződik be a feldolgozás. A háttérben, folytatja a figyelést és vár az újabb és újabb sorok érkezésére. Ezeket folyamatosan feldolgozza, real-time elemzést végez. (RUNNING="CONT")
A másik alapvető csoportosítási lehetőség a kiindulási szöveg típusa szempontjából: • •
Egysoros logok – vagy egyszerű szövegfájlok. Többsoros naplóbejegyzések.
Egysoros naplóbejegyzések Az egysoros bejegyzések kezelése egyszerűbb. Nem kell feltétlen megadni pl. az időbélyeg formátumát. (Hacsak nem akarunk idő szerinti CHECKPOINT-ot definiálni.) Soronként kerül feldolgozásra. Ennek megfelelően a MASSALYZER soronként olvassa be a $INPUT_LINE rendszerváltozóba a megadott log-fájlt. Minden sor után lefut a megadott feldolgozás, azaz a CHANNEL bejegyzésekben meghatározott mintaillesztések, ellenőrzések sora.
T öbbsoros naplóbejegyzések A többsoros naplóbejegyzések megfelelő kivágásához szükség van egy jelre, ami alapján egyértelműen felismerhetők többsoros bejegyzések határai. A log-bejegyzések nagyon változatosak tudnak lenni, de abban általában megegyeznek, hogy tartalmaznak egy időbélyeget (timestamp) a bejegyzés jellegzetes részén. Az időbélyeg alapján MASSALYZER fel tudja ismerni az egyes bejegyzések határait. Így automatikusan összefüggő bejegyzésekre tudja darabolni a naplót. Ehhez egy fontos dolgot kell megadni, az időbélyeg formátumát. A különböző naplók típusonként a legváltozatosabb formátumban képesek az időbélyeget ábrázolni. Amikor az időpont nem a sor elején helyezkedik el, akkor a pozíciójára vonatkozó beállításra is szükség van. Ezeket a paramétereket – mint látni fogjuk –, viszonylag egyszerű beállítani.
3
3. A MASSALYZER .ini felépítése A MASSALYZER inicializáló fájl szekciói: Beállítások: • • • • • •
[GLOBAL] [CONVSTRINGS] [COUNTERS] [NETWORK] [STRINGS] [PLUGINS]
-
Általános beállítások, paraméterek. A konverziókhoz használt konvertálási szabályok. Események számlálásához használt változók deklarálása. Hálózati beállítások Szöveges változók deklarációi. A használandó külső függvények osztott könyvtárai.
Programszekvenciák: • • •
[CHANNEL…] - Egy mintaillesztéshez tartozó szekvencia*. (Lényegi rész.) [CHECKPOINT...] - Megadott N soronként lefutó szekvencia. [CRTL-C] - A MASSALYZER futásának megszakításakor fut le.
• •
[POSTSEQ] [PRESEQ]
(* CLTR-C lenyomásakor vagy a „kill -2 ...” parancs hatására)
- A feldolgozás befejezésével lefutó szekvencia. - A feldolgozás indulásakor lefutó szekvencia.
(* Szekció: Az ini-fájl egy adott – megnevezett – témájához tartozó paraméterek csoportja.) (* Programszekvencia: Az adott szekció alá tartozó, tevékenységet leíró utasítássor.)
A fentiek közül az első hatos csoport a ([NETWORK] … [STINGS]) a működési alapbeállításokért felel. A második ötös csoport a tevékenységek a definíciója, a végrehajtandó feladat „programja”. A MASSALYZER fájlja a hagyományos ini/cfg formátumot követi. Ez abból a szempontból is előnyös, hogy az sok editor ismeri. Ha ilyent használunk, akkor az automatikus kiemelés, színezés az átláthatóságot segíti.
4
Az egyes szekciók és azon belül a paraméterek általában tetszőleges sorrendben lehetnek. Kivétel ezek közül a [CHANNEL ...] szekció paraméterei. Ez(ek) végzi(k) a lényegi feladatot. (Sárgával jelölt rész.) [CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",REGEXP="",COUNTER="EXCEPTION",TYPE="HARD",VALUE="10000"] #============================================ # 1 2 3 4 5 6 7 8 9 10 #============================================ LINE1 = "" , "", "","","","","M","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR $ESC[A\n" [POSTSEQ] LINE1 = "", "", "" ,"" ,"" ,"", "M" ,"=","" ,"SHOW $ACTDATETIME LINE: $READNUMLINES TALÁLT: $ERROR \n" LINE2 = "", "", "" ,"" ,"" ,"" , "M" ,"=","" ,"SHOW ====== FINISH! ===== \n" [CHANNEL NAME="TEST_0001",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 1",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0002",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 2",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0003",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 3",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0004",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 4",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0005",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 5",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0006",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 6",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0007",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 7",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" [CHANNEL NAME="TEST_0008",COUNTER="ERROR",START_POS="10",END_POS="100",STR_PATTERN="Pattern 8",REGEXP=""] LINE1 = "$INPUT_LINE","" , "" ,"" ,"" ,"" , "M" ,"=","" , "" . .
(* Az egyes paraméterek magyarázatát lásd később.)
A végrehajtási sorrend felülről lefelé halad. Így tehát a korábban definiált csatorna előbb hajtódik végre, mint a később (lejjebb). A fenti – fiktív – példában csatornánként (lila „[CHANNEL NAME...”) egy sor szerepel (kék „LINE...”), de összetett feladat esetén több sor is szerepelhet egy-egy CHANNEL-ben.
5
4. MASSALYZER SZEKCIÓK 4.1 [CHANNEL ...] A MASSALYZER központi része. Itt kerül definiálhatjuk a feladatot, – hogy milyen események mintáit akarjuk felismerni, és ezekhez milyen akciót, (utasításokat) rendelünk. A CHANNEL elnevezés arra utal, hogy a logfájl egy kaotikusnak tűnő szövegfájl, amiből szeretnénk kiszűrni és rendszerezni a számunkra fontos információt. Egy CHANNEL definíció alatt, egy sikeres mintaillesztést, azaz egy eseménytípus előfordulásának felismerését értjük. Olyan ez, mint amikor pl. a rádión kiválasztunk egy frekvenciát és az adott csatornát hallgatjuk. Kiszűrjük a sok adó közül azt az egyet. Itt is a sokféle bejegyzésből kiválasztunk egy jellemző eseménytípust – a rá egyértelműen jellemző minták alapján –, teendőket rendelünk hozzá, amit végrehajtatunk. Több ilyen CHANNEL bejegyzést használhatunk attól függően, hogy hányféle dolgot szeretnék egyszerre figyelni. Ezek végrehajtási sorrendje az elhelyezkedésüktől függ. A végrehajtás felülről-lefelé történik. Így amit időben előbb szeretnénk ellenőrizni/végrehajtani, akkor azt előrébb kell elhelyeznünk. Egyéb megkötés nincs. Minden egyes CHANNEL egy (itt lilával színezett) „fejléccel” kezdődik. A fejléc paraméterei között szerepelnek alapvető információk arra vonatkozóan, hogy milyen mintát keresünk egy-egy naplóbejegyzés sorában. Ez lehet szövegminta vagy reguláris kifejezés. Amennyiben a megadott minta illeszkedik, akkor jutnak szerephez, a fejléc alatt szereplő – kékkel jelölt – sorok. Ezekben további ellenőrzések, konverziók és utasítások szerepelhetnek. Vegyünk egy egyszerű példát ahol a „LEVEL: Error” mintát keressük és ezeket a bejegyzéseket akarjuk külön fájlba leválogatni: [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
A bejegyzés „fejlécében”a következőket paramétereket láthatjuk:
NAME="DB2 LOG ERROR" A bejegyzés neve. A statisztikában – END_INFO=”ON” esetén – ezen a néven jelenik meg.
COUNTER="ERROR" Mintailleszkedés esetén – amikor talál egy megfelelő bejegyzést – az itt megadott számlálót automatikusan növeli. (Nem kötelező, opcionális paraméter.)
START_POS="50" Amennyiben nem az egész sort akarjuk vizsgálni mintaillesztésnél, akkor itt adhatjuk meg a vizsgálandó részlet elejének pozícióját.
6
END_POS="63" Amennyiben nem a beolvasott sor végéig akarjuk vizsgálni az illeszkedést, akkor itt adhatjuk meg a vizsgálandó részlet végének pozícióját. Olyan tól-ig számokat adjunk meg, hogy szélsőséges esetben is beleférjen a keresett minta. Ez attól függ, hogy a megelőző adatok mennyire változó hosszúságúak lehetnek. Ha valamelyik sorban kicsúszik a megadott tartományból, akkor – értelem szerűen – nem fogja észrevenni. Erre figyeljünk! Inkább nagyobb részt adjunk, meg, minthogy elveszítsünk egy bejegyzést. Egy jól beállított részlet segítségével nagyságrenddel növelhetjük a feldolgozás sebességét.
STR_PATTERN="LEVEL: Error" Jellemző karakterlánc (character string) – amit keresünk. („LEVEL: Error”.)
REGEXP=""
Reguláris kifejezés. Ha egyszerűen nem tudjuk megadni az STR_PATTERN-el, akkor használhatunk reguláris kifejezést is a keresett minta leírására. (A példában üres. Később még részletesen visszatérünk rá.) Figyelem! Az STR_PATTERN illesztése gyorsabb, mit a reguláris kifejezésé. Ha választhatunk, akkor az STR_PATTERN-t részesítsük előnyben! Előfordulhatnak helyzetek amikor mindenképpen szükségünk van regurális kifejezésre. Abban az esetben, amikor STR_PATTERN-t is megadunk és REGEXP-et is, akkor a MASSALYZER mindkettőt kiértékeli. Először mindig az STR_PATTERN-t és ha itt van találat, akkor a REGEXP-et is. Ne feledjük, hogy egy logfájl, akár 98-99%-ban is tartalmazhat érdektelen információkat, tehát ha gyors futást akarunk, akkor nem csak megtalálni kell a számunkra értékes sorokat, hanem mihamarabb kizárni az érdektelen részeket. Amennyiben reguláris kifejezést kell használnunk, akkor is érdemes lehet STR_PATTERN-t is megadni mellette – amennyiben létezik egy szükséges, de nem elégséges karakterminta. Így le tudjuk szűkíteni a sorok a számát, amin a reguláris kifejezés – relatív lassú – illesztése ténylegesen megvalósul. A START_POS és END_POS segítségével kivághatunk egy részt a sorból – az adott minta jellemző előfordulási tartományának megfelelően –, és csak a két pozíció közötti részben keres (STR_PATTERN) ill. illeszti rá a megadott reguláris kifejezést (REGEXP). Figyelem! A jellemző illeszkedési pozíció tartományának leszűkítése – pl. több tíz soros, vagy ennél is hosszabb naplóbejegyzések előfordulása esetén –, nagyságrendekkel is gyorsíthatja a feldolgozást! A fejléc felépítését tisztáztuk. Most nézzük meg, hogyan folytatódik a példánk: [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
A sor elején elhelyezett # karakter jelzi, hogy ott megjegyzés van. Így tudunk magyarázatokat fűzni az egyes bejegyzésekhez.
7
A paraméterek minden esetben idézőjelek között vannak. Így szabadon „tologathatók” a jobb átláthatóság érdekében. A paramétereket vesszővel kell elválasztani egymástól. [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
Egy-egy [CHANNEL...] szekció a következő szekcióbejegyzésig – vagy ha az utolsó, akkor a fájl végéig – tart. Egy fejléchez több sor is tartozhat a feladattól függően. A fenti példában három sort láthatunk. Egyetlen sor a következőket tartalmazza: Param. szám
1. 2.-3. 4.
Paraméter tartalma Megadhatjuk, munkaterületre
hogy
mi
kerüljön
A lényeges részt kivághatjuk.
Eredmény a A feltöltjük a WRKSPC-t. Ezen dolgozunk. A WRKSPC-en csak a kivágott rész marad meg.
Konvertálhatunk, többféle módon is, akár A WRKSPC-en saját egyedi függvénnyel is. marad.
a
konvertált
tartalom
A konvertálás után egyszerűbb reguláris kifejezést használhatunk a mintafelismerésre. Ez is a feldolgozási sebességet és az átláthatóságot növeli. (Pl. egy URL dekódolt szöveget egyszerűbb kifejezéssel lehet illeszteni, mint egy nem dekódolt link részletét.)
7.
Reguláris kifejezés
Igaz/Hamis (Illeszkedik vagy nem?)
6.
„=” vagy „!”
A „!” az ellenkezőjére váltja a mintaillesztés eredményét. Az „=” nem változtatja meg. Ha ezek után igaz értéket kapunk, akkor végrehajtódik a 8. paraméterben található az utasítás. (Ha az adott sorban van olyan)
5.
Az reg. kif. illeszkedés eredménytől függően Feltételhez kötött folytatás. dönthetünk a további feldolgozásról. „C” „T” „F” „S” „Q”
8.
Folytatás (feltétel nélkül). Ha igaz (az illesztés) akkor tovább. Ha hamis (az illesztés) akkor tovább. Mindenképp megáll (Stop). Kilép a feldolgozásból (Quit).
Az 5.-6.-7. paraméter által leírt feltétel Pl. munkaterület mentése változóba, shell eredményétől függő utasítást állíthatunk script/parancs indítás, hálózati üzenet össze és adhatunk ki. kliensnek, stb.
Az előző felsorolás mind opció. Soronként a tetszőleges paraméterek tölthetők ki, ami az adott lépéshez kell. Így tömören tudjuk megfogalmazni a lépéseket.
8
4.1.0 - Sornév: LINEx=
A sor neve/címkéje. Nem lehet két ugyanolyan címkenév egy CHANNEL-en belül. Erre a célra tetszőleges, rövid szöveget használunk.
4.1.1 - 1. paraméter → Input
A paraméter-struktúra megértéséhez kell egy kis kitérőt tennünk a MASSALYZER működésével kapcsolatban. A MASSALYZER-nek vannak belső rendszerváltozói, amiket elérhetünk. A [COUNTERS] és [STRINGS] szekcióban deklarálhatunk saját változókat. Mindkét típus aktuális tartalmát a nevük elé tett $ jellel olvashatjuk ki. (Értékadáskor az ini-fájlban nem tesszük ki a $ jelet.)
$STR VARIABLE 1.
$COUNTER 1.
$STR VARIABLE 2.
$COUNTER 2.
$STR VARIABLE n.
$COUNTER n.
MOV CAT
INC DEC CLR
ADD SUB
$INPUT_LINE
$WRKSPC
SHOW
Console
WRITE
File
File
A fenti ábra megértéséhez két fontos belső változóról kell tudnunk: –
$INPUT_LINE: Az aktuálisan utoljára beolvasott sort tartalmazza. A feldolgozás azután kezdődik el egy adott soron, amikor azt sikeresen beolvasta a MASSALYZER. Többsoros naplóknál ez több fizikai sort tartalmaz, ez egy logikailag összetartozó teljes naplóbejegyzés.
–
$WRKSPC: A munkaterület. E köré épül fel a feldolgozás. Minden lényeges művelet ezen a munkaterületen megy végbe. Ebben keresünk mintát, ezt lehet vágni, itt keletkezik a konverziók végeredménye is. Az egyes lépések között ennek állapota megmarad és a következő művelet az itt hátrahagyott állapottal dolgozik tovább, amíg új – feltöltésével kapcsolatos – utasítás nincs.
(A többi változót és konstanst is megtalálhatjuk később, az összefoglaló táblázatban.)
9
File
File Output file
Input (log/text) row
$STR VARIABLE
$INPUT_LINE
TCP/IP client
Input / Copy (1)
$WRKSPC
Cutting (2,3)
Conv., filt. (4)
Selection (5,6,7)
Instruction (8)
f(...); Outside function (shared lib.)
>_ SHELL SQL (*optional)
A sárgával jelölt műveletek befolyásolhatják a $WRKSPACE tartalmát. A zárójelben az adott művelet paramétersorban (LINE=...) elfoglalt pozíciójának sorszámát látjuk. A MASSALYZER minden log-bejegyzés beolvasása után végigmegy a [CHANNEL...] fejléceken – a ini-ben felülről lefelé – és megpróbálja illeszteni az $INPUT_LINE tartalmára a fejlécben megadott STR_PATTERN és REGEXP mintákat. Ha mindkettőt megadtuk akkor mindkettőt. Először a STR_PATTERN-t ellenőrzi. Ha az illeszkedik az, akkor ellenőrzi a REGEXP mintát. Ha az STR_PATTERN nem illeszkedik, akkor nem végzi el a REGEXP illesztését, hanem hamis értékkel tér vissza. Ha a kettő közül csak az egyiket adtuk meg, akkor csak azt vizsgálja. Amennyiben az illesztés igaz eredménnyel zárul, akkor lefut a fejléc alatti sorokban definiált feladatsor. Abban az esetben, ha egyiket sem adjuk meg a fejlécben, akkor az automatikusan „igaz” értéket kap, így minden egyes log-bejegyzés felolvasása után, a CHANNEL fejléc után megadott szekvencia le fog futni.
10
Az automatikus beolvasás után az input fájlból felolvasott sor először az $INPUT_LINE jelzésű belső tárolóba kerül. Ahhoz, hogy meg tudjuk kezdeni a munkát fel kell töltenünk a munkaterületet ($WRKSPC). Az első paraméter „$INPUT_LINE” nem csinál egyebet, mint a naplófájlból felolvasott és – automatikusan – egyetlen egységnek felismert naplóbejegyzést a munkaterületre másolja, hogy tudjunk vele dolgozni. A munkaterületet más változókból is feltölthetjük kezdeti értékkel. Korábbi állapotok változókba mentett tartalmával is feltölthetjük. Ennek akkor van jelentősége, ha egy adott esemény kezelése függ egy korábban bekövetkezett esemény által okozott állapotváltozástól. Minden beavatkozás (vágás, konverzió, függvényhívás, stb.) a munkaterületen ($WRKSPC) hajtódik végre. Amennyiben nem írunk az első paraméterbe semmit, akkor nem történik változás a munkaterületen. Ebben az esetben a munkaterületen a legutoljára végrehajtott művelet eredménye marad meg. A következő művelet ezzel folytathatja a munkát. Ily módon több részfeladatra bonthatjuk a teendőket. Az egyes lépések után feltételekhez köthetjük a kiértékelés folytatását így feleslegessé vált műveleteket már nem kell elvégeztetnünk. Ha egy művelettel felülírtuk a munkaterületen levő eredeti logsort – mert pl. egy része kellett egy illesztéshez –, de újra az eredeti sorra van szükségünk, akkor az adott sor elején újra megadhatjuk az $INPUT_LINE-t és így újra megkapjuk a munkaterületen az eredeti log-bejegyzést. Ha nem a bejövő soron akarunk műveleteket végezni, hanem a korábban elmentett változón, akkor azt írjuk bemenetként az első paraméterbe. Akár több változót is felsorolhatunk. Összefoglalva: Ahol változónevet talál a program, azt lecseréli annak aktuális változó tartalmára – a többi szöveget változatlanul hagyja – és ez az eredmény kerül a $WRKSPC-re. Így akár több változó tartalmát és összefűzhetjük, keverhetjük a prompt beírt szöveggel is a változókat. A változóneveken kívül, a többi szöveget változatlanul hagyja.
11
4.1.2 - 2. és 3. paraméter – Start és End → Vágás Ez a két paraméter egy logsor lényeges tartományának kivágásához kell. Mivel a logok egyes sorai nem feltétlen pozíció azonosak, így a klasszikus substr() szerű függvénnyel (konkrét pozíció-tól/-ig való vágással) nem mennénk sokra. A sorok változó hossza miatt, változó pozíción helyezkedhetnek el az adatok. Mivel a paramétereket mindig pontosan szeretnénk kivágni, ezért itt mindkét paraméter (Start és End) egy-egy karakterminta. A megadott karakterminták megtalálása esetén a két találati pozíció közötti részt kivágja és elhelyezi a munkaterületen. Ezzel a módszerrel a változó pozíció esetén is megtalálja a megfelelő részt, ha sikerül megfelelő – egyedi – határolókaraktereket találnunk. A megadott minták nem lesznek részei az eredménynek, azok a levágott részhez tartoznak. Ha nem adunk meg Start paramétert, akkor a sor elejéről nem vágunk le semmit, End paraméter hiányában pedig a bejegyzés a végéig megmarad. A két paramétert külön-külön is használhatjuk, ha csak az elejéről vagy csak a végéről szeretnénk egy adott részt levágni. A példában ezek üresen maradtak, mert a teljes bejegyzésre szükségünk volt. A megfelelő rész kivágásához nem csak konkrét karaktermintát, hanem változók tartalmát és ezek kombinációját is felhasználhatjuk.
4.1.3 - 4. paraméter – Konverzió Előfordulhat, hogy a logban nem olyan formában található a tartalom ami nekünk megfelelő lenne. Szükség lehet szűrésre vagy átalakításra az egyszerűbb kezelhetőség miatt. (Egyszerűbb keresőmintákat adhatunk meg.) Ennek egyik legegyszerűbb példája, ha pl. nem abban a kódolásban vannak az adatok, mint amilyen a rendszerünk. Vagy pl. egy egyszerű URL dekódolást kellene végrehajtanunk, mielőtt egyszerűen mintát keresnénk/illesztenénk az adott sorra. (Nem is beszélve arról a megoldásról, melyben konverzió nélkül, kizárólag reguláris kifejezésre
bízzuk a felismerést. Ez a fenti esetben bonyolult és erőforrás pazarló.) Az is előfordulhat, hogy egyes karaktereket ki akarunk szűrni a kimenetre írandókból, (pl. a szövegben szereplő esetleges – „don't”,”can't”, stb. – aposztróf hibát okozna, ha egy command shell parancsot állítunk össze, amiben szintén van szimpla idézőjel...), vagy pl. nem nyomtatható karaktereket akarunk figyelni... A végtelenségig lehetne sorolni, hogy mikor jön jól, ha cserélni, szűrni, konvertálni tudjuk a be-/kimenetet. A MASSALYZER-ben konvertálni pillanatnyilag 3 különböző módon lehetséges. 1) Konvertáló string-párok használatával. (Lsd. Később.) 2) Belső függvény meghívásával. (MASSALYZER-be épített.) 3) Külső függvény hívásával. (Megosztott könyvtár.)
12
4.1.4 - 4. paraméter → Konvertáló string-párok Összeállíthatunk string-párokat, amivel egyszerűbb szűréseket, konverziókat hajthatunk végre. Ezeket az értékpárokat [CONVSTRINGS] szekcióban deklarálhatjuk. [CONVSTRINGS] STR1_S="[ 27][0A ][0D ]_ +*/#.!:,;[]%=?~<>()aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789" STR1_D="['`'][0A ][0D ]_ +*/#.!:,;[]%=?~<>()aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789" STR1_R="?"
A fenti példában a konvertáló string-pár neve STR1. Minden konvertáló string-hez bejegyzés-hármas tartozik: STR1_S (S, mint Source), STR1_D (D, mint Destination) és STR1_R (R, mint Replace). Ez utóbbi egyetlen karakter. A konverzió folyamán munkaterület összes karaktere sorban ellenőrzésre kerül. A MASSALYZER először ellenőrzi, hogy az adott karakter szerepel-e az STR1_S srtingben. Amennyiben megtalálta, úgy lecseréli a STR1_D azonos pozícióján található karakterre. Ha nem találja, akkor az STR1_R-ben található karakterrel fogja helyettesíteni. Amennyiben a példában az STR1_R üres lenne, akkor az azt jelentené, hogy nem kell helyettesíteni semmivel, hanem a fel nem sorolt karaktereket egyszerűen el kell hagyni, ki kell szűrni. A fenti példában az „ismeretlen” – STR1_Sben fel nem sorolt – karakterek helyén egy kérdőjel (?) fog megjelenni. Célszerű a string-eket úgy szerkeszteni, hogy az egymáshoz tartozó karakterek egymás alá/fölé kerüljenek a könnyű átláthatóság miatt. Egyes nem nyomtatható karaktereket kapcsos zárójelben, számjegyekkel is megadhatunk. Ilyenkor a karakter decimális kódját (pl. [ 27]) kell beírnunk. Hogy ilyen esetben se csússzon el a pozíció ezért a nyomtatható karaktereket zárójelben, szimpla idézőjelek között (pl. ['`']) formában is megadhatjuk. Így nem nyomtatható karaktereket nyomtathatóra cserélhetjük (és viszont). A fent említett módon definiált konvertáló string-et felhasználhatjuk a 4. paraméterben. Egyszerűen csak be kell írnunk a konvertáló string nevét – jelen esetben ”STR1” – és a konverzió automatikusan végbemegy és a munkaterület tartalma ($WRKSPC) a konverziónak megfelelően átalakul. Amennyiben nem akarjuk felsorolni az összes karaktert, akkor lehetőségünk van arra, hogy csak a kivételeket adjuk meg. Ebben az esetben a fenti példában a STR1_R értékhez a ”SELF” paramétert kell rendelni. Ezek után az összes karakter érvényes lesz és semmi nem kerül kiszűrésre. Az STR1_S és STR1_D string-ekben pedig csak azokat a karaktereket kell felsorolni, melyeken tényleg változtatni akarunk. [CONVSTRINGS] STR1_S="'" STR1_D="`" STR1_R="SELF"
Végül nézzünk egy nagyon egyszerű, fiktív példát: Ha a pl. $WRKSPC tartalma „HI JOJO”, akkor az alábbi beállítás mellett az ”STR1” konverzió után a tartalma „BABA” lesz. [CONVSTRINGS] STR1_S="OJ" STR1_D="AB" STR1_R=""
13
[CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
Amennyiben többféle konverziót is akarunk, úgy azokat az idézőjelen belül egymás után, vesszővel elválasztva sorolhatjuk fel. A feldolgozás a felsorolás sorrendjében fog végrehajtódni. pl. ”STR1,STR2,URL”.
4.1.5 - 4. paraméter → Konverzió beépített függvénnyel A MASSALYZER beépítve tartalmaz egy URL dekódert. Amennyiben pl. URL dekódolásra van szükségünk, akkor csak annyit kell írnunk a 4. paraméterhez, hogy ”URL”. (Előfordulhat, hogy a későbbi verziókban további beépített konvertáló függvények is lesznek, de valószínűbb, hogy a fejlesztés iránya külső osztott könyvtárak bővítése felé halad inkább, és a további „gyári” – konvertáláshoz használható – függvények ezekben lesznek elérhetők.)
4.1.6 - 4. paraméter → Konverzió küls ő függvényhívással A fentieken kívül lehetőség van egyedi konverzióra is. Ehhez először meg kell írni a megfelelő konvertáló függvényt és elhelyezni egy megosztott könyvtárban (shared library). A megfelelően elkészített függvényt, a függvény nevének beírásával – fentiekhez hasonlóan – hívhatjuk meg. Így gyakorlatilag bármilyen egyedi konverziót megvalósíthatunk a saját speciális igényeinknek megfelelően. Saját függvények készítéséről a [PLUGIN] szekció leírásánál „Külső függvény létrehozása” fejezetnél találhatunk információt és példát.
és
a
14
4.1.7 - 5. Paraméter → Feltételes folytatás Ez a paraméter csak a 6. és 7.paraméterrel együtt értelmezhető. Az 5. paraméter arról szól, hogy mit tegyen majd a továbbiakban miután végzett az aktuális sor végrehajtásával. A 6. és 7. paraméter határozza meg azt a feltételt, aminek kiértékelése után (igaz/hamis) dönthető el, hogy folytatni kell-e a feladatot a következő sorral. A folytatásra vonatkozó feltétel ettől az igaz/hamis értéktől is függhet. A folytatást egyetlen karakter megadásával határozhatjuk meg: [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
””
– Üres paraméter ugyanazt jelenti, mintha ”C”-t adtunk volna meg.
”C”
– (CONTINUE) Mindenképp folytatja a munkát következő LINE sorral, amennyiben van olyan a csatornán belül.
”S”
– (STOP) Mindenképp álljon meg és ne menjen a következő sorra.
”F”
– (FALSE) Ha nem teljesül a feltétel (6. és 7. param.), akkor menjen tovább egyébként itt hagyja abba a csatorna kiértékelését.
”T”
– (TRUE) Ha teljesül a feltétel (6. és 7. param.), akkor menjen tovább a következő sorra, különben itt hagyja abba a csatorna kiértékelését.
”Q”
– (QUIT) Feltétel nélkül kilép a programból. A MASSALYZER futása megszakad.
Egyéb karakter hatástalan – azaz mintha üres lenne. Legtöbbször a "C” opciót fogjuk használni. A többi speciális esetekben, viszonylag ritkán kell. Főleg az ”F”-re és a ”T”re lesz szükségünk, ha feltételekhez akarjuk kötni a folytatást.
15
4.1.8 - 6. paraméter → A mintaillesztés eredményének módosítása Itt két opció lehetséges: ”=”
– A 7. paraméterben megadandó (reg. kif.) mintaillesztés eredményén nem változtat. „Ezeket a sorokat keressük – a megadott minta alapján.”
”!”
– A 7. paraméterben megadott (reg. kif.) mintaillesztés eredményét az ellenkezőjére változtatja. „Ezeket a sorokat NEM keressük – a megadott minta alapján.”
[CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
”<”
– Megpróbálja a $WRKSPC aktuális tartalmát és 7. paraméterben megadott értéket is számként értelmezni. Amennyiben a $WRKSPC egész számként (integer) értelmezett értéke kisebb, mint a 7. paraméterben megadott számként értelmezett értéke, úgy igaz eredményt ad.
”>”
– Megpróbálja a $WRKSPC aktuális tartalmát és 7. paraméterben értéket is számként értelmezni. Amennyiben a $WRKSPC egész (integer) értelmezett értéke nagyobb, mint a 7. paraméterben számként értelmezett értéke, úgy igaz eredményt ad. Ha nem feltétel, akkor hamis az eredmény.
megadott számként megadott teljesül a
FIGYELEM! Ha valamely szöveg nem értelmezhető számként – nem tartalmaz számjegyeket, vagy nem azzal kezdődik –, úgy az nullának számít és nulla értékkel végzi el az összehasonlítást.
16
4.1.9 - 7. paraméter → Mintaillesztés reguláris kifejezéssel [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+========+========+========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
A hetedik paraméter egy reguláris kifejezés. Amennyiben nem adunk meg reguláris kifejezést, akkor ennek a mezőnek az illesztésének eredménye automatikusan igaz. (Ahogy a fenti példánál.) A MASSALYZER POSIX rendszerű reguláris kifejezéseket használ – kis kiegészítéssel. Amennyiben járatlanok vagyunk a reguláris kifejezésekben és egyszerű karaktermintát szeretnénk keresni, úgy vigyázzunk a speciális karakterekre, mert azok „megviccelhetnek”, amennyiben olyan karaktereket adunk meg amelynek reguláris kifejezésekben különleges szerepe van. (*,?,^,{,},[,],+,$,|,stb.) Ezeket egy „\” (backslash) karakter kell, hogy megelőzze, ha azt szeretnénk, hogy egyszerű literális karakterként értelmezze. A 7. paraméterben az idézőjelek között megadott reguláris kifejezést illeszti a $WRKSPC aktuális tartalmára. Az eredmény egy igaz/hamis érték lesz. (Illeszkedik-e rá vagy sem.) Ettől az igaz/hamis értéktől függ egyrészt, hogy a 8. paraméterben megadott utasítás végrehajtódik-e, másrészt a 5. paraméterben megadott folytatási feltételt is ez alapján értékeli ki. Visszatérve egy pillanatra a 6. paraméterre: Azért van rá szükség, mert reguláris kifejezéssel könnyen megadhatunk egy mintát, ami adott szövegre illeszkedik, de ennek az ellenkezőjét adott esetben szinte lehetetlen megadni. Ha ilyen feltételre van szükség, akkor a 6. paraméter (”!”) negálja a reguláris kifejezés által visszaadott logikai értéket. Így ha logikailag az ellenkezőjére van szükségünk, akkor is egyszerűen ugyanazt a feltételt adhatjuk meg, amit az illeszkedés keresési mintájául is adnánk.
Különösen fontos a reguláris kifejezések bonyolultságával hatványozottan nőhet a kiértékeléshez szükséges erőforrásigény. Amennyiben több egyszerűbb részkifejezésre tudunk felbontani egy bonyolultabb reguláris kifejezést, úgy: – átláthatóbb részeket kapunk – az egyszerűbb részek kiértékelése összességében kevesebb erőforrást igényel, mint egyetlen bonyolultabb kifejezés. – A rész kifejezéseket önálló logikai egységenként tudjuk ki/be kapcsolni, (pl. comment-be tenni), mozgatni, változtatni, stb. – Ha egy korábbi részletben nem találunk illeszkedést, a többi részlet (sor) illesztését már nem is kell végrehajtani.
17
Mielőtt továbbmennénk, nézzük meg a használható jelöléseket és ezek jelentését: A MASSALYZER reguláris kifejezéseiben használható jelölések \ (escape karakter)
„\*” - csillag, „\\” vissza-per, \” idézőjel. Literál karakter magadásához.
. (pont)
Illeszkedik minden karakterre, de az ENTER kivétel! (új sor - \n) Többsoros naplófájlnál erre figyelni kell! Ha nem figyelünk rá, akkor előfordulhat, hogy nem az egész bejegyzést, csak annak első sorát vizsgáljuk.
^ (kalap)
Sor elejére illeszt.
$ (dollár)
Sor végére illeszt.
| (pipe)
Logikai vagy. Az előtte vagy a mögötte levő karakter, kifejezés
[] pl. [0123456789]
Karakterosztály. A szögletes zárójel közötti karakterek bármelyike. (Több esetén – pl. [0123456789]* - bármilyen sorrendben.)
[0-9] (karakterosztály) [^0-9]
Tartomány 0-9 közötti számjegyre illeszkedik A [ utáni ^ jel negálás, tehát ez a kifejezés „bármely nem szám karaktert” jelent.
[a-zA-Z]
ASCII karaktertartományok jelzésére – Betűkre illeszkedik.
[\x01-\xFF]
Tetszőleges tartomány megadása a karakter hexadecimális ASCII kódjával. (Pl. pont nem használható [] között eredeti értelmében – itt a literálját – azaz valóban pontot jelent, nem pedig a „minden karakter kivéve az ENTER-t”.)
()
Al-kifejezések ill. egyes karakterek hatályának jelzésére, csoportosítás.
* (csillag)
0 vagy többszöri ismétlődés jelzése
+ (plusz)
1 vagy többszöri ismétlődés jelzése
{3}
Az megelőző karakter pontosan háromszor szerepel.
{3,}
Az megelőző karakter legalább háromszor szerepel.
{3,5}
Az megelőző karakter legalább háromszor, de legfeljebb ötször szerepel.
\x0A vagy \X0A
Egy karakter a hexadecimálisan, bájtkódja szerint megadva.
\n
ENTER (Line feed) (0x0A)
\t
TAB (Tabulátor)
\r
Carriage return
\f
Form Feed
\v
Vertical TAB
Egy-egy logbejegyzés általában több logikailag összefüggő mezőre osztható részből áll. Ezek a mezők egy-egy paraméter megnevezését és értékét tartalmazhatják. A reguláris kifejezéssekkel nem csak mintakeresést végezhetünk, de az adott sorok paramétermezőkre bontását is elvégezhetjük. A 7. – reguláris kifejezést tartalmazó paraméternél –, megadhatunk zárójeles alkifejezéseket is. A teljes kifejezés illeszkedése esetén az egyes zárójeles kifejezések eredményei rendre megjelennek a MASSALYZER eredménytömbjében. Az első zárójel eredményének értéke a $REG_RET[1] változóban, a második zárójeles kifejezésre illeszkedő részt a $REG_RET[2]-ben találjuk és így tovább. Innen elmenthetjük saját váltózóba vagy felhasználhatjuk azonnal. (Pl. MOV, WRITE, SHOW utasításokkal a 8. paraméternél.) A RET értékek addig maradnak meg, amíg $WRKSPC (a munkaterület) nem változik meg, vagy amíg nem futtatunk újabb reguláris kifejezést – pl. a következő sor 7. paraméterével. A $WRKSPC teljes kifejezésre illeszkedő egy részletét a $REG_RET[0] tartalmazza. A fentiek alapján lehetőségünk van egyetlen lépésben – egy összetett reguláris kifejezéssel – szétválogatni a teljes logsor számunkra érdekes részleteit, mezőit. Többsoros naplóbejegyzéseknél a sorvégek (ENTER) jelzéséhez a \n jelet használhatjuk. A $REG_RET maximális indexe 255, így maximum ennyi paramétert tudunk egyetlen lépésben szétválogatni.
18
A nem nyomtatható karaktereket ebben a mezőben \x után két hexadecimális számjeggyel írhatjuk le. (A \n helyett tehát elvileg lehetne akár \x0A is a sor végén, – UNIX típusú szövegeknél. DOS/Windows-ban használatos sorvég \x0D\x0A [\r\n] lenne.) Példa egy beolvasott naplóbejegyzés első sorából, a PID és a MESSAGE mezők értékének leválogatása – megnevezésükkel együtt – rendre a $REG_RET[1], és $REG_RET[2] változóba. (Ne ijedjünk meg, ha elsőre bonyolultnak tűnik, a következő oldalon részletesen elmagyarázzuk.) "(PID
: [0-9]+)[\X01-\X79]+(MESSAGE : [\X20-\X79]+[\n](([ ]{10}[\X20-\X79]+[\n])+)?)"
Ha további mezőre lenne szükségünk a következő sorból, akkor egyszerűen folytathatnánk a megfelelő rész zárójelezve. Nézzünk most egy konkrét – többsoros – előfordulást egy minta logban:
A csatorna fejlécében megadott STR_PATTERN="LEVEL: Error" találat miatt „be fog jönni” ebbe a csatornába a feldolgozás. (Az első sor végén – a képen a sötéttel jelölt részen – fogja megtalálni.)
19
Ahogy már említettük, a zárójeles részeredményeket a $REG_RET tömbben szolgáltatja. Ahhoz azonban, hogy ez igaz legyen, nem elég az adott al-mintának illeszkednie, az egész reguláris kifejezés illeszkedése szükséges. Ez a fenti mintánál adott. Az reguláris kifejezés első zárójelének tartalma: (PID : [0-9]+) Ennek eredményeként a $REG_RET[1] tartalma a „PID : 26135” lesz. A második zárójel tartalma: (MESSAGE : [\X20-\X79]+[\n](([ ]{10}[\X20-\X79]+[\n])+)?) Ez alapján a $REG_RET[2] tartalma: „MESSAGE : ZRC=0x850F0005=-2062...” a MESSAGE bejegyzés végéig. Ha ezek után kiíratjuk a $REG_RET[1] és $REG_RET[2] tartalmát („WRITE” utasítással), akkor megkapjuk a reguláris kifejezéssel kivágott részlet tartalmát a kimeneti fájlban:
Ha nem akarjuk, hogy az eredmény tartalmazza a címkeneveket is, akkor egyszerűen kivesszük a zárójeles rész elé. A feladatot meg lehetne oldani a 2. és 3. paraméter (kivágás) használatával is – lépésenként, több sorban. Ez egyszerűbb lehet azoknak, akik nem akarnak reguláris kifejezésekkel foglalkozni. Azoknak akik járatosabbak a reguláris kifejezések összeállításában, lehetőségük van több egyszerűbb, vagy egyetlen összetett kifejezéssel elvégezni a feladatot.
Ha már a reguláris kifejezéseknél tartunk, nézzük meg lépésenként a kifejezést: "(PID
: [0-9]+)[\X01-\X79]+((MESSAGE : [\X20-\X79]+[\n])(([ ]{10}[\X20-\X79]+[\n])+)?)"
Nézzük a PID részt :„(PID
„PID :„ „[0-9]” +
: [0-9]+)”
jelentése: keresd a „PID : „ mintát jelentése: ezután számjegynek kell következnie jelentése: ameddig folyamatosan tartanak számjegyek, addig az beleszámít
PID után következő szám és a MESSAGE közötti szövegrészek „átugrása”:„[\x01-\x79]+” Miután az előzőket megtalálta, bármilyen karakter jöhet hexadecimális 01 és hexadecimális 79 kód között. Mivel ékezet nélküli karakterekről van szó – és egyéb speciális karaktereket sem tartalmaz, ami 0x80 és felette lenne –, így ennek gyakorlatilag bármelyik karakter megfelel, ami a log-ban található. Erre a sorrészre illenek azok a szövegek, paraméterek, amik elválasztják egymástól a PID és a MESSAGE mezőket. Mivel ez részt zárójelezés nélkül adtuk meg így nem kerül bele egyik $REG_RET eredménybe sem. Ha különleges karakterek is lennének benne, akkor lehetne akár [\X01-\XFF]+ is. A „[\X20-\X79]” helyett felhasználhatnánk a . (pont) jelet is – mivel sor végéig akarunk illeszteni, de mivel itt többsoros logról van szó –, előfordulhat az „átugrandó” részben több
20
ENTER is. Ha mégis ragaszkodnánk a ponthoz, akkor pl. a „(.*\n*)*” kifejezés egy megoldás lehet, de lássuk, hogy ehhez zárójelezésre volt szükségünk, ami egyrészt bonyolítja a megoldást, másrészt eredménye bekerül a REG_RET[2]-be, amire jelen esetben semmi szükségünk. (Mivel a sor ismétlés (*) jelzése a zárójelen kívül van, ezért illeszkedés esetén sem lesz benne értelmes adat.) Ezenkívül az ENTER külön kezelése az ismétlődések miatt is gondot okozhat. Külön gondoskodnunk kell az ENTER és az egyéb karakterek ismétlődésének különböző kombinációjáról, ami megint csak bonyolítaná a feladatunkat. A fentiek alapján az „[\X20-\X79]+” alak használata is egyszerűbbnek látszik. Ha mégis olvashatóbb alakot szeretnénk, akkor a [ -z] alak is használható. (Space-től z-ig.) A „[\n-z]+” alak pedig a többsoros illeszkedés [\x0A-\0x79]+ megfelelője lenne, ami jelen példánál ugyanúgy megfelelne. (Nem tartalmaz a minta sem tabulátort, sem ENTER-nél kisebb kódú speciális karaktert. Lsd.: ASC-II kódtáblázat.) Ehhez azonban pontosabban ismerni kell a ASCII (/UTF) táblázat felépítését és a naplófájlt is, míg az eredeti megoldáshoz ugyanez – legalábbis részleteiben – nem szükséges.
MESSAGE tartalom kinyerése:„(MESSAGE : [\X20-\XA0]+[\n](([ ]{10}[\X20-\X79]+[\n])+)?)” Ez szintén zárójeles rész, ami azt jelenti, hogy ennek eredménye megjelenik a $REG_RET[2]ben. A belső zárójelek ne zavarjanak senkit, azok már csak az egyes egységek határolói, a tárolással kapcsolatos hatásuk már nincs. „MESSAGE
: ” : Keresd a „MESSAGE : ” mintát.
[\X20-\X79]+ : A 0x20 és 0x79 között bármilyen karakter jöhet, a + jel miatt többször is. (lsd. ASCII kódtábla) – az ENTER nincs benne. [\n]
: egészen a sor végéig. (\n = ENTER, azaz új sor.)
--- opcionális rész innen --((
: Érvényességi blokk határolók (az egyik majd a + jelnek, a másik a ?-nek lesz.)
[ ]{10}
:Az új sorban keressen 10 db space-t egymás után.
[\X20-\X79]+ : Ha megvan, akkor fogadjon el 0x20 és 0x79 közötti karaktereket, [\n]
: a sor végéig.
)+
: A belső zárójelig ez többször is ismétlődhet, tehát több ilyen 10 space-el kezdődő sort is elfogad,
)?
: … de ha nincs ilyen (space, plusz sor), az sem baj, mert ez csak opcionális. Tehát, a sima egysoros - csak MESSAGE-et – is találatnak veszi. Ha nincsenek további (space-el kezdődő) sorok, az nem lesz kizáró ok.
Kihasználtuk, hogy a MESSAGE résznek akkor van vége, amikor megint a sor elején kezdődik. (Vagy nincs további sor a bejegyzésben.) Ilyenkor már nem illik rá a 10 db sor eleji space.
21
4.1.10 - 8. paraméter → Utasítás Elérkeztünk az utolsó paraméterhez a sorban. Ez az amiért az összes eddigi történt. A 8. paraméterben egy utasítás áll – amennyiben kitöltjük ezt a mezőt. Tehát, ha a kivágás és a konverziók után a megadott reguláris kifejezés illett a megadott mintára – ill. a 6. paraméterrel együtt igaz a végeredmény – azaz megtaláltuk a keresett mintát –, akkor valahogy reagálni szeretnénk erre. Ezt a 8. paraméterben leírt utasítással tehetjük meg. (Ha nem adunk meg reguláris kifejezést, akkor annak értéke automatikusan igaz lesz, tehát végrehajtja az utasítást amennyiben a 6. paraméter tartalma ”=”.) [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+========+========+========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"STR1", "C" ,"=" ,"" ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"WRITE $WRKSPC\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"MOV LAST_ERROR=$WRKSPC"
22
A MASSALYZER utasításai: Utasítás
Példa
Leírás
ADD
ADD STR_VARIABLE=123456 ADD STR_VARIABLE=$WRKSPC ADD STR_VARIABLE=$STR_VARABLE_2
- Beírt szám hozzáadása. - Rendszerváltozóban tárolt szám hozzáadása. - Másik változóban tárolt szám hozzáadása. (A MASSALYZER a számokat is szövegként tárolja, mivel a be- és kimeneteken is így jelenik meg, így ilyenkor nincs szükség konvertálásra.) (Az egyenlőségjel előtti változónév elé nem kell kitennünk $ jelet!)
CALL
CALL MY_CONV_FUNCTION
Külső – shared library-ban tárolt - függvény meghívása.
CAT
CAT STR_VARIABLE=”something” CAT STR_VARIABLE=$WRKSPC CAT STR_VARIABLE=$STR_VARIABLE_2
- String hozzáfűzése egy stringváltozóhoz. - Rendszerváltozó hozzáfűzése. - Saját változó hozzáfűzése.
CLR
„CLR COUNTER”
Counter – numerikus számláló – nullázása.
DEC
„DEC COUNTER”
Counter – numerikus számláló – csökkentése eggyel.
INC
„INC COUNTER”
Counter – numerikus számláló – növelése eggyel.
MOV
MOV STR_VARIABLE=something MOV STR_VARIABLE=Row : $WRKSPC\n MOV STR_VARIABLE=$STR_VARIABLE_2
- Értékadás: egyszerű szöveg. - Szöveg plusz változó tartalma. - Változó tartalmának átmásolása.
SEND
SEND CONTNAME=TEXT OF MESSAGE: $WRKSPC
CONTNAME néven beléptetett (TCP/IP) kliens felé üzent küldése.
SHOW
SHOW $ACTDATETIME LINE: $READNUMLINES A konzolon való megjelenítés (sdtout). FOUND: $ERROR $ESC[A\n Csak parancssoros futtatás esetén működik. Ha real-time feldolgozást választunk, úgy lekapcsolódik az indítás után shell-ről, emiatt nem juthatnak el oda az üzenetek.
SQL
SQL INSERT INTO TABLE_A SET FIELD1='$MASSA_VARIABLE';
- SQL-query végrehajtása (MariaDB, MySQL) adatbázison.
SQL $QUERY
- Változóban összeállított query-t futtat.
SUB
SUB STR_VARIABLE=123456 SUB STR_VARIABLE=$WRKSPC SUB STR_VARIABLE=$STR_VARIABLE_2
- Beírt szám kivonása. - Rendszerváltozóban tárolt szám kivonása. - Másik változóban tárolt szám kivonása.
SYS
SYS cat '$EMAIL_TEXT >>/tmp/message'
- SHELL parancs, script, vagy program indítása. SYS segítségével tudunk írni akár más fájlokba is.
*
(Relatíve ritka eseményeknél jól használható. Gyakori használat esetén viszonylag sok erőforrást fogyaszt, ezért nagy teljesítményű szövegfeldolgozáshoz korlátozottan ajánlott. Amennyiben mégis tömegesen parancsfuttatást kell használnunk, akkor például megtehetjük, hogy változóban gyűjtjük össze a teendőket és rendszeres időközönként egyszerre hajtatjuk végre.) SYS mail -s /tmp/message
'Helloi'
[email protected]
< - Pl. e-mail küldése is használható adott esemény bekövetkezésekor. (Feltéve, hogy megfelelően be van állítva a környezet.)
JMP
„JMP LINE1”
Ugrás adott CHANNEL-en belül egy adott címkéjű sorra. A 6.-7. paraméterrel együtt használva feltételes ugrást írhatunk.
WRITE
WRITE Last input line: $INPUT_LINE
A kimeneti fájlba írás. A változók helyére a tartalmuk kerül behelyettesítésre.
23
Az utasításokban felhasználhatjuk a saját és a rendszer változóit, konstansait. A MASSALYZER belső változói, konstansai Az 1. és 8. paraméterben használható konstansok Jelölés
Jelentés
\n
ENTER (10-es ill. 0Ah [h=hexa])
$ENTER
Ugyanaz, mint a "\n" 10-es kódú karakter. (Linux)
$ESC
A 27-es ASCII kódú escape (ESC) karakter
$PROC_ID
A futó MASSALYZER példány process ID-je. (Egyedi azonosításhoz.)
1. és 8. paraméterben használható rendszerváltozók (Csak olvasható)
$ACTLINE
Egysoros lognál a sor száma. Többsoros log esetén az utoljára beolvasott bejegyzés kezdősorának sorszáma.
$ACTDATETIME
Az utoljára beolvasott sor dátuma (TimeStamp) „2008.03.25 23:59:58” formában.
$ACTSEC
A $ACTDATETIME másodperc része „58”
$ACTMINUTE
A $ACTDATETIME perc része „59”
$ACTHOUR
A $ACTDATETIME óra része „23”
$ACTDAY
A $ACTDATETIME nap része „25”
$ACTMONTH
A $ACTDATETIME hónap része „03”
$ACTYEAR
A $ACTDATETIME év része „2008”
$INPUT_LINE
Az utoljára beolvasott sor (többsorosnál komplett bejegyzés) tartalma.
$LAST_MESSAGE
A korábbi $INPUT_LINE. Például, ha az $INPUT_LINE tartalma „Last message repeated
times”, akkor a $LAST_MESSAGE segítségével hozzáférhetünk az előző sorban található log bejegyzéshez.
$PREVMINUTE
Az előző perc a logban. (Az utolsó percváltás előtti perc:
„2014.01.20 23:59”)
$PREVHOUR
Az előző óra a logban. (Az utolsó óraváltás előtti óra:
„2014.01.20 23”)
$PREVDAY
Az előző nap a logban. (Az utolsó napváltás előtti nap:
„2014.01.20”)
$PREVMONTH
Az előző hónap a logban. (Az utolsó hónapváltás előtti hónap „2014.01”)
$PREVYEAR
Az előző év a logban.
(Az utolsó évváltás előtti utolsó év
„2014”).
$PLUGIN_RET
Külső (megosztott könyvtári) függvény visszatérési értéke.
$REALDATETIME
A számítógép aktuális rendszerideje „2015.01.20 23:59:59” formában.
$REG_RET
Összetett reguláris kifejezés visszatérési értéke.
$REG_RET[X]
X=0-255 Összetett reguláris kifejezés al-kifejezéseinek eredménytömbje. X=0 : REG_RET = REG_RET[0] → Teljes kifejezés eredménye. X=1-255 : Az első zárójelben levő al-kifejezés eredménye REG_RET[1], a második eredménye REG_RET[2] és így tovább.
$READNUMLINES
A logból beolvasott sorok (pillanatnyi) száma. Minden sor beolvasásakor nő. Abban különbözik az $ACTLINE-től, hogy az általában kevesebb, mert az a bejegyzés elejét ( a bejegyzés kezdetének sorszámát) mutatja, ez pedig az eddig összes (a többsoros bejegyzés végéig) beolvasott sorok számát tartalmazza.
$SQL_RET
A SQL query egyetlen visszatérési értéke. SQL lekérdezés után ebbe a változóba fog kerülni. (Ha van ilyen adat.: Első sor első mező - ROW[0])
$WRKSPC
A munkaterület aktuális tartalma.
24
5. [CHECKPOINT] Az előző fejezetben megnéztük, hogy miképp hozhatunk létre csatornákat, és hogyan reagálhatunk a naplóban felismert eseményekre. Az adatok feldolgozása során azonban vannak olyan feladatok, melyek nem köthetők konkrét minta előfordulásához. Pl. nem szeretnénk minden egyes alkalommal – amikor találunk valamit – fájlt írni, vagy épp az operációs rendszerhez (shell command) fordulni, mert az nagyon lelassítaná a feldolgozást. Ugyanakkor ezer, tízezer vagy épp százezer soronként egyszer jó lenne végrehajtani pl. egy változóban tárolt adat kiírását, egy shell sript végrehajtását, vagy valamilyen egyéb – relatíve lassú – funkciót indítani. Itt jön képbe a CHECKPOINT. Ennek gyakorlatilag csak a „fejléce” különbözik a [CHANNEL ...]-től, az egyes sorok teljesen kompatibilisek. (Így másolás is használható a két típus között, mert nincsenek új, más paraméterek.) Ennek fejlécében nincs a minta megadási lehetőség, mivel ennek a lefutásának nincs köze a mintafelismeréshez, ezért sem REGEXP-et sem STR_PATTERN-t nem tartalmaz, és nem is lehet ilyet megadni. Ezek helyett más paramétereket láthatunk. Nézzünk meg egy adott CHECKPOINT fejlécet: [CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",COUNTER="EXCEPTION_CTR",TYPE="HARD",VALUE="10000"]
NAME:
A CHECKPOINT neve.
COUNTER: Amennyiben meg akarjuk számolni, hogy hányszor futott le, akkor itt megmondhatjuk a számláló nevét, amit automatikusan növelni fog. TYPE: 4 típus lehetséges: HARD, SOFT, LOGTIME és REALTIME. Az első kettő a „HARD” és a „SOFT”. A különbség többsoros log-oknál tér el alapvetően. Amíg a HARD beállításnál minden egyes fizikai sor beleszámít a számlálásba, addig a SOFT beállításnál a többsoros logbejegyzés számít egyetlen sornak. További különbség, hogy a HARD beállításnál a CHANNEL-ek feldolgozása előtt fut le a CHECKPOINT szekvencia, míg SOFT esetén a CHANNEL szekvenciák végrehajtása után. Összegezve: egy sor beolvasását követően először a HARD CHECKPOINT fut le, majd következnek a CHANNEL-ek és végül a SOFT beállítású CHECKPOINT-ok. Természetesen, amennyiben többsoros a log, akkor a HARD minden egyes sornál lefut, miközben a SOFT csak minden komplett bejegyzés felolvasása után. A fenti sorrend arra az esetre vonatkozik, amennyiben az adott bejegyzés egysoros, vagy több soros ugyan, de az adott sor egy többsoros log-bejegyzés utolsó sora. A „LOGTIME” típusra akkor van szükség, ha nem N soronként akarjuk lefuttatni a CHECKPOINT alatti szekvenciát, hanem adott időnként. Ez az idő azonban nem a valós időt jelenti, hanem a log-bejegyzések idejét. Például, ha perces, órás, napi, havi vagy éves összesítéseket szeretnénk készíteni a log alapján, akkor nagyon hasznos ez a lehetőség. Ilyenkor a
25
VALUE nem a sor számát tartalmazza, hanem azt az időegységet, aminek a változását figyelni szeretnénk. ”SEC”, ”MINUTE”, ”HOUR”, ”DAY”, ”MONTH” vagy ”YEAR” állítható be. Amennyiben az adott időegységben változás következik be akkor lefut a hozzá tartozó rutin. Például MINUTE estében a perc értéke megváltozik az éppen feldolgozott log TIMESTAMP-jében. Azt, hogy a változás milyen mértékű, a program nem vizsgálja. A változás előtti perc értékét a $PREVMINUTE változó tartalmazza. Minden időegységhez tartozik egy-egy változó, ami tartalmazza a változást megelőző állapotot. (Lsd. A korábbi rendszerváltozók táblázatát.) A „REALTIME” típusnak a rendszeridő az alapja. Ha REALTIME típust állítunk be, akkor a valós rendszeridő idő szerint tudjuk időzíteni a szekcióban deklarált szekvenciák lefutását. A LOGTIME-hoz hasonlóan itt is ”SEC”, ”MINUTE”, ”HOUR”, ”DAY”, ”MONTH” vagy ”YEAR” gyakoriság állítható be. Például „MINUTE” esetén minden perc váltáskor fog lefutni a CHECKPOINT-ban megadott szekvencia. Nézzünk a CHECKPOINT-ra egy egyszerű példát, hogy érthető legyen: A MASSALYZER futás közben nem ír ki különösebb információt a terminálra. Hosszabb futás esetén ez nyugtalanító lehet a visszajelzés hiánya. A CHECKPOINT alkalmas arra is – sok más mellett –, hogy a fő feladat mellett valami olyasmit is végrehajtassunk, ami nem tartozik szorosan a feldolgozás logikájához, de időnként szükséges. Jelen esetben pl. üzenjünk a konzolra, hogy éppen hol tart a feldolgozás. Ez a végeredményt nem befolyásolja a kimeneti fájlban megjelenő végeredményt, de jó, hogy menet közben követni tudjuk a feldolgozás alakulását. (A CHECKPOINT a rendszer flexibilitásához is nagyban hozzájárul. Összetettebb feladatokra is alkalmas, de a működés megértéséhez most ez az egyszerű példa is megfelelő.)
Először is hozzunk létre egy CHECKPOINT-ot arra, hogy 10.000 soronként kiírja a képernyőre, hogy épp melyik sorban tart a feldolgozás (aktuális timestamp), hány sorban talált egyezést. ($ERROR változó tartalmazza, – a CHANNEL fejlécben levő COUNTER=”ERROR” bejegyzés növeli találat esetén.) [CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",TYPE="HARD",VALUE="10000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR $ESC[A\n"
Ahogy láthatjuk a LINE1 érdemi része a nyolcadik paraméter – színezett rész -, az utasítás. Előtte semmi érdemleges nincs beállítva. A SHOW utasítás azt mondja, hogy írja ki konzolra az őt követő szövegeket és paraméterek tartalmát. Itt az első a $ACTDATETIME – ahogy a megadott rendszerváltozók táblázatában is látható – az utoljára beolvasott sor dátumát jelenti. A rendszerváltozó helyét lecseréli az aktuális dátumidő értékkel. Ebből láthatjuk, hogy milyen dátumnál (datetime) tart a feldolgozás. Majd jön a „ LINE: ” szöveg, amit változatlanul kiír. Ezután következik a $READNUMLINES változó, ennek helyére az addig beolvasott sorok száma jön. Aztán a „ FOUND : ” szöveg. Az ezt követő $ERROR egy COUNTER (felhasználói változó) tartalma, ami az ”ERROR” számláló aktuális állását jelenti. A sor végén a $ESC (27-es ACII karakter) és a [A\n intézi el, hogy a következő SHOW ugyanebbe a sorba írjon és ne „fusson a kép” a sok kiírástól. Mivel a számok így is olyan gyorsan peregnek, hogy ebből semmit sem látnánk ezért 1.000.000 soronként – egy újabb CHECKPOINT-ot felhasználva – kiteszünk még egy újabb soremelést.
26
[CHECKPOINT NAME="CHECKPOINT ON 1000000 LINES",TYPE="HARD",VALUE="1000000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW \n"
Az utasításon kívül a többi paramétert is kitölthetnénk, de ezekre viszonylag ritkán lehet szükség a CHECKPOINTOK esetében. Nyilván nem lesz szükségünk arra, hogy N soronként a $WRKSPC (munkaterületet) megváltoztassuk. Általában nem lenne szerencsés, ha a főtevékenység oldaláról nézve „véletlenszerű” helyeken belenyúlna az adatokba. A kompatibilitás érdekében és egyes speciális lehetőségek meghagyása miatt maradt meg ez a lehetőség. Ha mégis használnunk kell a munkaterületet egy CHECKPOINT-ban, akkor gondoskodjunk az aktuális munkaterület ($WRKSPC) elmentéséről és visszaállításáról, hogy a főfolyamat (CHANNEL-ek) számára észrevétlen legyen a dolog. Nézzük meg egyben egy egyszerű .ini-t: (* A GLOBAL, COUNTERS szekciók részletes tárgyalása később lesz, de nélkülük nem futtatható ez az .ini.) [GLOBAL]
INPUT="./Tests/db2diag.log OUTPUT="./Tests/db2diag_filtered.log" TIME_TYPE=”ANY” TIME_FORM="[%Y%m%d %H:%M:%S" [COUNTERS] ERROR=0 [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+========+========+========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"" , "C" ,"=" ,”” ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,”” ,"WRITE $WRKSPC\n"
[CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",TYPE="HARD",VALUE="10000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR $ESC[A\n" [CHECKPOINT NAME="CHECKPOINT ON 1000000 LINES",TYPE="HARD",VALUE="1000000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW \n"
Nézzük meg mi történik, ha lefuttatjuk a fenti összeállítást. A CHANNEL eredmény fájlba kerül, azt most nem látjuk. A két CHECKPOINT-nak köszönhetően viszont már szemmel is követhetőek az események:
27
6. [PRESEQ] és [POSTSEQ] A MASSALYZER-ben lehetőség van elő- és utófeldolgozás beállítására. Ez hasonlóképpen működik, mint a CHECKPOINT-ok, de egyszerűbbek. Az [PRESEQ]nél megadott szekvencia minden más tevékenység előtt fut le egyszer. Értelemszerűen az [POSTSEQ] minden más után, közvetlenül a program kilépése előtt fut le. A kezdés itt csak annyiból áll, hogy kiírjuk a „====== START: 5345 =====” szöveget és egy ENTER-t. ( Ha process id értéke 5345.) [PRESEQ] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","" ,"SHOW ======== START: $PROC_ID ===== \n"
Befejezésül pedig a végső állást és a „====== FINISH: 5345 =====” szöveget. [POSTSEQ] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR \n" LINE2 = "","","","","C","=","","SHOW ====== FINISH: $PROC_ID ===== \n"
Természetesen sokkal összetettebb feladatot is összeállíthatunk, ez csak egy egyszerű példa.
28
Nézzük meg egyben az egészet (kiegészítve PRESEQ-el és POSTSEQ-el): [GLOBAL]
INPUT="./Tests/db2diag.log OUTPUT="./Tests/db2diag_filtered.log" TIME_TYPE=”ANY” TIME_FORM="[%Y%m%d %H:%M:%S" [COUNTERS] ERROR=0 [CHANNEL NAME="DB2 LOG ERROR",COUNTER="ERROR",START_POS="50",END_POS="63",STR_PATTERN="LEVEL: Error",REGEXP=""] #======+=============+=======+=======+=====+========+========+========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "$INPUT_LINE","" ,"" ,"" , "C" ,"=" ,”” ,"WRITE ==== $ACTDATETIME == LINE: $ACTLINE ======" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,”” ,"WRITE $WRKSPC\n"
[CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",TYPE="HARD",VALUE="10000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR $ESC[A\n" [CHECKPOINT NAME="CHECKPOINT ON 1000000 LINES",TYPE="HARD",VALUE="1000000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","","SHOW \n" [PRESEQ] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","" ,"SHOW ======== START: $PROC_ID ===== \n" [POSTSEQ] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES FOUND: $ERROR \n" LINE2 = "","","","","C","=","","SHOW ====== FINISH: $PROC_ID ===== \n"
Futtatáskor a következő kimenetet kapjuk a konzolon:
29
7. [COUNTERS] A [COUNTERS] szekcióban számlálókat definiálhatunk. A számlálóknak kezdeti értéket kell adnunk. A számlálók olyan numerikus változók, melyeket adott esemény megszámlálására használhatunk. [COUNTERS] *EXCEPTION=0 *ERROR=0
Ez lehet automatikus, amikor az adott CHANNEL fejlécében kitöltjük a COUNTER tartalmát egy valós számláló nevével. A CHANNEL-ben ez egy opcionális paraméter. [CHANNEL NAME="DB2 LOG ERROR2",COUNTER="ERROR",STR_PATTERN="LEVEL: Error",REGEXP=""]
Ilyenkor külön beavatkozás nélkül, automatikusan növekedni fog a számlálón, minden olyan esetben, amikor a fejlécben meghatározott illesztések (STR_PATTERN és REGEXP) igaznak bizonyulnak. Ha saját magunk akarjuk – pl. összetettebb feltételek alapján – változtatni a számláló értékét, akkor a 8. paraméterben az INC utasítással növelhetjük és DEC utasítással pedig csökkenthetjük a megadott számláló értékét. A * (csillag) jellel kezdett változók és tartalmuk automatikusan megjelenik a MASSALYZER által megjelenített webfelületen. (Hivatkozni rájuk továbbra is a csillag nélkül kell, az nem része az elnevezésnek.) Ez vonatkozik a normál változókra is. Lsd.: [STRINGS].
8. [CTRL-C] Előfordulhat, hogy le kell állítanunk a MASSALYZER-t, még mielőtt teljesen elvégezte volna a feladatot, vagy épp a real-time feldolgozást kell valamiért megszakítani. Ilyenkor a gyűjtött adataink elvesznének. Például melyik sornál járt a megszakításkor, vagy mi az egyes változók aktuális tartalma. Fontosak lehetnek, ha pl. legközelebb innen folytatnánk. Így nem kell egy hosszú folyamat által előállított részeredményt szükségszerűen elveszítenünk. A [CTRL-C] alatt definiált szekvencia a CTRL-C billentyűkombináció megnyomásakor (off-line módban) vagy a KILL -2 parancs kiadásakor (real-time módban) fut le. Ezáltal kilépés előtt el tudjuk végezni az adatok mentését vagy épp azokat a dolgokat amit a [POSTSEQ] szekvenciának szántunk eredetileg. A [CTRL-C] szekció paraméterei teljesen kompatibilisek az PRESEQ és POSTSEQ és CHANNEL szekciókkal. [CTRLC] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "","","","","C","=","","SHOW YOU PRESSED CTRLC KEYS OR TYPED 'KILL 2 $PROC_ID'\n"
30
9. [GLOBAL] A [GLOBAL] szekció a MASSALYZER általános beállításait tartalmazza.
9.1 - INPUT A feldolgozandó naplófájl (szövegfájl) elérési útvonala és neve. pl.: INPUT="./Tests/db2diag.log" Az itt megadott fájl a feldolgozandó fájl neve. Indításkor megnyitja és ebből a fájlból olvassa fel a bejegyzéseket. Amennyiben a standard inputról szeretnénk fogadni az adatokat, akkor nem kell megadni ezt a paramétert, vagy ”stdin” beállítással adhatjuk meg. Parancssorból (command line) az INPUT paraméter felülbírálható. -i paraméterrel. Például.: "massalyzer test.ini -iinput.txt" Amennyiben a standard inputot akarjuk megadni bemenetnek a parancssorból, akkor itt az -stdin paramétert használhatjuk!
9.2 - OUTPUT OUTPUT="./Tests/db2diag_filtered.log" A WRITE utasítás ebbe a fájlba ír. (Ha nem adunk meg kimenetet, akkor a WRITE a standard outputra ír.) Parancssorból ez a paraméter felülbírálható az -o paraméterrel. Például.: "massalyzer test.ini -ooutput.txt".
31
9.3 - TIME_TYPE TIME_TYPE=”ANY” Lehetséges értékek magyarázatai: NONE
– nincs dátum (Nem igazi log, csak normál szövegfeldolgozáshoz.)
NORMAL
– "2006-09-21 16:00:00:123". Ebből 19 hosszan, másodperc felbontásig értelmezi.
SHORT
– "Sep 21 16:00:00" (a syslog-ng naplózórendszer default beállítása) Sajnos ez nem tartalmaz évet, ezért ezt a MASSALYZER 1970-ként fogja értelmezni. Ugyanígy az ANY esetén is, amennyiben nincs a timestamp-ben évszám.
ANY
– "[%Y-%m-%d %H:%M:%S" *lsd.: TIME_FORM
Az ANY bejegyzés azt jelenti, hogy a dátum formátumát a TIME_FORM paraméterrel állítjuk be. Ez lehetővé teszi a legkülönbözőbb dátumformátumok megadását.
9.4 TIME_FORM TIME_FORM="[%Y-%m-%d %H:%M:%S" Amennyiben a TIME_TYPE paramétert „ANY”-re állítottuk, akkor az időformátum mintáját itt adhatjuk meg. A példában egy IBM WebSphere log (pl. „[2010-11-22 23:48:12”) időbejegyzés előfordulásának megfelelő beállítást láthatunk. Az időformátum helyes megadása nagyon fontos! Ha nem jól adjuk meg az idő formátumát, akkor nem fogja megtalálni a program a bejegyzések határait és így az automatikus bejegyzésekre bontás sem fog működni.
Jobb esetben a fenti figyelmeztetést kapjuk. Ha a log rövid (<64 KByte), akkor lehet, hogy csak azt tapasztaljuk, hogy nem működnek a beállításaink. Nem működnek CHANNEL-ek, mert egyetlen – időpont nélküli – bejegyzésnek veszi az egész állományt.
32
Ha sikerül helyesen összeállítani a timestamp formátumát, akkor megfelelően működik az automatikus (többsoros) bejegyzésekre bontás. Az időformátum megadásához használható jelölések jelentése %%
A % karakter
%a %A
A hét napja a helyi beállítás szerint, rövidített formában vagy a teljes néven
%b %B %h
A hónap neve a helyi beállítás szerint, rövidített formában vagy teljes néven
%C
Az évszázad (0-99)
%d %e
A hónap napja (1-31)
%D
Egyenértékű %m/%d/%y -el
%H
Az óra. (0-23)
%I
Az óra 12 órában. (1-12)
%j
Az év napja. (1-366)
%m
A hónap száma (1-12)
%M
A perc (0-59).
%n %t
Tetszőleges whitespace
%p
A helyi megfelelője AM-nek vagy PM-nek. (Ha létezik.)
%r
Egyenértékű %I:%M:%S %p-vel
%S
A másodperc (0-60). A szökőmásodpercet is elfogad.
%T
Egyenértékű %H:%M:%S.
%U
A hét száma az éven belül, ha a hét vasárnappal kezdődik. (0-53)
%w
A hét napjának száma (0-6) Vasárnap = 0;
%W
A hét száma, melynek első napja hétfő. (0-53) A január első hétfője az első (1) hét első napja
%y
Az évszám évszázad nélkül (0-99) (69-99 →1969-1999 , 00-68 → 2000-2068)
%Y
Az évszám évszázaddal (pl. 2014)
33
9.5 - TIME_POS Előfordulhat, hogy az időbélyeg nem a sor elején található. Ha egy-egy fix karakter található előtte, az még beállítható a TIME_FORM-nál is. Ugyanakkor, ha minden sorban más-más pozíción található a timestamp, akkor ezt már nehezebb behatárolni. Az alábbi példánál pl. megelőzi egy változó hosszúságú mező a dátumot. Így nem tudható, hogy mikor-melyik pozíción jelenik meg. Az alábbi példában egy ilyen eset látható:
A TIME_POS beállításával azonban könnyen megoldhatjuk a feladatot. Ha megnézzük ennek a naplónak a szerkezetét, akkor láthatjuk, hogy itt a dátumot megelőző karakterek a „] ” (bezáró szögletes zárójel és egy space). Ezt használhatjuk fel a timestamp behatárolásához. Nézzük meg a fenti minta teljes időformátum beállításának paramétereit: TIME_TYPE=”ANY” TIME_FORM=”%D %r” TIME_POS=”] ”,”1”
Az TIME_POS első paramétere az a karakterminta amit keresünk. Ha megtalálja, akkor az ezt követő byte-okra fogja illeszteni a megadott TIME_FORM mintát. Így nem okoz az sem gondot, hogy az idő bejegyzés minden sorban más-más pozíción helyezkedhet el. A második paraméter az előfordulás száma. Előfordulhatna olyan is pl. hogy több hasonló mező is megelőzi – a megadottból (pl. „] ”-ból) - a dátumot. Ebben az esetben a második paraméterrel mondjuk meg, hogy hányadik találat után jön a datetime. Nekünk a fenti példában az első találat megfelel. (A default beállítás is 1, tehát a második paramétert üresen is hagyhatnánk.) Ha fentiekre nincs szükség, akkor hagyjuk üresen mindkét paramétert. Ilyenkor ki is hagyhatjuk ilyenkor az egész paramétert az ini-ből. TIME_POS=””,””
34
9.6 - START_LINE Előfordulhat, hogy nem az egész logot akarjuk feldolgozni, hanem mondjuk csak egy részidőszak érdekel minket. Az is előfordulhat, hogy real-time feldolgozás esetén mostantól akarjuk figyelni az eseményeket és ami korábban került bele a logba azt figyelmen kívül szeretnénk hagyni. Ilyenkor lehet érdekes a START_LINE paraméter. START_LINE ="2006.10.28 20:30:00"
A megadott dátumig figyelmen kívül hagyja a sorokat, és csak a megadott datetimemal egyező, és az azt követő idő számít a feldolgozandó sorok közé – adott másodperc. Figyelem! Az log időformátumától függetlenül – egységesen –, a fenti formában kell megadni az időpontot!
Amennyiben a fájl végéről kezdenénk a feldolgozást és csak az újonnan beérkező log sorok érdekelnek, akkor ezt következő értékkel állíthatjuk be: START_LINE ="EOF"
Erre real-time feldolgozás esetén lesz/lehet szükségünk. Ha van egy konkrét sorszámunk (log sorszámunk), amitől szeretnénk indítani a feldolgozást, akkor azt az adott log megfelelő sorszámának megadásával állíthatjuk be. START_LINE ="12345678"
35
9.7 - END_LINE Hasonlóan START_LINE-hoz megadhatjuk a tartomány végét is. Ez nyilván leginkább off-line feldolgozás esetén lehet érdekes. Időponttal megadva tehát: END_LINE ="2006.10.28 20:30:00" Figyelem! A log időformátumától függetlenül mindig a fenti formában kell megadni az időpontot! A megadott másodperc már NEM tartozik bele a tartományba.
Sorszámmal is megadhatjuk a tartomány végét: END_LINE ="12345678" Az itt megadott sorszám már NEM számít bele a tartományba. (Az előző még igen.)
9.8 - RUNNING A RUNNING paraméterrel tudjuk kiválasztani, hogy milyen módon akarjuk használni a MASSALYZER-t. RUNNING=”ONCE”
Ezzel beállítással az parancssoros (off-line) módot használjuk. Ilyenkor egyszer végigfut a megadott szövegen/logon és a végére érve kilép a program. RUNNING=”CONT”
A fájl végére érve nem száll ki, hanem várja a további sorok beérkezését. A program indításkor leválik az őt indító parancs folyamatáról és új folyamatot indít el és a háttérben fut tovább. Ez az un. daemon mód.
36
9.9 - STATUS Előfordulhat, hogy a program indításával nem akarjuk azonnal megkezdeni a feldolgozást. Ezért megadhatjuk, a program indítási státuszát. A STATUS=”RUNNING” beállítás esetén indításkor azonnal indul a feldolgozás.
Ugyanakkor a STATUS=”PAUSE” bejegyzésre nem indul el. Ilyenkor a futást, böngészőn keresztül tudjuk indítani (és megállítani) a „RESUME” (és PAUSE) jelzésű gomb megnyomásával. (Amennyiben a [NETWORK] szekcióban beállítjuk a webes eléréséhez szükséges paramétereket.)
37
9.10 - START_INFO A feladatunk tesztelésénél előfordulhat, hogy szeretnénk látni a MASSALYZER értelmezésében is a beállított paramétereket, vagy éppen egyszerűen dokumentálni szeretnénk az indulási paramétereket. Ekkor jöhet jól ez a beállítás. START_INFO="ON" Induláskor kiírja a fontosabb indulási paramétereket. (* Mivel a MASSALYZER daemon módban lekapcsolódik az indító shell-ről, így ez csak - RUNNING=”ONCE” - esetén működik.)
START_INFO="OFF" - Kikapcsolja a kiírásokat.
38
9.11 - END_INFO A program lefutása után – a fájl végére érve – kiírja az összefoglaló statisztikát. Melyik csatorna hányszor futott le, melyik változónak mi a végleges tartalma: END_INFO=”ON”
Egyszerű feladatoknál vagy egy-egy feladat tesztelésénél egyszerűsítheti a munkát,
hiszen így nem egyesével kell kiíratni az eredményeket. END_INFO=”OFF” - Kikapcsolja a kiírásokat.
39
[MYSQL] A MASSALYZER MariaDB vagy MySQL adatbázissal való kapcsolódásának beállításait tartalmazza. [MYSQL] MYSQL_IP=172.16.208.128 PORT=3306 USER=Massalyzer PASSWD=MassaPassword8364 MYDB=for_tests CONNECT_DB="N"
MYSQL_IP : A MySQL szerver IP címe PORT
: A MySQL szerver portja
USER
: Felhasználónév
PASSWD
: Jelszó
MYDB
: A hasznándó adatbázis
CONNECT_DB: Ha definiált az adatbázis elérés (pl. a [MYSQL] szekcióban), akkor ezzel a paraméterrel lehet be/ki kapcsolni (”Y”/”N”) az adatbázishoz kapcsolódást. Sikeres adatbázis kapcsolat esetén használható az „SQL” utasítás – a 8. paraméterben –, mellyel közvetlenül – SQL utasításokkal – szúrhatunk be rekordokat az adott adatbázisba. A legtöbb adatbázis-kezelő rendszer parancssorból is elérhető a megfelelő kliens feltelepítése után. Így előfordulhat, hogy nincs szükségünk a közvetlen elérésre. (Használhatjuk a SYS parancsot is a SHELLen keresztüli eléréshez.) Az SQL parancsokat – a teljesítmény fokozása érdekében – összegyűjthetjük változóban is, és adott rendszerességgel egyszerre is végrehajtathatjuk.
40
10. [NETWORK] A MASSALYZER tartalmaz egy beépített webszervert, így a futás során tudjuk az adatokat ellenőrizni.
Azok a változók melyeket csillaggal (*) jelöltük meg az .ini fájlban, megjelennek az oldalon. Így egyszerű értékadással (pl. "MOV LAST_ERROR=$WRKSPC") meg tudjuk jeleníteni a számunkra értékes információkat. (A fenti példánál a $LAST_ERROR, $STR_ERROR1 és az $STR_ERROR2 voltak ilyen változók.) Hosszabb szöveges bejegyzésekből többet láthatunk, ha az egérkurzort a tartalom fölé visszük. (Lásd szürke terület.)
10.1 - HTML_TITLE Itt adható meg, hogy a milyen szöveg jelenjen meg az adatok fejlécében. Ez a paraméter akkor lehet fontos, ha több szervert/logot figyelünk párhuzamosan. Ez a paraméter segít a – párhuzamosan futó – MASSALYZER példányok egyszerű megkülönböztethetőségében. HTML_TITLE=”MASSALYZER TEST SERVER”
41
10.2 - LISTENER_PORT Ezzel a paraméterrel megadhatjuk, hogy a beépített webszerver melyik porton szolgáljon ki. A böngészőben ugyanezt a portot kell megadnunk. pl.: „http://192.168.1.11:25000”. Nullás értéket megadva, (LISTENER_PORT=0) teljesen kikapcsolhatjuk a webes elérhetőséget. LISTENER_PORT=25000
10.3 - PRIORITY
("HIGH"/”LOW”) Ennek a paraméternek a szerver módú működés esetén van értelme. A működés során, adott feladattól függően más-más működési mód lehet fontosabb. Lehet, hogy azt szeretnénk, hogy bármikor ránézhessünk az adatokra és ne kelljen várakozni. Más esetben az lehet a fontos szempont, hogy erőforrásokat elsősorban a napló elemzésére fordítsa és csak akkor válaszoljon a böngészőnek, ha éppen nincs más feladata.
Amennyiben a web prioritását magasra („PRIORITY="HIGH"”) állítjuk, akkor a webes kéréseket azonnal kiszolgálja, ha alacsonyra („PRIORITY="LOW"”), akkor csak abban az esetben, ha nincs más – naplóelemzési – feladata. (Pl. a naplóállomány végén várakozik, hogy új bejegyzés érkezzen.) Utóbbi esetben védett a nagy számú http kérések által okozott lassulás ellen.
42
11. [PLUGINS] A speciális igények támogatása érdekében lehetőség van külső függvények felhasználására. Készíthetünk megosztott könyvtárakat (shared library) és felhasználhatjuk az ott elhelyezett függvényeket. A megosztott könyvtárak megnyitásához szükséges információt a [PLUGINS] szekció tartalmazza. [PLUGINS] PLUNGIN_1="/opt/massalyzer/lib/test_plugin.so.1.0" PLUNGIN_2="/opt/massalyzer/lib/test_plugin.so.2.0"
43
12. [STRINGS] Ebben a szekcióban tudjuk deklarálni azokat a változókat, amire az adattároláshoz szükségünk van. A MASSALYZER a számolásra is a szöveges változókat használja. Jelenleg csak egész számokkal dolgozik. Amennyiben a változóban egész (integer) számnak értelmezhető szöveg szerepel, akkor használható az ADD (hozzáadás) és a SUB (kivonás) utasítás. [STRINGS] EVENT="0" WARNING="0" INFO="0" ERROR="0" SEVERE="0"
Ezen kívül a MOV (másolás/mozgatás) és a CAT (hozzáfűzés) utasítások is működnek. A [STRINGS] szekción belül lehetőség van többsoros változók deklarálására is. Két dologra kell odafigyelni. Az egyik az, hogy a kezdő idézőjelnek a változó nevével egy sorban kell elhelyezkednie. A másik az, hogy amennyiben a szöveg maga is tartalmaz idézőjelet, akkor azt egy megelőző \ (backslash) karakterrel kell jelezni (\”). [STRINGS] WARNING="It's a real string variable" INFO=" It's a multiline variable! Apostrofe here:\” "
String változók is tartalmazhatnak más string változókat. Ezekben a tartalmazott változók felhasználáskor (WRITE, SHOW, SEND, stb. utasításokban) cserélődnek le a tartalmukra. A futás során a változó aktuális értéke kerül felhasználásra az utasításban. Kivétel egyedül a MOV utasítás. Ez mindig az eredeti, változatlan formában másolja át a string-eket. [STRINGS] TIME_IS="12:00:00" MESSAGE=”The time is $TIME_IS”
Ahhoz, hogy a felhasználáskor a csere megtörténjen, a tartalmazott változót hamarabb (előrébb, feljebb) kell definiálni/deklarálni, mint az őt tartalmazó string-et. Fontos lehet még, hogy a csere csak egyszeres mélységben hajtódik végre. Tehát, ha a tartalmazott változó is tartalmaz további változókat, azok már nem fognak tartalmukra cserélődni. A 14.2-es mintafeladatban láthatjuk majd ennek gyakorlati hasznát. Amennyiben szeretnénk böngészőből figyelemmel kísérni egy változót értékét futás közben, akkor a neve elé egy * (csillag) karaktert kell beszúrnunk. Ezzel automatikusan kikerül a böngészővel elérhető táblázatba. (Lsd. kép a [NETWORK] szekcióban.) [STRINGS] *MESSAGE=”This is a message”
(Ehhez engedélyeznünk kell a webszerver futását és paramétereket be kell állítani a [NETWORK] szekcióban.)
az
ehhez
szükséges
44
13. Külső függvény létrehozása A következő fejezet kifejezetten programozásban járatos szakembereknek készült. Aki nem járatos a C fejlesztésben, az ezt a fejezetet át is ugorhatja. Elég ha annyit tud, hogy egy C fejlesztésben járatos kolléga a speciális igényeket is képes a MASSALYZER-be integrálni. A MASSALYZER függvényei bővíthetők megosztott könyvtárakkal, ezekben elhelyezett „külső” függvényekkel. Ezeknek az osztott könyvtáraknak meg kell felelnie néhány speciális követelménynek. 1. Egy speciális függvényt tartalmaz, ami megadja az osztott könyvtár publikus függvényeinek neveit. Ezeket használhatjuk az .ini fájlokból. 2. A paraméterek (opcionális) átadás-/átvételének adott struktúrája van. A MASSALYZER osztott könyvtárainak tartalmaznia kell egy olyan függvényt, ami információt szolgáltat a publikus függvényekről. Ha új függvényt akarunk implementálni, akkor fel kell venni a publikus függvények közé, azaz fel kell venni az M_GetPublicFunctionNames függvény által visszaadott paramétersorba. Ez a string vesszővel elválasztott és idézőjelek közé zárva tartalmazza ezen függvények neveit. A MASSALYZER ez alapján tudja ellenőrizni, hogy az általunk az .ini fájlban hivatkozott külső függvény létezik-e. Ha nem létezik, hibaüzenetet kapunk. Így nem fordulhat elő, hogy futás közben ér olyan függvény hivatkozáshoz a MASSALYZER, ami nem létezik a felhasznált osztott könyvtárak egyikében sem. Példaként valósítsuk meg a SubStr függvényt, ami képes egy adott részletet kivágni – kezdő pozíció és hossz alapján – egy megadott string-ből. Tegyük fel, hogy korábban már volt egy Test1 és egy Test2 függvényünk. A visszaadott tartalom eredetileg: \"Test1\",\"Test2\" A SubStr hozzáadása után erre változik: \"Test1\",\"Test2\",\”SubStr\” Nézzük meg a teljes függvényt C forrásban: int M_GetPublicFuntionNames(char * buf) { strcpy(buf,"\"Test1\",\"Test2\",\”SubStr\”"); // Insert new function name return(3); // Number of (public) functions }
Az M_GetPublicFuntionNames függvényt hívja meg a MASSALYZER az adott library megnyitásakor. A visszaadott függvénynevek alapján ellenőrzi, hogy léteznek-e az fájlban megadott függvényhivatkozások. Ha itt nincs a felsorolásban a hívott függvény, akkor a MASSALYZER indításakor hibaüzenetet kapunk. A felsorolásba csak a publikus függvényeinket tegyük, amiket el kell tudnunk érni a MASSALYZERből is. Mivel a jelen MASSALYZER verzióban a függvény paraméterezése kötött így az osztott könyvtár egyes függvényeinek paraméterezését nem kell külön definiálnunk.
45
A visszatérési értéket a $WRKSPC-be tehetjük így az .ini fájl utasításai a külső függvényből való visszatérés után elérhetik. int Test1( PlgParams *Params ) { strcpy(Params>Workspace,"Test 1!"); return(1); }
Amint látható a MASSALYZER hívásakor az átadott paraméter egy struktúrára mutató pointer. A struktúra felépítése a következő: typedef struct { char VersionString[64]; // MASSALYZER version string. char BuildNumber[8]; // MASSALYZER compiled number. char * Workspace; // Pointer to $WRKSPC (read and write); char * CallStr; // Pointer to caller line } PlgParams;
VersionString – A hívó MASSALYZER verziója – a verzióspecifikus függvények támogatásához. BulidNumber – Az adott verzió fordítási száma. Workspace –
Pointer a $WRKSPC területre. Írhatjuk, olvashatjuk. A visszatérési érték – eredmény – itt képződik.
CallStr – 1. Amennyiben CALL paranccsal hívtuk meg a függvényt, akkor ez a pointer mutatja meg a parancssor kezdetét. A MASSALYZER hívás előtt a parancssorban található változók neveit (pl. $VARIABLE) lecseréli a tartalmukra. A CallStr pointer a segítségével paramétereket is tudunk a függvényeknek átadni. A paraméterek megfelelő átvételét a hívott függvénynek kell megoldani. Ez a maximális rugalmasságot szolgálja. A mutatott terület tartalma pl. ehhez hasonló lehet: ”CALL SubStr('Ezzel dolgozom …',6,8)\0”
2. Amennyiben a függvényt a csatorna sorának 4. paraméterből hívtuk (konverzió), akkor a CallStr tartalma NULL! Így azokat a függvényeket érdemes megírni, melynek összes be-/kimeneti paraméterét a $WRKSPC jelenti és nincs szüksége semmi másra. A 4. paraméterben csak a függvény nevét kell megadni – zárójelek nélkül – a felsorolásban. A CallStr-ba értéket visszaírni nem érdemes, mert értéke elveszik.
46
Nézzük a példaként egy megosztott könyvtárban megvalósított függvényt (SubStr) és a hozzá szükséges kiegészítő függvényeket. (Lényegi függvény nem itt, hanem a következő oldalon található.) #include <stdio.h> #include <stdlib.h> #include <string.h> //======================================================================== typedef struct { char VersionString[64]; // MASSALYZER version string. char BuildNumber[8]; // MASSALYZER compiled number. char * Workspace; // Pointer to $WRKSPC for read and write; char * CallStr; // Pointer to caller line – read only. // When used "CALL" keyword for calling this lib. // When you use it direcly from 4th parameter // then will be contain NULL.) } PlgParams; //============================================== // Mandatory funtion //============================================== int M_GetPublicFuntionNames(char * buf) { //================================= // Fill out the function's name //================================= strcpy(buf,"\"SubStr\"");//Return function name(s) of public: //”funct1”,”funct2”,..,”functN” return(1); // Number of (public) function(s) } //========================================================== // GetParams(Parameter line, Parameter array, Max parm num.) // Simple, short version... //========================================================== int GetParams(char * ParamLine,char * Param[],int MaxParam) { int inside=0,i,ParamNum=0; for (i=0; ParamLine[i] && ParamNum<MaxParam; i++) { switch((int) ParamLine[i]) { case '\\': // literal character if(ParamLine[i+1]=='\'') i++; break; case '\'': inside=!inside; break; case '(': if(!inside) { Param[ParamNum++]=&ParamLine[i+1]; } break; case ',': if(!inside) { Param[ParamNum++]=&ParamLine[i+1]; ParamLine[i]=0; } break; case ')': if(!inside) { Param[ParamNum++]=&ParamLine[i+1]; ParamLine[i]=0; } break; } } return(ParamNum); }
47
//========================================================== // SubStr(PlgParams *Params ) //========================================================== int SubStr(PlgParams *Params ) { int start,length; char *str_start; char *params[4]; // We need 3 parameters if(GetParams(Params>CallStr,params,4)!=3) return(1);//The return value accessable via //$PLUGIN_RET. For example: 1 error // Skip first apostrophe str_start = ¶ms[0][1]; //Get start position and length start = atoi(params[1]); length = atoi(params[1]); memcpy(&Params>Workspace[0],&str_start[start],length); Params>Workspace[length]=0; return(0); // The return value will be available in $PLUGIN_RET variable after return. }
A lényegi részt az utolsó return(0); előtti két sor végzi. A függvény visszatérési értéke – ami kötelezően integer – a MASSALYZER-be való visszatérés után elérhető lesz a $PLUGIN_RET rendszerváltozóban további felhasználásra. A fordítás folyamata a következő: 1, Elmentjük a forrást pl. test_plugin.c néven. 2, Létrehozzuk az objectet: gcc -Wall -fPIC -s -O2 -c test_plugin.c 3. Létrehozzuk a megosztott könyvtárat: gcc -shared -Wl,-soname,test_plugin.so.1 -o test_plugin.so.1.0 test_plugin.o Az általunk írt függvény felhasználásához az ini-fájlban hivatkozni kell az általunk létrehozott osztott könyvtárra a [PLUGINS] szekcióban. [PLUGINS] PLUNGIN_1="/opt/massalyzer/lib/test_plugin.so.1.0"
48
Az elkészített függvényt CALL utasítás segítségével tudjuk meghívni a LINE1 nyolcadik paraméterében. [CHANNEL NAME="DB2 LOG ERROR2",STR_PATTERN="LEVEL: Error"] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"CALL SubStr('$ACTDATETIME',0,10)" LINE2 = "" ,"" ,"" ,"" , "C" ,"=" ,"" ,"SHOW $WRKSPC\n"
Amennyiben olyan függvényt hozunk létre aminek nincs paramétere (pl. a $WRKSPC területtel dolgozik és oda is helyezi el a végeredményt), akkor a 4. paraméterből is hívható a hívott konverziók között a nevének beírásával. Ilyenkor a „()” zárójeleket nem kell – nem is szabad – kitenni, csak a nevet beírni. (Lds. 4 paraméter leírása.) A paraméterbe írt változók vagy rendszerváltozók lecserélődnek a tartalmukra. (Itt pl. a $ACTDATETIME helyett az aktuális – log szerinti – timestamp [pl. „2012.03.19 09:35:13”] fog szerepelni. A fenti SubStr végrehajtása után pl. „2012.03.19” lesz az eredmény.) Ez fog megjelenni, ha pl. a következő sorban egy "SHOW $WRKSPC\n" utasítást adunk ki.
49
14. Mintafeladatok 14.1 - Készítsünk CSV-t! Az alábbiakban bemutatjuk, hogy a gyakorlatban miképpen használhatjuk ki a MASSALYZER rugalmasságát. A CSV (comma-separated values) egy egyszerű és elterjedt formátum. Nézzünk egy példát, hogyan hozhatunk létre egy ilyen fájlt azokból az adatokból, amelyek a naplóban számunkra érdekesek. Tegyük fel, hogy szeretnénk megtudni, hogy egy adott log-fájlban hogyan alakultak a hibák perces maximumai. Ehhez szükségünk van az adott perces időpontra és a hozzá tartozó hiba darabszámára. Hibának az a sor számít, ahol a megfelelő pozíción megjelenik a „LEVEL: ERROR” bejegyzés. Csak azok a percek érdekesek, ahol legalább egy hiba volt. Ezeket a sorokat kell összeszámolni és percenként lejegyezni CSV formában, hogy azt más program számára is feldolgozható legyen. A sorok (rekordok) egyes mezőit pontosvesszővel (;) fogjuk elválasztani. Így könnyen betölthetjük az adatokat egy táblázatkezelő programba, azzal a céllal, hogy egy átfogó képet kapjunk az adott időszakról. Alább egy többsoros (jellemzően 5-100) bejegyzésekből álló log egy részletét láthatjuk: 2012-02-11-22.07.22.696607+060 E41321E373 LEVEL: Event PID : 31252 TID : 47133788989760PROC : db2sysc 0 INSTANCE: db2inst1 NODE : 000 EDUID : 79 EDUNAME: db2hadrp (HADRDB) 0 FUNCTION: DB2 UDB, High Availability Disaster Recovery, hdrSetHdrState, probe:10000 CHANGE : HADR state set to P-Peer (was P-NearlyPeer)
2012-02-11-22.10.15.094712+060 I41695E507 LEVEL: Event PID : 31252 TID : 47133793184064PROC : db2sysc 0 INSTANCE: db2inst1 NODE : 000 DB : HADRDB APPHDL : 0-28 APPID: *LOCAL.DB2.120211210715 AUTHID : DB2INST1 EDUID : 50 EDUNAME: db2stmm (HADRDB) 0 FUNCTION: DB2 UDB, config/install, sqlfLogUpdateCfgParam, probe:20 CHANGE : STMM CFG DB HADRDB: "Database_memory" From: "228224" To: "238100" 2012-02-11-22.20.45.252101+060 I42203E380 LEVEL: Warning PID : 1174 TID : 47476201794720PROC : db2haicu INSTANCE: db2inst1 NODE : 000 FUNCTION: DB2 Common, SQLHA APIs for DB2 HA Infrastructure, sqlhaGetPolicyTypeFromSysFile, probe:400 MESSAGE : No matching instance record ... setting policy to none DATA #1 : unsigned integer, 4 bytes 0 2012-02-11-22.20.45.627809+060 E42584E319 LEVEL: Error PID : 1174 TID : 47476201794720PROC : db2haicu INSTANCE: db2inst1 NODE : 000 FUNCTION: <0>, <0>, <0>, probe:10000 RETCODE : ZRC=0x827300CF=-2106392369=HA_ZRC_OBJECT_DOES_NOT_EXIST "Cluster object does not exist" 2012-02-11-22.20.45.752326+060 E42904E319 LEVEL: Error PID : 1174 TID : 47476201794720PROC : db2haicu INSTANCE: db2inst1 NODE : 000 FUNCTION: <0>, <0>, <0>, probe:10000 RETCODE : ZRC=0x827300CF=-2106392369=HA_ZRC_OBJECT_DOES_NOT_EXIST "Cluster object does not exist" 2012-02-11-22.21.14.201559+060 I43224E529 LEVEL: Warning PID : 31252 TID : 47133784795456PROC : db2sysc 0 INSTANCE: db2inst1 NODE : 000 APPHDL : 0-64 APPID: *LOCAL.db2inst1.120211212045 AUTHID : DB2INST1 EDUID : 80 EDUNAME: db2agent (instance) 0 FUNCTION: DB2 Common, SQLHA APIs for DB2 HA Infrastructure, sqlhaGetPolicyTypeFromSysFile, probe:400 MESSAGE : No matching instance record ... setting policy to none DATA #1 : unsigned integer, 4 bytes 0
Ennek a feladatnak a megoldására nem szeretnénk 5 percnél több időt szánni. Nézzük, hogyan tudjuk ezt megoldani a MASSALYZER segítségével.
50
A feladat elvégzéséhez szükséges .ini fájl – némi magyarázattal: #======================================================================================================= # log2csv.ini #======================================================================================================= [GLOBAL] INPUT="./Tests/db2diag.log" OUTPUT="./Tests/db2diag_report.csv" TIME_TYPE="ANY" TIME_FORM="%Y%m%d%H.%M.%S." [STRINGS] MIN=”0” [CHANNEL NAME="ERROR COUNTER",STR_PATTERN="LEVEL: Error"] #======+=============+=============+==============+=============+========+========+=============================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=============+==============+=============+========+========+=============================+ # | Input | Cut start | Cut end | Conversion | Cont. | '='/'!'| Instruction | #======+=============+=============+==============+=============+========+========+=============================+ LINE1 = "" ,"" ,"" ,"" , "C" ,"=","" ,"ADD MIN=1" [CHECKPOINT NAME="CHECKPOINT PER MINUTE",TYPE="LOGTIME",VALUE="MINUTE"] #======+=============+=============+==============+=============+========+========+=============================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=============+==============+=============+========+========+=============================+ # | Input | Cut start | Cut end | Conversion | Cont. | '='/'!'| Instruction | #======+=============+=============+==============+=============+========+========+=============================+ LINE1 = "$MIN" ,"" ,"" ,"" , "F" ,"=","0" ,"" LINE2 = "" ,"" ,"" ,"" , "C" ,"=","" ,"WRITE $PREVMINUTE:00;$MIN\n" LINE3 = "" ,"" ,"" ,"" , "C" ,"=","" ,"MOV MIN=0"
A [GLOBAL] szekcióban beállítjuk az input és output fájlt: INPUT="./Tests/db2diag.log" OUTPUT="./Tests/db2diag_report.csv
: A feldolgozandó log. : Az eredményfájl.
Azután az időformátum beállítása következik: TIME_TYPE=”ANY” TIME_FORM="%Y%m%d%H.%M.%S."
: Tehát a formátuma TIME_FORM paraméterrel adható meg. : A log-fájlban található timestamp formátum(ÉVHÓNAPÓRA.PRC.MPRC.)
A [STRINGS] szekcióban létrehozunk egy változót. Ebben fogjuk tárolni az eredményt amíg ki nem írjuk. MIN=”0” – MIN nevű változó, nulla kezdőértékkel. Létre kell hoznunk egy csatornát, ami felismeri az adott mintát: [CHANNEL NAME="ERROR COUNTER",STR_PATTERN="LEVEL: Error"] Amennyiben felismeri a megadott (STR_PATTERN) mintát, akkor hozzá kell adnunk egyet az erre létrehozott MIN változóhoz. Ezt a 8. paraméterben tudjuk megtenni. Hozzáadunk egy sort (LINE1=...) és bejegyezzük a 8. paraméterhez: "ADD MIN=1". Ez elvégzi a MIN változó növelését. (Értékadásnál nem kell kitenni a $ jelet a változó elé.) Ezzel az egyetlen bejegyzéssel megoldottuk a számlálást.
51
A következő feladat, hogy percenként (ha volt bejegyzés) írjuk ki a számláló értékét a megfelelő formátumban, azután nullázzuk le a számlálót, hogy a következő perc is nulláról induljon. Ahhoz, hogy ezt a megfelelő pillanatban tudjuk megtenni, segítségünkre lesz a [CHECKPOINT...], amit már korábban bemutattunk. [CHECKPOINT NAME="CHECKPOINT PER MINUTE",TYPE="LOGTIME",VALUE="MINUTE"] A típusa LOGTIME lesz, mert a log-idő alapján szeretnénk „megszakítást” végeztetni. A VALUE értéke pedig MINUTE, mert a perc változására figyelünk. Az első sorban lényegében három (1.,5.,7.) paramétert kell kitöltenünk: 1. 5. 6. 7.
LINE1 = "$MIN","","”,"”,"F” ,"=" ,"0”, "" Az első paraméter „$MIN” azt jelenti, hogy a számlálónk tartalmát bemásoljuk a WRKSPC-re. Erre azért van szükség, hogy a 7. paraméterben megadott ”0”-val össze tudjuk hasonlítani a tartalmát. Amennyiben a két érték egyezik, akkor nem szeretnénk, hogy a szekvencia a következő soron folytatódjon (hiszen a számlálónk nulla volt és ezt az értéket nem szeretnénk kiírni). A folytatást az 5. paraméterben megadott „F” (false) értékkel akadályozzuk meg. Így abban az esetben, ha a MIN értéke 0, nem fog ráfutni a kiírást végző részre. Ellenkező esetben, ha a $MIN értéke nem nulla, akkor tovább folytatja a szekvencia végrehajtását a következő sorral. 1. ... 8.
LINE2 = ""… ,"WRITE $PREVMINUTE:00;$MIN\n" A második sorban csak az utolsó (8.) paraméter (instruction) lényeges. A WRITE utasítással kiírjuk a perc értékét ($PREVMINUTE). Mivel ez csak a percig tartalmazza a timestamp értékét – hiszen a másodpercek nem játszanak szerepet –, így ezek helyét „:00”-ra cseréljük a formátum megtartása kedvéért. Így teljes dátumidőt kapunk. Ezután jön a CSV fájloknál használatos határolójel, a pontosvessző. Majd a $MIN értékkel a darabszámot is kiíratjuk. Még egy feladtunk maradt. A számlálót ki kell nulláznunk, hogy következő perc számlálását nulláról kezdje. Ezt a harmadik sorban elhelyezett utasítás végzi el:
„MOV MIN=0" Ezzel végeztünk is a feladat megoldásával. Csak le kell futtatnunk a MASSALYZER-t:
$ massalyzer log2csv.ini Az eredmény néhány másodpercen belül rendelkezésre áll. A jobboldali listán láthatjuk a kapott CSV szövegfájl elejét. (6575 db ilyen találatunk volt.) Látható az időbélyeg, az elválasztó „;” és az adott perchez tartozó darabszám.
2012.02.11 22:20:00;2 2012.02.11 22:50:00;2 2012.02.11 22:51:00;1 2012.02.12 00:13:00;1 2012.02.12 08:09:00;1 2012.02.12 11:31:00;1 2012.02.12 14:35:00;1 2012.02.12 16:50:00;1 2012.02.12 20:07:00;1 2012.02.12 20:52:00;1 2012.02.12 21:22:00;1 2012.02.12 22:02:00;6 2012.02.12 22:05:00;3 2012.02.12 22:17:00;1 2012.02.12 22:20:00;2 2012.02.12 22:22:00;1 2012.02.12 22:33:00;1 2012.02.12 22:37:00;1 2012.02.12 22:43:00;1 2012.02.13 02:27:00;1 2012.02.13 03:56:00;1 2012.02.13 05:02:00;1 2012.02.13 09:16:00;1 2012.02.14 02:42:00;1 . . 52
Az így elkészített .csv fájlt egy táblázatkezelőbe töltve, majd kirajzoltatva, az alábbi diagram áll elő:
A feladatot minimális energiabefektetéssel megoldottuk. További előny, hogy ha egy teljesen más formátumú naplóállományon lenne hasonló feladatunk, akkor TIME_FORM-ot (szükség esetén a STR_PATTERN-t, vagy REGEXP-et is) átírva, már képessé tettük annak feldolgozására is.
53
14.2 - Komplett diagram automatikusan Az előző példában láthattunk egy megoldást arra, hogy miképp állítunk elő CVS fájlt további manuális feldolgozáshoz. Egy másik életszerű példa, amikor nem szeretnénk az adatokkal manuálisan dolgozni, hanem egy teljesen automatikus rendszert akarunk beállítani. Például szeretnénk, ha a rendszer bemenete a log-fájl lenne és a kimenet egy kép állomány. Ezt azután számtalan módon publikálhatjuk. Egy webszerveren keresztül, vagy épp időszakos összefoglaló mellékleteként is elküldhetjük egy mail paranccsal. A lényeg, hogy külön beavatkozás nélkül készüljön el a végeredmény, pl. az előzőhöz hasonló diagram. Hogyan hozzunk létre meghatározott időszakra?
egy
összefoglaló
diagramot
az
adatokból,
Sok különböző megoldás lehetséges. Ebben a megoldásban az ingyenesen hozzáférhető, gnuplot programot használjuk. Több platformra elérhető, így Linuxon is rendelkezésre áll. (http://www.gnuplot.info) Telepítés után parancssorból futtatható. Ez számunkra megfelelő, mert a MASSALYZER SYS utasításával el tudjuk érni. A diagram elkészítéséhez három lényeges dolgot kell tennünk: 1. A naplóállományból meg kell szerezni a szükséges információt és a megfelelő formában el kell készíteni a szükséges adatfájlt. Ez most egy több oszlopos szöveges fájl lesz. Az egyes oszlopok egy-egy eseménytípust reprezentálnak. Az első oszlop tartalma timestamp lesz. 2. Létre kell hozni egy konfigurációs fájlt. Ez a gnuplot számára (plot fájl) tartalmazza a beállításokat, utasításokat. Ez határozza meg az adatok forrását, típusát, formáját és a diagram egyéb tulajdonságait. 3. A megfelelő paraméterekkel meg kell hívnunk a gnuplot-ot, hivatkozva az elkészített plotfájlra. Nézzük a szükséges ini-fájlt lépésenként: Először meghatározzuk időformátumot.
a
forrás-
és
célfájlt,
valamint
a
logban
használt
#=============================================================================================== # chart_demo.ini #=============================================================================================== [GLOBAL] INPUT="./Tests/db2diag.log" OUTPUT="./Tests/db2_to_graph.dat" TIME_TYPE="ANY" TIME_FORM="%Y%m%d%H.%M.%S."
Kellenek változók, amiben tároljuk a számláláshoz szükséges információt. A MASSALYZER-ben a számítások eredményei is string-ekben tárolódnak. Ennek maximális mérete 64Kbyte lehet.
54
Létrehozzuk a megfelelő változókat a számlálókhoz. A kezdeti értékeket is megadjuk (0). [STRINGS] EVENT="0" WARNING="0" INFO="0" ERROR="0" SEVERE="0"
Létrehozzuk a plotfájl-t is egy változóban. Ezt fogjuk majd kiírni és végrehajtatni. Létrehozhatnánk egy külön fájlt is, de így egy szebb, kompakt megoldásunk lesz. Deklaráljuk a plotfájlhoz szükséges változókat: IMAGEPATH="/home/pet/Massalyzer/Desktop/massalyzer_test.png" DATASOURCE="/home/pet/Massalyzer/Tests/db2_to_graph.dat" PLOTFILE=" set title \"LOG ANALYZING EXAMPLE BY MASSALYZER\" font \"arial,16\" set xdata time set style data lines set term png size 800,500 enhanced set grid x y set font \"arial,10\" set timefmt \"%Y.%m.%d %H:%M\" set format x \"%Y.%m.%d\" set xlabel \"Time\" set ylabel \"Events/Min.\" set yrange [ 0 : 50] set xtics font \"arial, 10\" set xrange [\"2012.02.20 00:00\":\"2012.02.28 00:00\"] set output \"$IMAGEPATH\" set datafile separator \"\\t\" plot \ \"$DATASOURCE\" u 1:2 t \"Event\" w lines,\ \"$DATASOURCE\" u 1:3 t \"Warning\" w lines,\ \"$DATASOURCE\" u 1:3 t \"Info\" w lines,\ \"$DATASOURCE\" u 1:4 t \"Error\" w lines,\ \"$DATASOURCE\" u 1:5 t \"Severe\" w lines"
A [STRINGS] szekción belül lehetőségünk van többsoros értékeket is megadni. A deklaráció az első idézőjellel kezdődik és a másodikkal végződik. Amennyiben a deklaráción belül is szükségünk van idézőjelre, akkor egy megelőző \” (backslash) jel segítségével tudjuk jelezni. Erről felismerhető, hogy nem a befejező idézőjel következik. (Arra figyeljünk, hogy a nyitó idézőjelnek mindenképp a változó nevével azonos sorban legyen!) Két részletet kivettünk az eredeti plotfájlból. (A fenti ábrán vastaggal jelölve.) Definiáltunk az IMAGEPATH és a DATASOURCE változókat. Mivel ezek a PLOTFILE változó előtt lettek definiálva így hivatkozhatunk rá a PLOTFILE változóban. Ez egyrészt egyszerűsítette is a PLOTFILE-t, másrészt, ha szükséges könnyen és egyetlen helyen kell csak módosítanunk. Első feladatunk, hogy a naplóállományból (log) létrehozzuk azokat az adatokat, melyből a diagram megrajzolható. Perces összesítéseket szeretnénk az állományban előforduló különböző eseményekből.
55
Az öt esemény (Warning, Error, Severe, Info, Event) felismerése érdekében mindegyikhez készítünk egy-egy csatornát. Mindegyik a naplóállományban előforduló megfelelő minta előfordulására aktiválódik. Ezt a csatornák fejlécében az STR_PATTERN megadásával tudjuk elérni. (Például STR_PATTERN="LEVEL: Event") Az adott minta megtalálásakor lefut a hozzá tartozó csatornában deklarált szekvencia. Mivel a fejlécben megadott szűrési feltétel elég, így a csatornán belül nem kell további ellenőrzéseket végezni. Egyetlen dolgunk maradt, hogy a korábban előkészített számlálót megnöveljük. Ezt az utolsó paraméterben (instruction) megadott utasítással végezhetjük el. Az ADD EVENT=1 eggyel növeli az adott EVENT változó értékét. [CHANNEL NAME="EVENT COUNTER",START_POS="50",END_POS="70",STR_PATTERN="LEVEL: Event"] #======+=============+=======+=======+=====+=======+========+=========================================+ # LINE | 1 | 2 | 3 | 4 | 5 | 67 | 8 | #======+=============+=======+======+======+=======+========+=========================================+ # | Input | Cut | Conv.| Criteria | Instruction | #++++++|+ # | | | | | Cont. |6. =/! | | # | | Start | End | | |7.regexp| | #======+=============+=======+======+======+=======+========+=========================================+ LINE1 = "" ,"" ,"" ,"" ,"C" ,"=" ,"" ,"ADD EVENT=1" [CHANNEL NAME="WARNING COUNTER",START_POS="50",END_POS="70",STR_PATTERN="LEVEL: Warning"] LINE1 = "" ,"" ,"" ,"" ,"C" ,"=" ,"" ,"ADD WARNING=1" [CHANNEL NAME="ERROR COUNTER",START_POS="50",END_POS="70",STR_PATTERN="LEVEL: Error"] LINE1 = "" ,"" ,"" ,"" ,"C" ,"=" ,"" ,"ADD ERROR=1" [CHANNEL NAME="SEVERE COUNTER",START_POS="50",END_POS="70",STR_PATTERN="LEVEL: Severe"] LINE1 = "" ,"" ,"" ,"" ,"C" ,"=" ,"" ,"ADD SEVERE=1" [CHANNEL NAME="INFO COUNTER",START_POS="50",END_POS="70",STR_PATTERN="LEVEL: Info"] LINE1 = "" ,"" ,"" ,"" ,"C" ,"=" ,"" ,"ADD INFO=1"
Minden mintára létrehoztuk a megfelelő műveletet. Így az események számlálása elkészült. Ha a naplóállományon belüli teljes összesítést szeretnénk készíteni, akkor készen is lennénk. A feladat viszont most a perces összegek meghatározása. Ehhez fel kell ismerni, hogy új perc kezdődik, ki kell menteni az értékeket, le kell nullázni a számlálókat, hogy a következő percben számláló újra nulláról induljon. A MASSALYZER felismeri, ha új perc kezdődik, így ezt könnyű megoldani. Nekünk csak be kell állítanunk és kell határoznunk, hogy ilyenkor mit tegyen. Erre való a [CHECKPOINT]. [CHECKPOINT NAME="WRITE OUT",TYPE="LOGTIME",VALUE="MINUTE"] LINE1 = "","","","","C","=","","WRITE $PREVMINUTE\t$EVENT\t$WARNING\t$INFO\t$ERROR\t$SEVERE\n" LINE2 = "","","","","C","=","","MOV EVENT=0" LINE3 = "","","","","C","=","","MOV WARNING=0" LINE4 = "","","","","C","=","","MOV INFO=0" LINE5 = "","","","","C","=","","MOV ERROR=0" LINE6 = "","","","","C","=","","MOV SEVERE=0"
A CHECKPOINT fejlécében található „LOGTIME” és „MINUTE” beállítások mondják meg, hogy idő szerinti és azon belül perces „megszakításokat” („interrupt”) kérünk. Az első sorban (LINE1) történik az adatok mentése. Egy WRITE utasítással kiírjuk a kimeneti adatfájlba a számlálók tartalmát. A következő sorokban pedig semmi más nem teszünk, mint sorban minden egyes számlálót lenullázzuk. Ezzel elvégeztük az adatok perces összegének mentését. A kimeneten rendre meg fognak jelenni azon percek összesítései, melyekhez létezett bejegyzés ez eredeti naplóállományban.
56
Hogy az adatfájl emberi szemmel is jól nézzen ki, jó, ha teszünk egy fejlécet az adatok elé. [PRESEQ] LINE1 = "","","","","C","=","","SHOW ======== START: $PROC_ID ======= \n" LINE2 = "","","","","C","=","","WRITE #\tTIMESTAMP\tEVENT\tWARNING\tINFO\tERROR\tSEVERE\n"
Ezt legegyszerűbben a [PRESEQ]-ben tehetjük meg a WRITE utasítással. (LINE2) Ezzel az adatfájl elkészítésével végeztünk. Ha végrehajtatjuk az eddigieket és megnézzük a kész adatfájl elejét, következőt láthatjuk:
Már csak létre kell hoznunk a kapott adatfájlból a diagramot. Mint már tudjuk, a MASSALYZER a log feldolgozása után kilép, előtte azonban még lefuttatja az [POSTSEQ]-ben meghatározott sorokat. Ezt fogjuk felhasználni. Mire a folyamat ideér, addigra az adatfájlunk elkészült és felhasználhatjuk. [POSTSEQ] LINE1 = "", "", "" ,"" , "C" ,"=","" ,"SHOW ====== GENERATE CHART ======= \n" LINE2 = "", "", "" ,"" , "C" ,"=","" ,"SYS echo '$PLOTFILE' >/tmp/MassTmp_$PROC_ID.plot" LINE3 = "", "", "" ,"" , "C" ,"=","" ,"SYS gnuplot p /tmp/MassTmp_$PROC_ID.plot" LINE4 = "", "", "" ,"" , "C" ,"=","" ,"SYS rm /tmp/MassTmp_$PROC_ID.plot" LINE5 = "", "", "" ,"" , "C" ,"=","" ,"SHOW ====== FINISH: $PROC_ID ======== \n"
A lényegi részt a LINE2 - LINE4 sorok végzik. Először egy SYS utasítással kiadunk egy echo parancsot, amivel a korábban definiált $PLOTFILE tartalmát kiírjuk a /tmp könyvtárba. Ha a fájl nevébe tesszük a $PROC_ID változót, akkor az megvéd attól, hogy több MASSALYZER példány „összeakadjon” az azonos átmeneti fájl nevének azonossága miatt. (Itt most nincs rá feltétlen szükség, mert nem futtatjuk egyszerre több példányban.)
57
Nézzünk bele a kiírt plotfájl tartalmába:
Ez idáig rendben van. A következő lépés a gnuplot futtatása a megfelelő paraméterekkel. Ezt a LINE3-as sorban található "SYS gnuplot p /tmp/MassTmp_$PROC_ID.plot" utasítás végzi. Miután végzett a gnuplot, jó ha töröljük a már szükségtelenné vált ideiglenes fájlt, hogy ne halmozódjanak fel feleslegesen a minden egyes futtatáskor létrejövő plotfájlok. Ezt elvégzi el a LINE4-ben a "SYS rm /tmp/MassTmp_$PROC_ID.plot" parancs. Ha megnézzük az elkészült massalyzer_test.png-t, akkor láthatjuk a végeredményt:
58
Létrehozhattunk volna nagyobb felbontású és még látványosabb diagramokat is – a gnuplot oldalán válogathatunk a rendelkezésre álló kollekcióból. A gnuplot-hoz hasonlóan alkalmazhatunk bármilyen más plotter programot is. A MASSALYZER-ben az a jó, hogy a kimeneti formátumot könnyen hozzáigazíthatjuk bármilyen textfájlból dolgozni tudó programhoz. A fenti mintafeladat egy off-line feldolgozás volt. Nagyon hasonlóan készíthetünk realtime feldolgozás esetén is rendszeres diagramokat. Eben az esetben a gnuplot meghívása nem az [ENSEQ] szekcióba kerül, hanem a megfelelő időközönként beállított [CHECKPOINT] futtatná le. Adott esetben számlálót is használhatunk arra, hogy valamely időköz (perc, nap,...stb.) többszöröseként futtassuk a külső parancsot, úgy hogy a növelések mellett csak a megfelelő érték elérése (feltétel) mellett fusson le. [COUNTERS] MIN_COUNT=0 . . [CHECKPOINT NAME="TEN MINUTES",TYPE="REALTIME",VALUE="MINUTE"] LINE1 = "","","","" ,"C","=","" ,"INC MIN_COUNT" LINE2 = "$MIN_COUNT","","","" ,"Y","=","10","" LINE3 = "","","","" ,"C","=",”" ,"CLR MIN_COUNT" LINE4 = "","","","" ,"C","=",”" ,"SYS <SHELL COMMAND>" . .
Ebben példában minden 10. percben fut le a hívott shell parancs.
59
15. Külső TCP kapcsolat A massalyzer-ben található szerver nem csak HTTP kérések kiszolgálására alkalmas. Azt már láttuk, hogy HTTP protokollon keresztül miképp érhetünk el bizonyos adatokat. Van egy másik lehetőség is az adatok elérésre. A HTTP jó szemrevételezéshez, de program-program közötti real-time adatátvitelhez nem feltétlen a legideálisabb, mert ehhez rendszeres pollingra lenne szükségünk. Az .iniben lehetőség van TCP/IP kapcsolatot definiálni. Ennek real-time adatfeldolgozás esetén van értelme. Lehetőség van arra, hogy a külső program TCP/IP-n keresztül adatokat kaphasson a MASSALYZER futása közben. Ez is ugyanazon a porton működik, mint amire a http szervert (LISTENER_PORT) állítottuk. Ha telnet-tel (teszteléshez, egyébként megfelelő célprogrammal) kapcsolódunk a MASSALYZER-hez, akkor képes azt beléptetni. A felhasználónév alapján azonosítja a kapcsolatot. A beléptetés után, a kapcsolat megkap minden olyan üzenetet, amit SEND utasítással az adott kapcsolatnak (kliens) küldünk. (Ha épp nincs ilyen nevű aktív kapcsolat amikor a SEND parancsra fut, akkor nem küld üzenetet. Amennyiben több kapcsolat is fut azonos néven, akkor minden egyes – az adott névvel azonosított – kliens megkapja az adott névre szóló üzenetet. Ha nincs olyan fájlunk, ami elég nagy, akkor nehezen fogjuk tudni kipróbálni, mert mire a telnet-tel rákapcsolódnánk, esetleg már végzett is a munkával. Vagy real-time módban kell indítanunk, vagy a [GLOBAL] szekcióban a STATUS-t „PAUSE” állásba kell tennünk, hogy indulás után ne kezdjen el azonnal dolgozni. Ez élesben nyilván nem lesz szükséges, ezért a mintában megjegyzésbe (comment) tettem ezt a sort. Ilyenkor böngészőből indíthatjuk el a feldolgozást. A működéséhez be kell állítani a [NETWORK] szekcióban a megfelelő portot. Ezenkívül, ha azt szeretnénk, hogy a MASSALYZER azonnal kiszolgálja a kérésinket, akkor érdemes a PRIORITY-t is „HIGH”-ra állítani. [GLOBAL] #STATUS="PAUSE" [NETWORK] LISTENER_PORT=”25000” PRIORITY="HIGH" [LOGIN] #Password converted to MD5 Hash TEST="5f4dcc3b5aa765d61d8327deb882cf99"
A [LOGIN] szekcióban tudjuk felsorolni az azonosító és jelszó párokat. TEST="5f4dcc3b5aa765d61d8327deb882cf99" A fenti példánál a TEST lesz a bejelentkezési név. Az idézőjelek között pedig a jelszó MD5-ös hash kódját kell feltüntetni.
60
Most már tudunk kapcsolódni a MASSALYZER-hez TCP/IP-n. Telnet-tel ellenőrizhetjük a kapcsolatot. Hogy értelme is legyen a kapcsolatnak, némi forgalmat is generálunk. Egészítsük ki a korábbi példánál látott, kifejezetten a program futásának követhetőségét biztosító kijelzést. Így nem csak a konzolon, hanem a távoli kliensen is követhetővé válik a folyamat. [PRESEQ] LINE1 = "","","","" ,"C","=","" ,"SHOW ======== START: $PROC_ID ======= \n" LINE2 = "","","","","C","=","","WRITE #\tTIMESTAMP\tEVENT\tWARNING\tINFO\tERROR\tSEVERE\n" [CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",TYPE="HARD",VALUE="10000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW $ACTDATETIME LINE: $READNUMLINES$ESC[A\n" LINE2 = "" , "", "","","C","=","","SEND TEST=$ACTDATETIME LINE: $READNUMLINES$ESC[A\n" [CHECKPOINT NAME="CHECKPOINT ON 1000000 LINES",TYPE="HARD",VALUE="1000000"] #============================================ # 1 2 3 4 5 6 7 8 #============================================ LINE1 = "" , "", "","","C","=","","SHOW \n" LINE2 = "" , "", "","","C","=","","SEND TEST=\n" [POSTSEQ] LINE1 = "", "", "" ,"" , "C" ,"=","" ,"SHOW $ACTDATETIME LINE: $READNUMLINES\n" LINE3 = "", "", "" ,"" , "C" ,"=","" ,"SHOW ====== GENERATE CHART ======= \n" LINE4 = "", "", "" ,"" , "C" ,"=","" ,"SYS echo '$PLOTFILE' >/tmp/MassTmp_$PROC_ID.plot" LINE5 = "", "", "" ,"" , "C" ,"=","" ,"SYS gnuplot p /tmp/MassTmp_$PROC_ID.plot" LINE6 = "", "", "" ,"" , "C" ,"=","" ,"SYS rm /tmp/MassTmp_$PROC_ID.plot" LINE7 = "", "", "" ,"" , "C" ,"=","" ,"SHOW ====== FINISH: $PROC_ID ======== \n" LINE8 = "", "", "" ,"" , "C" ,"=","" ,"SEND TEST=\n====== FINISH: $PROC_ID ======== \n"
Nézzük, hogyan kapcsolódhatunk MASSALYZER-hez és mi történik?
ezek
után
a
már
beállított
és
elindított
A programindításra a program elindul, de a feldolgozás még vár. ( STATUS="PAUSE") Jelentkezzünk be a telnet segítségével:
A bejelentkezés után a webfelületen a RESUME gombbal indítjuk el az ini-ben megállított feldolgozást.
61
Nézzük, mi történik:
Látható, hogy a „távoli kliensen” (jobb oldal) is megjelentek az üzenetek. Mivel ezeket az üzeneteket az adott helyzetnek megfelelően tudjuk változtatni, így viszonylag egyszerűen állíthatunk össze más szöveges protokolloknak megfelelő formátumot is. (Pl. XML , HTML,CSV, JSON vagy bármi egyedi szöveges formátumot.) Az üzenetekben használhatjuk a (MASSALYZER) rendszerváltozókat és a saját változóinkat is. A kliens oldalon lehet például adat kollektor, megjelenítő kliens vagy bármilyen más program (interfész). Láttuk, hogy lehetőség van a feldolgozás során nyert információt real-time, azonnal továbbítani TCP/IP kapcsolaton keresztül tetszőleges felhasználásra.
MASSALYZER
Database Interface
Amennyiben további kérdése e-mail címen: [email protected]
Chart
vagy
észrevétele
Display
van,
kereshet
minket
az
alábbi
További információ: www.massalyzer.com www.facebook.com/MASSALYZER
62
Szekciók - összefoglaló táblázat Szekció [CHANNEL...]
Paraméter [CHANNEL NAME=”{channel name}”, COUNTER=”{counter name}”, START_POS=”{start clip pos.}”, END_POS=”{clip end position.}”, STR_PATTERN=”{string pattern}”, REGEXP=”{regular. exp.}”]
Érték / Péda [CHANNEL NAME="DB2 LOG ERROR", COUNTER="ERROR", START_POS="50", END_POS="63", STR_PATTERN="LEVEL: Error", REGEXP=""]
Megjegyzés Ez a szekvencia bevezető sora, fejléce. Kivágja az aktuális sorból a START_POS és az END_POS közötti részt és megpróbálja illeszteni rá a megadott STR_PATTERN-nt vagy a megadott REGEXP reguláris kifejezést. Ha mindkettőt megadtuk, akkor a fenti sorrendben mindkét illesztést megkísérli és csak abban az esetben fut le a szekvencia, ha mindkét illesztés igaz eredményt ad. Amennyiben igaz, a COUNTER-nél megadott számlálót automatikusan megnöveli. (Nem kötelező megadni. Ha szükség van rá, a [COUNTERS] szekciónál létre kell hozni a változót.) Ha nem adjuk meg sem az STR_PATTERN-t, sem a REGEXP-et – üresen hagyjuk az idézőjel közötti részt -, akkor minden beolvasott logsornál igaz értéket kap és így lefut a fejléc után definiált szekvencia. A szekvencia felépítését lásd a részletes leírásnál.
[CHECKPOINT...]
Mint a [CHANNEL...]-nél. Lsd. a [CHECKPOINT] részletes leírását. A fejlécben: NAME=”{channel name}”, COUNTER=”{counter name}”, TYPE=”{HARD/SOFT/LOGTIME/ REALTIME}”, VALUE=”{linenumbers/chgTime}”
A feldolgozás közben – megadott soronként – olyan műveleteket végezhetünk, ami nem kötődnek szorosan a feldolgozáshoz, de adott estben nagyon hasznosak. Pl. kiírhatjuk, hogy hol tartunk vagy épp [CHECKPOINT egy stringben gyűjtögetett NAME="CHECKPOINT MINUTES",COUNTER="EXCEPTION" információkat menthetünk ki fájlba. ,TYPE="LOGTIME",VALUE="SEC"] Olyan ellenőrzéseket is végezhetünk segítségével, amik túlságosan lassítanának, ha minden sornál megtennénk, de időnként meg kell tennünk. [CHECKPOINT NAME="CHECKPOINT ON 10000 LINES",COUNTER="EXCEPTION", TYPE="HARD",VALUE="10000"]
HARD és SOFT típus esetén a beolvasott sorok/bejegyzések számát kell megadni. LOGTIME és REALTIME esetén azt az időt (SEC, MINUTE, HOUR, DAY, MONTH, YEAR) aminek a változása esetén le kell futnia a szekvenciának.
[CTRL-C]
Mint a [CHANNEL...]-nél. Lsd. az [CTRL-C] részletes leírását.
[GLOBAL]
END_INFO
END_INFO="OFF" END_INFO="ON"
A kilépés előtt - a munka végeztével - a változó értékek összefoglaló kiírásának ki/be kapcsolása.
[GLOBAL]
END_LINE
END_LINE="2012.02.11 22:07:20"
Időszűrés: A vége időpont ameddig beleszámít az idő. A megadottal egyező időpont már NEM SZÁMÍT BELE! Csak max. az előző másodper keletkezett (jelölt) sorok!
A CTRL-C megnyomása vagy – daemon módú futás esetén – a „kill -2 ...” paranccsal való kilövés esetén lefutó szekvencia. Pl. az adatok mentésére is lehet felhasználni.
END_LINE ="12345678"
Amennyiben a fájl nagyobb, mint
63
Szekció
Paraméter
Érték / Péda
Megjegyzés amilyen tartományra kíváncsiak vagyunk, akkor ezzel lehet megadni, hogy pl. összesítéseket, csak bizonyos korláton belül vegye figyelembe. (Lásd még : START_LINE)
INPUT
"./Tests/db2diag.log"
A bemeneti fájl elérési útvonala és neve.
OUTPUT
"./Tests/db2diag_filtered.log"
A kimeneti fájl elérési útvonala és neve.
TIME_TYPE
"ANY"
- Tetszőlegesen állítható
"NONE"
- Nincs dátum (szöveg)
Az „ANY” használatával gyakorlatilag bármilyen időformátum beállítható. Ez ajánlott. (Lásd még TIME_FORM.) A NONE a szövegfeldolgozáshoz való, amikor a sorok nem tartalmaznak dátumot. Ilyenkor minden sor egyesével kerül feldolgozásra.
TIME_FORM
"NORMAL" - ("2006-09-21 16:00:00:123") "SHORT" - ("Sep 21 16:00:00")
(A MASSALYZER belső változói max. másodperces felbontással dolgoznak.)
"%Y-%m-%d-%H.%M.%S." pl. 2012-02-2111.33.09.
TYME_TYPE=”ANY” esetén meg kell adni a formátumot is.
"%Y-%m-%d %H:%M:%S" pl. 2012-02-21 11:33:09 "%m/%d/%Y %I:%M:%S %p" pl. 02/21/2012 11.33.09 AM
TIME_POS
"[","1"
TIME_FORM="[%m/%d/%y %H:%M:%S"
(pl. IBM WebSphere) A formátum beállításához szükséges jelöléseket külön táblázat tartalmazza.
Akkor használatos, amennyiben az idő pozíciója nem a sor elején van: 1 - Karakter minta - string. 2 – Előfordulása (amennyiben nem az első előfordulás az adott sorban.) A megadott mintára után keres az n.-ik előforduláskor (default = 1) Találat esetén a találat utáni részre próbálja illeszteni a megadott TIME_FORM-ot. Amennyiben nincs rá szükség, hagyjuk üresen. ("","")
START_LINE
START_LINE= "2006.10.28 20:30:00"
START_LINE=”12345678”
START_LINE=”EOF”
[GLOBAL]
STATUS
STATUS = ”RUNNING” STATUS = ”PAUSE”
Időszűrés: A lényeges időtartományt kezdetét adhatjuk meg "2006.10.28 20:30:00" formában. Megadhatjuk egy konkrét sor számát is. Ilyenkor innen indul a feldolgozás. A korábbi sorokat a feldolgozás „átugorja”. Ha fájl végéről akarunk indulni és csak az újonnan beérkező sorokat akarjuk feldolgozni, akkor „EOF” értéket (End Of File) adjuk meg. (Real-time feldolgozásnál lehet hasznos.) A webfelületen a programot megállíthatjuk, továbbindíthatjuk. Előfordulhat olyan eset, amikor nem akarjuk, hogy a program indításával elkezdődjön a feldolgozás is, hanem a webfelületről szeretnénk a megfelelő pillanatban indítani. Ebben az esetben a ”PAUSE”
64
Szekció
Paraméter
Érték / Péda
Megjegyzés beállításra van szükségünk, Az alap beállítás a ”RUNNING”. Ez a normál indítási folyamat.
START_INFO
START_INFO="OFF" START_INFO=”ON"
Induláskor a beolvasott beállítások ellenőrzése. (Bekapcsolás esetén („ON”) kiírja az standard outputra az indulási paramétereket.)
RUNNING
RUNNING="CONT" RUNNING="ONCE"
CONT – Daemon módú futás. Leválik az indító processzről. A log végéhez érve nem lép ki, hanem várja a további „beérkező” sorokat. Ezeket folyamatosan feldolgozza. Real-time feldolgozást végez. ONCE – Ez az „offline” működés, amikor csak egyetlen logot akarunk feldolgozni és a fájl végéhez érve véget ér a munka.
[CONVSTRINGS]
{stringnév}_S {stringnév}_D {stringnév}_R
Egyszerű példa:
Adott karaktereket konvertál egyik értékkészletből egy másikba.
Csak a számjegyeket akarjuk kiszűrni a szövegből:
..._S= Forrás string ..._D= Cél string ..._R= Helyettesítő karakter. (1db)
STR1_S="0123456789" STR1_D="0123456789" STR1_R=""
Például nem akarjuk, hogy a „don't” szöveg aposztrófja belezavarjon egy SHELL parancs szövegbe vagy az SQL query szövegünkbe és lezáró karakterként értelmezze – ezért lecseréljük egy másik fajtára. STR2_S="'" STR2_D="`" STR2_R="SELF"
Ha nincs a megadott karakter a készletben akkor ez a karakter kerül a helyére. Ha ez üres akkor teljesen kimarad az eredmény-stringből a fel nem ismert karakter. Ha "SELF" szöveget adunk meg helyettesítő karakter paramétereként, akkor a nem talált karaktereket meghagyja (különben kigyomlálná), így elég a kivételeket megadni, a helyben maradó karaktereket nem kell felsorolni sem a forrás-, sem a céloldalon. Az aláhúzásjel ("_") előtti rész használható azonosításra. Az így definiált konverziót a CHANNEL szekcióban az egyes sorok („Line_X=”) 3. paraméterében lehet felhasználni, végrehajtatni. Lásd: [CHANNEL] szekció. Nem nyomtatható karakterek is megadhatók: pl. [0A ] vagy [ 0A] formában. Azért, hogy a cél-stringben ne csússzon el, és átlátható maradjon, hogy melyik forrás karakterhez melyik célkarakterhez tartozik, megadhatjuk a nyomtatható célkaraktert ['a'] formában is.
65
Szekció
Paraméter
[COUNTERS]
Érték / Péda
Megjegyzés
Pl.:
Változónév=érték
ERROR=0
(Ékezet, speciális karakter, ékezet és space nélküli.)
vagy
Az egyenlőség jel után kezdeti értéket kell adni neki.
*ERROR=0
Amennyiben *-al is jelöljük, az annyit jelent, hogy szeretnénk hogy - futás közben – web felületen is megjelenjen az adott változó pillanatnyi értéke. A [CHANNEL...] szekció fejlécében COUNTER=”ERROR” formában hivatkozhatunk rá. Ez esetben az itt megadott minta illeszkedése esetén automatikusan növelődik. Ezen kívül az INC és SUB parancsokat is alkalmazhatjuk az értékének növelésére/csökkentésére.
[NETWORK]
HTML_TITLE
A http felületen megjelenő cím
Megkülönböztető jelzés, hogy az adott felület melyik szerverről, naplóról, és milyen szűrésről tartalmaz információt.
LISTENER_PORT
Portszám. Pl.:
Melyik porton figyeljen a beépített webszerver. (Vigyázzunk, ne ütközzön más alkalmazásokkal, vagy másik MASSALYZER példány portjával!)
LISTENER_PORT=”25000”
[LOGIN]
PRIORITY
”LOW” vagy ”HIGH”
LOW esetén csak akkor szolgálja ki a HTTP kéréseket, amennyiben épp nincs feldolgozandó logsor. HIGH esetén azonnal kiszolgálja a HTTP kéréseket.
AZONOSÍTÓ= ”PASSWORD_MD5-HASH”
TEST="5f4dcc3b5aa765d61d8327deb8 82cf99"
AZONOSÍTÓ=”PASSWORD_MD5HASH” formában kell megadni a kliensek adatait a TCP/IP kapcsolat fogadásához. A kapcsolatot a [NETWORK] szekcióban megadott portszámmal egyező porton fogadja. A kapcsolat felvétele után a „login TEST” parancsra megjelenő „Password:” felíratra helyesen válaszolva felépül a TCP kapcsolat. A belépés után a „SEND TEST=....” parancsok az egyenlőségjel után megadott üzenetet elküldik. Az üzenetekben változók használhatók. Azok nevei lecserélődnek pillanatnyi értékükre. Amíg nincs kapcsolat, addig a SEND nem küld üzenetet. Ha több ilyen névvel azonosított kliens is van, akkor mindegyik megkapja az üzenetet.
[MYSQL]
MYSQL_IP: A MySQL IP címe PORT: A MySQL szerver portja USER: Felhasználónév PASSWD: Jelszó MYDB: A hasznándó adatbázis CONNECT_DB: (Y/N) kapcsolódás
MYSQL_IP=172.16.208.128 PORT=3306 USER=Massalyzer PASSWD=MassaPassword8364 MYDB=for_tests CONNECT_DB="N"
MariaDB vagy MySQL adatbázishoz való kapcsolódás paraméterei.
66
Szekció [PLUGINS]
Paraméter PLUGIN_1 PLUGIN_2 . . PLUGIN_N
Érték / Péda
Megjegyzés
PLUNGIN_1="/opt/massalyzer/lib/tstpl Paraméterként a használni kívánt lib.g.so.1.0" et kell megadni. Akár többet is lehet.
Az osztott könyvtárakban levő függvényeket hívhatjuk meg a CALL kulcsszóval a [CHANNEL...] szekcióban tárolt szekvenciák utolsó paraméterében. (Lsd. [CHANNEL...].)
[POSTSEQ]
Mint a [CHANNEL...]-nél.
A feldolgozás végeztével lefutó – opcionális - szekvencia. Nem kötelező.
[PRESEQ]
Mint a [CHANNEL...]-nél.
A feldolgozás megkezdése előtt lefutó – opcionális - szekvencia. Nem kötelező.
[STRINGS]
{stringnév}=”kezdőérték”
Itt adhatjuk meg a használni kívánt szöveges (string) változókat. Minden bejegyzéshez tartozik egy 64KByte méretű memóriaterület. Ezt használhatjuk szöveges eredmények tárolására. Adott stringhez [CHANNEL] szekciónál (8. paraméter) férhetünk hozzá a következő utasításokkal: MOV - Értékadás (felülírás) (pl. MOV VALNEV=”Akarmi” CAT - Hozzáfűzés WRITE - Kiírás (fájlba) SHOW - Megjelenítés (stdout) Amennyiben a tárolt szöveg csak számjegyeket tartalmaz, használhatók a következő utasítások is: ADD - szám hozzáadása SUB - szám kivonása
67