Pages

Wednesday, 12 December 2012

Shell Scripts မ်ား

Shell Scripts ေတြအေၾကာင္း ရွင္းရရင္ေတာ့ တပံုၾကီးပါ။ ကိုယ္တိုင္စာအုပ္ဖတ္ၾကည့္မွ ပဲေတာ္ေတာ္ မ်ားမ်ား အေၾကာင္းကို တီးမိေခါက္မိ ရိွနိုင္ပါ့မယ္။ အခုဒီမွာနမူနာၿပထားတာကေတာ့ Java Process တခုရဲ ့Performance ကို jstat , jmap , နဲ ့ jstack ဆိုတဲ့ Java command ၃ခုကို သံုးၿပီး Monitor လုပ္ရာမွ ရလာတဲ့ result ကို mail နဲ ့ၿပန္ ပို ့ေပးမွာပါ။ Java process ေတြရဲ ့PID ကို သိေအာင္လုပ္တဲ့ေနရာမွာ unix command (ဥပမာ ps -ef လိုမ်ိဳး) ကိုအသံုးမၿပဳဘဲ jps ဆိုတဲ့ Java command ကိုသံုးထားပါတယ္။


ဒီေနရာမွာ အဓိကေၿပာခ်င္တာက script ရဲ ့အလုပ္လုပ္ ပံုသာၿဖစ္ၿပီး Java အေၾကာင္း မဟုတ္ပါ။
က်ေနာ္ကိုယ္တိုင္လည္း Java ကြ်မ္းက်င္သူတေယာက္မဟုတ္ပါ။ ဒီ နမူနာေပးထားတဲ့ script ကေတာ့ က်ေနာ္ ကိုယ္တိုင္ေရးထားတာ ၿဖစ္လို ့ဘယ္သူမဆို အသံုးတည့္မည္ဆိုရင္ လိုအပ္သလို ၿပန္ၿပင္ၿပီးသံုးနိုင္ပါတယ္။

script နွစ္ခုကို ေရးထားၿပီး တခုကေန တခုကိုေခၚသံုးတဲ့ပံုစံပါ။ တစ္ကယ္ေတာ့ JVM တခုထဲကို လုပ္မယ္ဆိုရင္ ဒီတခုထဲနဲ ့တင္ရပါတယ္။ JVM ၂ ခု ဒါမွမဟုတ္ ၂ ခုထက္ပိုခဲ့မယ္ဆိုရင္ အခုၿပထားတဲ့ example ထဲကလိုသံုးမွ အဆင္ေၿပနိူင္မွာပါ။ အခုၿပထားတဲ့ ဥပမာမွာ jvmlog.sh နဲ ့vm.sh တို ့ကို folder တခုေအာက္မွာထားၿပီး jvmlog.sh ကို execute လုပ္လိုက္တာနဲ ့vm.sh ကို ေခၚသံုးသြားမွာပါ။

ေအာက္က script ကို jvmlog.sh ဆိုၿပီး နာမည္ေပးထားပါတယ္။

 #!/bin/sh  
 JDK_32=/usr/jdk/instances/jdk1.6.0/bin  
 echo "Logging JVM for Jgroup ..."  
 /opt/jvmlog/vm.sh `${JDK_32}/jps | grep -v Jps | awk {'if($2=="GossipRouter") print $1, $2 '}`  


#!/bin/sh ဆိုတာ shell နဲ ့run မည့္ဖိုင္ဆိုၿပီး ညြန္းထားတာၿဖစ္ပါတယ္။

JDK_32=/usr/jdk/instances/jdk1.6.0/bin ဆိုတာ JDK Path ကို ေၾကၿငာထားတဲ့ variable ၿဖစ္ပါတယ္။

echo ဆိုတာကေတာ့ shell ရဲ ့print ထုတ္တဲ့ command ၿဖစ္ၿပီး ေနာက္က " " ထဲမွာရိွတဲ့စာသားကို print ထုတ္ေပးမွာၿဖစ္ပါတယ္။

/opt/jvmlog/vm.sh ဆိုတဲ့ script ကိုသြား run ေပးမွာပါ။ ေနာက္က `` ထဲက value က output ၂ခု ထုတ္ေပးမွာၿဖစ္ၿပီး အဲဒီ output ကို vm.sh ဆိုတဲ့ script ထဲမွာ အသံုးၿပဳမွာပါ။

${JDK_32}/jps commandကို run လိုက္ရင္ ရိွသမွ် Java process ေတြရဲ ့PID နဲ ့class name ေတြ ထြက္လာမွာပါ။

grep -v Jps ဆိုတာက အခု run လိုက္တဲ့ jps ရဲ ့process ကို output ထဲကေန remove လုပ္လိုက္တာပါ။

awk {'if($2=="GossipRouter") print $1, $2 '} ကေတာ့ GossipRouter ဆိုတဲ့ Class name ရိွတဲ့ process ရဲ ့PID နဲ ့class name ကို output ၂ ခုအေနနဲ ့ထုတ္တာပါ။ ဒီေနရာမွာ awk ကိုမသံုးဘဲ တၿခား shell command  ေတြ (ဥပမာ cut , sed လိုမ်ိဳး) ေတြကိုသံုးလည္းရပါတယ္။



ေအာက္က script ကို vm.sh ဆိုၿပီး နာမည္ေပးထားပါတယ္။  

 #!/bin/sh  
 SERVER=10.65.0.84  
 JDK_32="/usr/jdk/instances/jdk1.6.0/bin"  
 ROOTDIR="/opt/jvmlog"  
 DATE=`date "+%Y-%m-%d-%H:%M"`  
 RECP="myname@mydomain.com"  
 SNDR="myname@mydomain.com"  
 mkdir -p $ROOTDIR/logs/$2  
 LOGDIR=$ROOTDIR/logs/$2  
 JMAPEND=$LOGDIR/"jmap_"$DATE".log"  
 JSTACKEND=$LOGDIR/"jstack_"$DATE".log"  
 JSTATEND=$LOGDIR/"jstate_"$DATE".log"  
 WORKFILE=/tmp/fxspacelog.txt  
 ${JDK_32}/jmap -histo:live $1 > $JMAPEND  
 echo "Jmap Log for $2 $DATE on ${SERVER}" > ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JMAPEND >> ${WORKFILE}  
 sleep 2  
 ${JDK_32}/jstack -l $1 > $JSTACKEND  
 echo >> ${WORKFILE}  
 echo "Jstack Log for $2 $DATE on ${SERVER}" >> ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JSTACKEND >> ${WORKFILE}  
 sleep 2  
 ${JDK_32}/jstat -gcutil -t -h20 $1 1000 20 >> $JSTATEND  
 echo >> ${WORKFILE}  
 echo "Jstat Log for $2 $DATE on ${SERVER}" >> ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JSTATEND >> ${WORKFILE}  
 mailx -r ${SNDR} -s "Java Log for $2 $DATE on ${SERVER}" ${RECP} < ${WORKFILE}  


#!/bin/sh ဆိုတာ shell နဲ ့run မည့္ဖိုင္ဆိုၿပီး ညြန္းထားတာၿဖစ္ပါတယ္။
SERVER ကေနၿပီး WORKFILE ဆိုတဲ့အထိက variables မ်ားေၾကၿငာထားတာၿဖစ္ပါတယ္။ 
ဒီ script ကို run ရင္ေနာက္ကေန input နွစ္ခုထည့္ေပးရမွာၿဖစ္ပါတယ္။ ပထမ input ($1) ကေတာ့ JVM ရဲ ့PID ၿဖစ္ၿပီး။ ဒုတိယ input ($2) ကေတာ့ သူ ့ရဲ ့class name ၿဖစ္ပါတယ္။

${JDK_32}/jmap -histo:live $1 > $JMAPEND
${JDK_32}/jmap ဆိုတာက jmap command ကိုေခၚတာၿဖစ္ၿပီး၊ -histo:live ဆိုတာကသူ ့ရဲ ့switch ပါ။ $1 ကေတာ့ PID number ၿဖစ္ၿပီး၊ > sign ကေတာ့ output ကို $JMAPEND ဆိုတဲ့ဖို္င္ထဲကို redirect လုပ္သြားဖို ့ပါ။

echo "Jmap Log for $2 $DATE on ${SERVER}" > ${WORKFILE}
သက္ဆိုင္ရာ variable ေတြရဲ ့value နဲ ့ စာေၾကာင္း ကို ${WORKFILE} ထဲကို write ပါလိမ့္မယ္။

echo >> ${WORKFILE}
blank လိုင္း တခုကို print ထုတ္ၿပီး ${WORKFILE} ထဲကို append လုပ္လိုက္တာပါ။

cat $JMAPEND >> ${WORKFILE}
$JMAPEND ထဲက log ေတြကို ${WORKFILE} ထဲကို append လုပ္လိုက္တာပါ။

sleep 2
၂ စကၠန္ ့ေလာက္ ခဏနားေနတာပါ။

ၿပီးရင္ jstat နဲ ့jmap လည္းသူတို ့သက္ဆိုင္ရာ command ေတြ switch ေတြသံုးၿပီး အလုပ္လုပ္ပါလိမ့္မယ္။ အားလံုးၿပီးသြားရင္ရိွသမွ် log ေတြက ${WORKFILE} ထဲမွာ ေရးထားၿပီးသားၿဖစ္ေနပါလိမ့္မယ္။

mailx ကေတာ့ e-mail ပို ့တဲ့ shell command ၿဖစ္ပါတယ္။ သက္ဆိုင္ရာ variable ေတြရဲ ့value ေတြကိုသံုးၿပီး ပို ့သြားမွာၿဖစ္ပါတယ္။ Message Body အေနနဲ ့ ${WORKFILE} ကိုအသံုးၿပဳမွာၿဖစ္ပါတယ္။


No comments:

Post a Comment