From c4a3e9b71723e83b61a92a82a4cb4dfa87f8d7f7 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 18 Dec 2016 21:26:37 +0100 Subject: [PATCH] p/jmx: extract the source from the jar --- plugins/java/jmx/plugin/.classpath | 6 + plugins/java/jmx/plugin/.gitignore | 3 + plugins/java/jmx/plugin/.project | 17 ++ plugins/java/jmx/plugin/META-INF/MANIFEST.MF | 3 + plugins/java/jmx/plugin/jmxquery.jar | Bin 8977 -> 0 bytes .../plugin/src/org/munin/Configuration.java | 148 ++++++++++++ .../jmx/plugin/src/org/munin/JMXQuery.java | 228 ++++++++++++++++++ 7 files changed, 405 insertions(+) create mode 100644 plugins/java/jmx/plugin/.classpath create mode 100644 plugins/java/jmx/plugin/.gitignore create mode 100644 plugins/java/jmx/plugin/.project create mode 100644 plugins/java/jmx/plugin/META-INF/MANIFEST.MF delete mode 100644 plugins/java/jmx/plugin/jmxquery.jar create mode 100644 plugins/java/jmx/plugin/src/org/munin/Configuration.java create mode 100644 plugins/java/jmx/plugin/src/org/munin/JMXQuery.java diff --git a/plugins/java/jmx/plugin/.classpath b/plugins/java/jmx/plugin/.classpath new file mode 100644 index 00000000..fb501163 --- /dev/null +++ b/plugins/java/jmx/plugin/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/plugins/java/jmx/plugin/.gitignore b/plugins/java/jmx/plugin/.gitignore new file mode 100644 index 00000000..f00d6296 --- /dev/null +++ b/plugins/java/jmx/plugin/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/.settings/ +*.class diff --git a/plugins/java/jmx/plugin/.project b/plugins/java/jmx/plugin/.project new file mode 100644 index 00000000..8fe5521c --- /dev/null +++ b/plugins/java/jmx/plugin/.project @@ -0,0 +1,17 @@ + + + plugin + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/java/jmx/plugin/META-INF/MANIFEST.MF b/plugins/java/jmx/plugin/META-INF/MANIFEST.MF new file mode 100644 index 00000000..bd17a1b5 --- /dev/null +++ b/plugins/java/jmx/plugin/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Ant-Version: Apache Ant 1.8.1 +Created-By: 1.6.0_22-b04-307-10M3261 (Apple Inc.) diff --git a/plugins/java/jmx/plugin/jmxquery.jar b/plugins/java/jmx/plugin/jmxquery.jar deleted file mode 100644 index 5c37d4bdec25e453d0891a5d12d899f30cecd157..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8977 zcma)i1yCJZw)Vj-xO;#A!QI^};F@50xpU{v z+d;JTlEb(4JRz^dURay30d3;Psk%e^zU6F-xa(t>z zo&6iv*1pTQ6pk~qywaq+79a|SmgVM^cS}~ZIb+CRJAuqov#|hcOMSsWiM%>=cfXNmO85LGt9PiO^D>yn+dCmT9 zW5fB%eV^#9LD%-sT^8!l?A)D(*p13D6!h4ZDKCjkw#|M&xt89-)s@~dX8h~riZoEp zSttUonW$Gnsd$}MCR=0ATLy@nOB+gfnHZMJLqrwIj@=E>FTzXLmJY+}j|p4GYBZ$_ z^a7;9*`Rg5niP6q)G07| zygKQf;t&rltxwJe#iCVCPU3+^dpsG9NLusw@pnyKc$KFUEc;FsEHe|yud|W}2wgsI z1njCKu4ztIh+E3G!iHxoZt7ChjWRLzmwL}DoqSbWOl#$|fm{=P@*ya+(5KCuxo8dh z&KyrO#}Mv$GQMeAh|}kGI9tMh&&Mq3c z@lIh_)l!`0JBZn{{t#dDNK-hlQ>%3o`h$Xxd(A9UWXqy@7~yf(OtO7GH*UB^v z4$w`AKm&TVula1GxUc$rKN}Cd_Q*%Ul-M$L!RPN6!{}%_MBA$P@Uvmvz>}uuwzE_A z#R=P3@g;$}la)-n3hf?dG;YgzmVOw#uSdI>q5H%tZBL9}v(Q%jG{WVR=vL-QW*Hc} zM%k_Aax0vVlHKckJ_p?Wq$!a~@5Fh|-=pPJ5%v6PGrsKXDZ6^aHUALr$^kx`)y`1M z)~~qylIw`s{Dh4sE|uqu(bv_oV!zqshR4Azg!Nkzo5+_Dq^dzc`Ln2dm{NuryL)`I&G~>!jp5 z^@iAm8@31q-HhQz8M$-#l{RLP(9x~WZvEn(zMq{^G$5dbJNsrlkXxY1kJJU9qy2yf;yxw{Q^qm$Jy69L&F+sRl2Y%~d1&y?o*5t+5V^$@3Q2r!?E*%jx)fH`NBq)JtUt z#E?NmkD1=6Ss$xqNtoy4@rmw_5G2v1n}q`HLbK1YE6s)}pD6$81%ICL9MV*dbw~if zCrki<{Qo}V|2)%^b4?9C#mAPW|{ zVU~%O9zsHj5%Z0_6%`$NWgRjVO^h3vHg)nd-+b*lv@4p7w~VVXc{{DG^gK*2Yo_2f zv(EhvAF{8(>Hhn%gsgB!17bAIh;dPV@S^-Yy73@ocTBs(U8)lf^NwHjdob_R)Uv2$TVNI`MG4>_{ zNd-FRqq4yyZA6Sh$>+S0m+Y?}Jp2$v%|TF>|3pbE?`rQ@ivd zyLpjM;Z+Lg_GC;K*NV~cdt7?WicbG(S7xD9r7=q5_*rhctJgwTaKrZry$wtK!a9SX zuKerb;O@@xW~!0&l!RfGSmHZue`e+PeI|4zMe)at43E@YTS^(PO5IuF>nX>NJ>v3e z;^wj3UNA*y=|y!)-bT$2w*L&4k6Qnosh5@y>cZcfW9XQ1)cd#d=hDSD4=-NS{ZkgH`dOJLGBi?{p>vXjM-w^kA~Mrp}}H8aIv zSxtszL(ek8X*g}6nZwm7*tM93wK30+LGY5+N|{wGg~@Df4Le>3y`?elV#CkFZEkd( z*}R+@3Dblx987LE`EuMhpOftEVubIiMOJRbpsORGXro4XSbgXEieX8cW!zRfL$EY| zYbrARR4cbC`~4EQt}jp1nB#D`6n;J#C9`0`wi1htwCxy@tw_Wbw@Ns)KfmL^C{*!9 zKEk^V9~HV>ZW>$VC8g7oy90Y)bt`LZAgUBEck7m2LE^!g?AdgM&|_Fzt7y=ik@IEo zqHcbQO)}0xT{OLW%Q{~1d`E1^0rU}0(okS&WLa@i!Isg_;d@5NYy)8Pi0mm9>oxHk z;#T-%i!_S~T4~l+-aF?H2Z!uVL@@Ry@XAZlliFvSDwPL%{Q<8o^g>9T1NC=4B3Vjm=(Zr1$sr)KWI06oI2rB}C67R0egKX%Ezvqi#g-?H+&fEDM zg~?1^x^wY;>4a33gKQ8xI~=qhQZFj$-3b;p`~u%mEbMPDC#6vxnDW)(qvQG{tbUF} zoCWnk{D_AJjLt1WYj*ewN!pNsAAkHLLVc`91L8q-3)>O69`W!}TTHe&8o6WOaJF)C zUbM4w_&08Y)=#`h4@K)IA|ZlrRfln@jKHjzYA6 z522*{lR8(p;Q_hj1Szwi)*g?6CeWf9MwCU3)#STyBLmTK_K?S?uC7YjnXg#ull^fB zZZ(;n{RcA@xqv1|PnX5rGgL1*nDeZTt6Dr8iVjQJjFgyqTC)?V=LGQQq6-Xf8;c7c z+lqjFk4Ve~kaycZ<~$%}M}qHRecTd_Z3n*RCO;*0!(znm3rg$sgI-vfuJ|@b5>7n< zn&5yi!ZbQEbDs96TfqkcwOyP{uN2b+|1y)9^3cl!Ms}aNL*AEF*5tmn_0gYRO$)pF zqaIf}4vd=D#{b#vQ`)T7NpJuFLRtWT=s&vsJ7rxpcS{%Ve>QquG(XMx^k1FhyYK1v zuwdcCQbWv;lTak^7^S>IFQVvRP%z=B4e9tsx-G2I^_tC-(ugf^}k zHIPI^9N8AMR?I)>uCAP}cvP%9w5@x1uGZ?_{Q~=1b1H;!KTAxC#Q*O4zAsar2L)nc zKe@44_QE^rGXwStkUNZGHsT9@5`qHqX1aVvlpTGK$YTTaCB^b{eBW+=eI|L%OnnD6 zVtWqWz@7cb_SJZ{3UW_5`=qb?BAfB+X4Vnf_3p^?<`L(?@qrTbqLVM?1tNJ?%MeSR z7I+YYf>RItmv5|NS@F0y>|i#HD zZ0W*_eRd-4?{{yN9#R%~GWCx$7f)I}lu0$b=YaV`#jzwclPe2uoH*YNM>SWl;tOVF znLFkqtdvfcbvIX9KlByOFHkI|EIhc|rIDpud>KhnNFPa?K^Ii%l`p{PPdZf^*!E(! z3Y)upqfsE3-_*DoK@7HPB34|an>h1YDeox!`4GlTK6$&6NqtGAF+XfHQKm$*U`yva zZXp$i^SHLOhz+&4;u%N+H>{`YzR_OIJ>XQJQPd=il$jk%r_+i3=Dnd!XD!uE{w~Hb zs((C1>7IhCWqApgXF&F{8hhRL4Gm`_Js4Uk9|cn1h@3uXjY$`d=u5%lH)rOe4!1IZ zL99%4jwJpb`DT}cBPgPX*K#(&=0jZq*1(;|y#uz&IQhh+S)=^YT5So60b`i08+*dM z?TqS~d;Vy<=@c-c#jQnJ$!-PtybohQZdaDyRoQV#DdN(U&YC;%otrg!T{-XI*nH%1~A`D?2Tvx`=k5hQb{mD;g^i@Y6jk21I-%7WhD`m9~n;y znS|QWlR7&JGBGc^Vl(ju=Mu6s04m6ulP^jzi}OE_=q58WQR*F@k-;9WjHEoyN2Z9| z!gOFF2ul!2=T4gp z8@b5qFgyjOt|M&RVDq9?`*ITc;NX`>*DQcAcZn^G1kk%^Eu*2v+Ey5p1OAzloeR<4t(J zu)HNA59KgRoiue=3`!*@@jPA|zy{yDgik(BPZL5VAaXEd^Zcc*e0@k7VPzeRxRH&D zuVakur1M_f)*MZ+>XUujAi-kSFbB)hXQr7L=xk3CX}((BT*Lys5LYb^ zJ>6Wn-9*TX{3zv^bbi3z7qN1$^wSrQi(n;@yii`_bvh!7Eg*PunoE#!FO&Nvcam}k zlSTr&>Ds+B-BAJ(n>Zo(F?2fvU667o-qtU3k`mXPVrMmBUU0ML_lGkgyLJ<0292kF ze{$ZSx%-7W$Iq1>x)pKDJ^p>jMgC9)*$6nSw_JG%7W|laKKs)_H1AsEsl@ci3NB(W zhrsk~{-@|m%wP_FINAJ9S0{L}YFdPrr%Q~F)WqjXB5sW%N*Mvs^nRcp&KZ>XxmU%@c5d`}R>L{9>J0GMQX^;b#f^;~j^!ficDIX; zHtS?7&8Bk)`sL=MZ53lNKWS>Re~3!=1rb59pxs~7=?KsxgyrnG! z=oF-XSHKDu$1f%x;KsuB{mHx2_>k>Ft-tz%{k(>(wuq%Zm~xBl`02G65EWw@Y$CQ*Tg(rG(*&0MzYuuVL%^kW3l@3%ZZbIE_ zI?(Rf#BxLRHO3X>ttu+Ptjg5Nl8@pS%p|h=(`o%96UGl7eQwPIS7>9g{8X{7O8Ev+ zAex|6imKWS$@3Fz4UgCwH=<{mv0Vutyu1ZXimd%eSZjIHolZKV`YEg|a6+j^@=`T-4cpeKn1qStB!V6sT!A7LyzGzYrlfb4HvHT6ABs3~Ogb@l20}`I>7qx&Z#f*hVGg~c*>Wrpjt2u`#EHw`0 z{Eqtgv^*kwHI%`1Z*#C8-WX}q4yKCIyvow%^Bv)o$nAilivQ(OUlX41C8M-2t}N3? zBtErDZpKge%lxRT5StF$0BlfwnrJBSlZ+f?VP>QzTjd^>L(|e)Uas?w5Q9^26zsgp zXBsTO;H;nw`eB~omS97hD#U%9BhozQ`Y&|qU_n}w(pn!dY5W@=aW4 z);4BAm8+tN*A^n;hJMqc4LWYxYv5rC*1?>S`wAje{iyAi7N;}Bv|oZT2Fa?e z4f6!Y)q=S;SyJTtGMf;UStB>TIKg1JYv5;qO@{e4IHiaSjut$@n60RdCSNAg~DMLrI8g9g7yhTq}0j2$;YXPOlMczEm zct>p)v2xCZl(N82p*7qk(#Y5!22O74u?7t!glbyJ2R9}7wl*DN`sx)yp7^kiR5)7{ z4|pDY(@GEA>(SYi?_1;JB+JyD9>^dBO!bF)rn~}E8YQwhT>v_a*fTkud^Rk*n{I&& zZw!Ozy&`lW%$LBBH-nh)IR(e&Zblcxr5FNsle6U-c=ltq$Y92@OC)ra=_jsuwTcev zq@u%Bo{d_LymTvSI94SA#5-t4<-?(4|@h$1JP>z-q| ztBa|Yi2s8sMWsnK~4(LCv!ocJBPFJtIR6onWeN%L{oWj*RC<6 zLoDl82*}EW6W0SYuc3Fpf@2i|qwWx6C zx31`GZ0MJ@-1EyR?2(Pg5Sw|Ru9?%RLos;snSS~*dk^UvV05YqtqUy?uvtCa&jrhT zCHPuOoLe9>8t|-1=_PN^4T$Nec^eptAB(83!D35 zFl^gFN>vgIzm0!(l`Usli~)$x4z|oeM1CQgzDLVV{Bca@q^mp!b%feooMLAv8W(kiRAEwg(Uys9O-pa) zb`2fR@hj9C_krSP#HMME1s?=Oq7u;P#gsN7L)(w^Yi+>$TA_31HF~q*70Zz`;-;W^GXhxLlA{e#+ zev%9LP%$tD_E~Q+qq)6c(?kvy9@p*d$d%?4m=zm7zrt7Sx+GE-P*~(fN)TB@B!B*f zC!Nhbras0|3eZD)$$_B5)hAH>a*sFhzNBf%(nFp==5>b^S&ukT*R3MEyM__4p0y6- z&iT|XSAxjfimI(IcYj#fl74Ys_fAwkbu5|gQ(p>rZO<)L={jhqWlhGT!9T&f;?VX?BcHc3(Yl?QFXsGu?iY28rRsahO>oeVj+q&DKGf8{|i=&K^pvtV3!vO(? zfWV#$bK{lGgLA7uAUxydtcpSW_KIBB_`1q!#-mNDezT|}j6`QeLHt7LC*B5jswOO# zJ2lk`d&AnsUE_k#0!gVEQFm%;$R07}e3ZH*Il8tXenUW}Z8exjls-?_WE-AX6z_e3sIs%L zgs%lFv$8LxKiA%f`3bZL!*mU_KHtK0T)C}z{G*aelam|^+kWzc`Hr7u@ls*cEAQ*0 z4g{$GfHj58LYKlhfZpnw8sn0a(;LypG$#JS-|rhmj;uu}2hAqelW@+!6X@psA?KFS z7TmUn>lWe#pld9UD=Cl-U;Il+_ZO&mf?jvRa>N`!)q(>H0z*^_bL0%i{uPaXCS+U? z{;4%QTl&@s75nL}Ke50Qi^Zj90!-~%F?Z1@R~ zPxO?@i}(2NWTVr5(LQt)<`nz2l4@;}S>%0!oLkl4SdYtMnnvQnem)1@#O)sd>wSU4 zKNuIZkWN@)wP?QY0#vbdv-gIM+&!4sPW zsZd|>@V;YbHRo))O9T=&b{~?0MW&WtF*i9p^M|CKafYo$%@(*9Tu#|ffm3v`KpqYy zz0GrDz*{f56C|ooe`VBG9k%Cu#zSBcpS^`q<)Ao&_pB0GoTS(%h}f7fb&D(VVHg|c zTf9eWpRofiyZj8r(tSCX@-^G5bzyebeITNk>M15nwac50lN$p7>n|}?MHpB-xc^%z z@q4KB+pqwq5`WzPC5HG@H}MzszbhyHApBvFAg15@zo>uHQT#plAKHt5!2h}ZA$9oE z{s`Xw`|(fV!(TD~yY%7TjE#RX{t`m`#ryA4h(CFM fieldMap = new HashMap(); + private List fields = new ArrayList(); + + public class FieldProperties extends Properties { + private static final long serialVersionUID = 1L; + private ObjectName jmxObjectName; + private String jmxAttributeName; + private String jmxAttributeKey; + private String fieldname; + private static final String JMXOBJECT = "jmxObjectName"; + private static final String JMXATTRIBUTE = "jmxAttributeName"; + private static final String JMXATTRIBUTEKEY = "jmxAttributeKey"; + + public FieldProperties(Configuration paramConfiguration, + String fieldname) { + this.fieldname = fieldname; + } + + public String getJmxAttributeKey() { + return jmxAttributeKey; + } + + public String getJmxAttributeName() { + return jmxAttributeName; + } + + public ObjectName getJmxObjectName() { + return jmxObjectName; + } + + public String toString() { + return fieldname; + } + + public void set(String key, String value) + throws MalformedObjectNameException, NullPointerException { + if ("jmxObjectName".equals(key)) { + if (jmxObjectName != null) + throw new IllegalStateException( + "jmxObjectName already set for " + this); + jmxObjectName = new ObjectName(value); + } else if ("jmxAttributeName".equals(key)) { + if (jmxAttributeName != null) + throw new IllegalStateException( + "jmxAttributeName already set for " + this); + jmxAttributeName = value; + } else if ("jmxAttributeKey".equals(key)) { + if (jmxAttributeKey != null) + throw new IllegalStateException( + "jmxAttributeKey already set for " + this); + jmxAttributeKey = value; + } else { + put(key, value); + } + } + + public void report(PrintStream out) { + for (Iterator it = entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + out.println(fieldname + '.' + entry.getKey() + " " + + entry.getValue()); + } + } + + public String getFieldname() { + return fieldname; + } + } + + public static Configuration parse(String config_file) throws IOException, + MalformedObjectNameException, NullPointerException { + BufferedReader reader = new BufferedReader(new FileReader(config_file)); + Configuration configuration = new Configuration(); + try { + for (;;) { + String s = reader.readLine(); + if (s == null) + break; + if ((!s.startsWith("%")) && (s.length() > 5) + && (!s.startsWith(" "))) { + configuration.parseString(s); + } + } + } finally { + reader.close(); + } + + return configuration; + } + + private void parseString(String s) throws MalformedObjectNameException, + NullPointerException { + String[] nameval = s.split(" ", 2); + if (nameval[0].indexOf('.') > 0) { + String name = nameval[0]; + String fieldname = name.substring(0, name.lastIndexOf('.')); + if (!fieldMap.containsKey(fieldname)) { + Configuration.FieldProperties field = new Configuration.FieldProperties( + this, fieldname); + fieldMap.put(fieldname, field); + fields.add(field); + } + Configuration.FieldProperties field = (Configuration.FieldProperties) fieldMap + .get(fieldname); + String key = name.substring(name.lastIndexOf('.') + 1); + field.set(key, nameval[1]); + } else { + graph_properties.put(nameval[0], nameval[1]); + } + } + + public Properties getGraphProperties() { + return graph_properties; + } + + public void report(PrintStream out) { + for (Iterator it = graph_properties.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + out.println(entry.getKey() + " " + entry.getValue()); + } + + for (Configuration.FieldProperties field : fields) { + field.report(out); + } + } + + public List getFields() { + return fields; + } +} diff --git a/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java b/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java new file mode 100644 index 00000000..0ac91905 --- /dev/null +++ b/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java @@ -0,0 +1,228 @@ +package org.munin; + +import java.io.IOException; +import java.text.NumberFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +public class JMXQuery { + private static final String USERNAME_KEY = "username"; + private static final String PASSWORD_KEY = "password"; + public static final String USAGE = "Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL"; + private String url; + private String username; + private String password; + private JMXConnector connector; + private MBeanServerConnection connection; + private Configuration config; + + public JMXQuery(String url) { + this(url, null, null); + } + + public JMXQuery(String url, String username, String password) { + this.url = url; + this.username = username; + this.password = password; + } + + private void connect() throws IOException { + Map environment = null; + if ((username != null) && (password != null)) { + environment = new HashMap(); + + environment.put("jmx.remote.credentials", new String[] { username, + password }); + environment.put("username", username); + environment.put("password", password); + } + + JMXServiceURL jmxUrl = new JMXServiceURL(url); + connector = JMXConnectorFactory.connect(jmxUrl, environment); + connection = connector.getMBeanServerConnection(); + } + + private void list() throws IOException, InstanceNotFoundException, + IntrospectionException, ReflectionException { + if (config == null) { + listAll(); + } else { + listConfig(); + } + } + + private void listConfig() { + for (Configuration.FieldProperties field : config.getFields()) { + try { + Object value = connection.getAttribute( + field.getJmxObjectName(), field.getJmxAttributeName()); + output(field.getFieldname(), value, field.getJmxAttributeKey()); + } catch (Exception e) { + System.err.println("Fail to output " + field); + e.printStackTrace(); + } + } + } + + private void output(String name, Object attr, String key) { + if ((attr instanceof CompositeDataSupport)) { + CompositeDataSupport cds = (CompositeDataSupport) attr; + if (key == null) { + throw new IllegalArgumentException( + "Key is null for composed data " + name); + } + System.out.println(name + ".value " + format(cds.get(key))); + } else { + System.out.println(name + ".value " + format(attr)); + } + } + + private void output(String name, Object attr) { + CompositeDataSupport cds; + Iterator it; + if ((attr instanceof CompositeDataSupport)) { + cds = (CompositeDataSupport) attr; + for (it = cds.getCompositeType().keySet().iterator(); it.hasNext();) { + String key = it.next().toString(); + System.out.println(name + "." + key + ".value " + + format(cds.get(key))); + } + } else { + System.out.println(name + ".value " + format(attr)); + } + } + + private void listAll() throws IOException, InstanceNotFoundException, + IntrospectionException, ReflectionException { + Set mbeans = connection.queryNames(null, null); + for (ObjectName name : mbeans) { + MBeanInfo info = connection.getMBeanInfo(name); + MBeanAttributeInfo[] attrs = info.getAttributes(); + String[] attrNames = new String[attrs.length]; + for (int i = 0; i < attrs.length; i++) { + attrNames[i] = attrs[i].getName(); + } + try { + AttributeList attributes = connection.getAttributes(name, + attrNames); + for (Attribute attribute : attributes.asList()) { + output(name.getCanonicalName() + "%" + attribute.getName(), + attribute.getValue()); + } + } catch (Exception e) { + System.err.println("error getting " + name + ":" + + e.getMessage()); + } + } + } + + private String format(Object value) { + if (value == null) + return null; + if ((value instanceof String)) + return (String) value; + if ((value instanceof Number)) { + NumberFormat f = NumberFormat.getInstance(); + f.setMaximumFractionDigits(2); + f.setGroupingUsed(false); + return f.format(value); + } + if ((value instanceof Object[])) { + return Integer.toString(Arrays.asList((Object[]) value).size()); + } + return value.toString(); + } + + private void disconnect() throws IOException { + connector.close(); + } + + public static void main(String[] args) { + int arglen = args.length; + if (arglen < 1) { + System.err + .println("Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL"); + System.exit(1); + } + + String url = null; + String user = null; + String pass = null; + String config_file = null; + boolean toconfig = false; + for (int i = 0; i < arglen; i++) { + if (args[i].startsWith("--url=")) { + url = args[i].substring(6); + } else if (args[i].startsWith("--user=")) { + user = args[i].substring(7); + } else if (args[i].startsWith("--pass=")) { + pass = args[i].substring(7); + } else if (args[i].startsWith("--conf=")) { + config_file = args[i].substring(7); + } else if (args[i].equals("config")) { + toconfig = true; + } + } + + if ((url == null) || ((user != null) && (pass == null)) + || ((user == null) && (pass != null)) + || ((config_file == null) && (toconfig))) { + System.err + .println("Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL"); + System.exit(1); + } + + if (toconfig) { + try { + Configuration.parse(config_file).report(System.out); + } catch (Exception e) { + System.err.println(e.getMessage() + " reading " + config_file); + System.exit(1); + } + } else { + JMXQuery query = new JMXQuery(url, user, pass); + try { + query.connect(); + if (config_file != null) { + query.setConfig(Configuration.parse(config_file)); + } + query.list(); + } catch (Exception ex) { + System.err.println(ex.getMessage() + " querying " + url); + ex.printStackTrace(); + System.exit(1); + } finally { + try { + query.disconnect(); + } catch (IOException e) { + System.err.println(e.getMessage() + " closing " + url); + } + } + } + } + + private void setConfig(Configuration configuration) { + config = configuration; + } + + public Configuration getConfig() { + return config; + } +}