piątek, czerwca 17, 2011

Linux to jednak fajny jest ;-)

Jest sobie taki tool w JDK, który zowie się JSTACK.
Dzięki niemu można podpiąć się do wybranej maszyny wirtualnej i dostać stack trace'y wszystkich wątków w maszynie.
To się przydaje żeby zobaczyć np. co teraz się dzieje.

W Windows jest w miarę prosto bo wyniki JSTACKa lecą prosto na konsolę, wystarczy więc je przekierować do pliku (tutaj mała uwaga jak używacie tego na odległej maszynie przez remote desktop to trzeba uruchomić MSTSC używając mstsc /admin (albo na niektórych systemach /console) ;-) )
Ale w Linuksie gdy chcemy podglądnąć Tomcata nie jest tak łatwo, wyniki JSTACKa lecą do loga Tomcata, czyli do catalina.out.
Same logi potrafią być ciężkie i trudno je pobierać za każdym razem z serwera żeby je sobie dokładnie przejrzeć.
No to spróbowałem dziś czegoś takiego:

tail -f catalina.out > toster.txt &
jstack <pid>
fg
Po czym zrobiłem sobie CTRL-C.
I co mam w wyniku w pliku toster.txt? :-) Kawałek cataloina.out z moim stosem :-) [fakt, że jak Tomcat jest mocno obciążony to będzie tam też dużo innych logów, ale to zawsze prościej pobrać plik mający nawet 1MB (a wydruk stosu taki może być ;-)) niż 20MB].

Same wyniki JSTACKa wyglądają tak:

"Thread Group 1-68" prio=6 tid=0x393c6800 nid=0x1304 runnable [0x3dd4f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
- locked <0x1880b868> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown So
urce)
- locked <0x18443280> (a sun.net.www.protocol.http.HttpURLConnection)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(Unknown So
urce)
at java.net.URLConnection.getHeaderFieldInt(Unknown Source)
at java.net.URLConnection.getContentLength(Unknown Source)
at org.apache.jmeter.protocol.http.sampler.HTTPSampler.readResponse(HTTP
Sampler.java:204)
at org.apache.jmeter.protocol.http.sampler.HTTPSampler.sample(HTTPSample
r.java:470)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSa
mplerBase.java:863)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSa
mplerBase.java:849)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:300)
at java.lang.Thread.run(Unknown Source)

"D3D Screen Updater" daemon prio=8 tid=0x39407400 nid=0x98c in Object.wait() [0x
3999f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at sun.java2d.d3d.D3DScreenUpdateManager.run(Unknown Source)
- locked <0x0af4e198> (a java.lang.Object)
at java.lang.Thread.run(Unknown Source)

Pid procesu można dostać używając:

jps
z katalogu z JDK, w przypadku gdyby nie chwytało ja używam brzydkiej metody (i Linux zawsze na mnie krzyczy, że źle formatuje przełączniki do PS, ale moja wina, że ja miałem pierwsze doświadczenia z *niksami na HP-UX? ;-))

ps -aux | grep "java"
I któryś z wyników to zwykle nasza Java ;-)


Podobne postybeta
IE suxx ;-)
OpenOffice.org i inne produkty Open Source - ofiary kryzysu? ;-)
PROPFIND, czyli jak przechytrzyć HttpURLConnection
Zły dzień programisty
Wysyłamy pliki do Google Docs przy pomocy Go :-)