A következő címkéjű bejegyzések mutatása: Bytecode. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: Bytecode. Összes bejegyzés megjelenítése

2010. február 5., péntek

Btrace bemelegítés

Egy Sun-os konferencián hallottam először a Dtrace nevű eszközről, mely egy dinamikus nyom-követő. Sajnos használható formában csak Solaris vagy OpenSolaris platformokra érhető el, és mivel eléggé kernel szintű integrációja van a rendszerrel nehézkes a portolása. Sokáig vártam egy Linux-os verzióra, de sajnos még a mai napig sincs használható állapotban (vagy csak én nem boldogultam vele).
A Dtrace működése röviden annyi, hogy van egy saját programozási nyelve a D, és ezen a nyelven kell megírnunk a kernelnek, hogy a vizsgált alkalmazás mely állapot-változásait figyelje. A dolog szépsége, hogy az alkalmzásunkba nem kell "hook" pontokat elhelyezni, tehát a működés megfigyelése teljes mértékben kívülről történik, menet közben megváltoztatható, és nem utolsó sorban, akár éles üzemben is bevethető. A programozó döntése, hogy mit figyel, a megfigyelt eseményekről mekkora mennyiségű információt irat ki a képernyőre, vagy akár egy log fájlba.
Bár a Dtrace platform-függő, létezik egy kifejezetten Java alkalmazásokra szánt Java-s átírat, amit Btrace-nek hívnak (a honlap nem tudom meddig lesz elérhető, mert a project a Kenai forrás-megosztó oldalon van elhelyezve, amit jól megvett az Oracle és jól be is szippantja "belső" használatra). A Btrace egyébként nyílt forrású project, és jelenleg az 1.1.1-es verziónál tart.
Használat:
  • Telepítése igen egyszerű, jóformán nincs, a bináris-t ki kell csomagolni a kívánt helyre.
  • Ezután első lépésként meg kell írnunk első Btrace scriptünket, mely annyit csinál, hogy az application.Main osztálynak figyeli a someMethod metódus hívását.
    package btrace;
    import static com.sun.btrace.BTraceUtils.*;
    import com.sun.btrace.annotations.*;
    @BTrace public class ClassTracer {
       @OnMethod(clazz = "application.Main", method = "someMethod")
       public static void methodcalled() {
           println("Method called");
       }
    }
    
  • Következő lépésként a vizsgálandó alkalmazást kell elindítani, egy apró külöbséggel, hogy a JVM-et meg kell kérni, hogy HotSpot módban induljon, ennek módja az alábbi: `java -client -jar sampleapp.jar`. A jar-ba fordított programocska:
    package application;
    public class Main {
       public static void main(String[] args) {
           for (int i = 0; i < 1000; i++) {
               someMethod();
               try { Thread.sleep(100);
               } catch (Exception ex) {}
           }
       }
       public static void someMethod() {}
    }
    
  • Miután fut az alkalmzásunk egy arra alkalmas eszköz segítségével meg kell tudnunk a futó programunk azonosítóját, PID-jét, Linuxon a top parancs segítségével jutunk sikerre, bár nem ez az egyetlen mód.
  • Majd a Btracet kell ráállítani a JVM-re, hogy dolgozza fel a kapott információkat a `btrace PID ClassTracer.java` paranccsal (ha elsőre Connection refused hiba-üzenettel leáll még 1x érdemes megpróbálni futtatni, van, hogy elsőre nem indul el).
  • Nincs más dolgunk, mint élvezni a konzolt elárasztó Method called kiírásokat.
A módszer legnagyobb előnye, hogy bytecode szinten tudjuk nyomon-követni alkalmazásunkat, azt látjuk, ami a virtuális gépben ténylegesen végrehajtódik.
Még néhány lehetőség (a teljesség igénye nélkül):
  • Van mód arra, hogy a clazz vagy method @Annotáció érték helyére reguláris kifejezést illesszünk, így nem csak egy osztályt vagy metódust, tudunk lekezeleni, hanem a mintára illeszkedő összeset.
  • Mivel a callback metódusokat mi hozzuk létre, paraméterként számtalan bemeneti változó közül választhatunk, melyeket @Annotációkkal jelölhetünk. Pár példa: @ProbeClassName String probeClass paraméterrel az osztályt, @ProbeMethodName String probeMethod paraméterrel a metódust kapjuk meg. @Return Class returnClass-al megkapjuk a metódus visszatérési értékét (ehhez az @OnMethodban fel kell venni egy location=@Location(Kind.RETURN) értéket), a AnyType[] args-el az átadott argumentumokat.
  • Egy Btrace scripten belül párhuzamosan több metódussal is követhetjük az állapotot, ennek köszönhetően a programozó fantáziájára van bízva, hogy pontosan mit is szeretne megfigyelni.
  • Lehetőség van időzített ismétlődő műveletek futtatására, így képet kaphatunk a processzor terheltségéről, vagy akár a memória használatról is, ekkor az @OnMethod helyett @OnTimer(long ms) @Annotációt kell használnunk.
  • Meglévő Dtrace scriptjeinkkel is összeköthetjük Btrace scriptjeinet, bár ennek nem sok értelmét látom, hisz ahol van Dtrace ott minek használnák a Btracet.
  • Létezik egy VisualVM plugin is a Btracehez, így a scripteket a VisualVm-en belül is szerkeszthetjük akár futás-időben is. Mindennapi használatra ezt javaslom egyébként, számtalan ponton könnyíti a munkát.
A felhasználói kézikönyv szerintem magáért beszél, továbbá a példa kódok bőbeszédűek, azokból is elsajátítható az eszköz használata.
Még egy fontos jó-tulajdonsága van a Btracenek, mégpedig az, hogy mivel POJO osztályokat kell létrehoznunk, és @Annotációkat használ a sajátságos működéshez, a jar-okat importálva bármely Java képes fejlesztő-eszközhöz van támogatás, ami valljuk be elég nagy könnyebbség a fejlesztőnek.
Zár-szóként remélem kedvet kapott a kedves Olvasó, hogy kipróbálja ezt a remek eszközt, és bár az írás eléggé bevezető jellegű mégis hasznos volt.