1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.util;
18
19 import java.io.Closeable;
20 import java.io.IOException;
21 import java.io.PrintWriter;
22 import java.io.StringWriter;
23 import java.lang.management.ManagementFactory;
24 import java.lang.reflect.Array;
25 import java.util.Iterator;
26 import java.util.Set;
27
28 import javax.management.AttributeNotFoundException;
29 import javax.management.InstanceNotFoundException;
30 import javax.management.IntrospectionException;
31 import javax.management.MBeanAttributeInfo;
32 import javax.management.MBeanException;
33 import javax.management.MBeanInfo;
34 import javax.management.MBeanServer;
35 import javax.management.MalformedObjectNameException;
36 import javax.management.ObjectName;
37 import javax.management.ReflectionException;
38 import javax.management.RuntimeErrorException;
39 import javax.management.RuntimeMBeanException;
40 import javax.management.openmbean.CompositeData;
41 import javax.management.openmbean.CompositeType;
42 import javax.management.openmbean.TabularData;
43
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46 import org.codehaus.jackson.JsonFactory;
47 import org.codehaus.jackson.JsonGenerationException;
48 import org.codehaus.jackson.JsonGenerator;
49
50
51
52
53 public class JSONBean {
54 private static final Log LOG = LogFactory.getLog(JSONBean.class);
55 private final JsonFactory jsonFactory;
56
57 public JSONBean() {
58 this.jsonFactory = new JsonFactory();
59 }
60
61
62
63
64 public interface Writer extends Closeable {
65 void write(final String key, final String value) throws JsonGenerationException, IOException;
66 int write(final MBeanServer mBeanServer, ObjectName qry, String attribute,
67 final boolean description) throws IOException;
68 void flush() throws IOException;
69 }
70
71 public Writer open(final PrintWriter writer) throws IOException {
72 final JsonGenerator jg = jsonFactory.createJsonGenerator(writer);
73 jg.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
74 jg.useDefaultPrettyPrinter();
75 jg.writeStartObject();
76 return new Writer() {
77 @Override
78 public void flush() throws IOException {
79 jg.flush();
80 }
81
82 @Override
83 public void close() throws IOException {
84 jg.close();
85 }
86
87 @Override
88 public void write(String key, String value) throws JsonGenerationException, IOException {
89 jg.writeStringField(key, value);
90 }
91
92 @Override
93 public int write(MBeanServer mBeanServer, ObjectName qry, String attribute,
94 boolean description)
95 throws IOException {
96 return JSONBean.write(jg, mBeanServer, qry, attribute, description);
97 }
98 };
99 }
100
101
102
103
104
105
106
107
108
109 private static int write(final JsonGenerator jg,
110 final MBeanServer mBeanServer, ObjectName qry, String attribute,
111 final boolean description)
112 throws IOException {
113 LOG.trace("Listing beans for "+qry);
114 Set<ObjectName> names = null;
115 names = mBeanServer.queryNames(qry, null);
116 jg.writeArrayFieldStart("beans");
117 Iterator<ObjectName> it = names.iterator();
118 while (it.hasNext()) {
119 ObjectName oname = it.next();
120 MBeanInfo minfo;
121 String code = "";
122 String descriptionStr = null;
123 Object attributeinfo = null;
124 try {
125 minfo = mBeanServer.getMBeanInfo(oname);
126 code = minfo.getClassName();
127 if (description) descriptionStr = minfo.getDescription();
128 String prs = "";
129 try {
130 if ("org.apache.commons.modeler.BaseModelMBean".equals(code)) {
131 prs = "modelerType";
132 code = (String) mBeanServer.getAttribute(oname, prs);
133 }
134 if (attribute != null) {
135 prs = attribute;
136 attributeinfo = mBeanServer.getAttribute(oname, prs);
137 }
138 } catch (RuntimeMBeanException e) {
139
140
141 if (e.getCause() instanceof UnsupportedOperationException) {
142 if (LOG.isTraceEnabled()) {
143 LOG.trace("Getting attribute " + prs + " of " + oname + " threw " + e);
144 }
145 } else {
146 LOG.error("Getting attribute " + prs + " of " + oname + " threw an exception", e);
147 }
148 return 0;
149 } catch (AttributeNotFoundException e) {
150
151
152 LOG.error("getting attribute " + prs + " of " + oname
153 + " threw an exception", e);
154 } catch (MBeanException e) {
155
156
157 LOG.error("getting attribute " + prs + " of " + oname
158 + " threw an exception", e);
159 } catch (RuntimeException e) {
160
161
162
163 LOG.error("getting attribute " + prs + " of " + oname
164 + " threw an exception", e);
165 } catch (ReflectionException e) {
166
167
168
169 LOG.error("getting attribute " + prs + " of " + oname
170 + " threw an exception", e);
171 }
172 } catch (InstanceNotFoundException e) {
173
174 continue;
175 } catch (IntrospectionException e) {
176
177
178 LOG.error("Problem while trying to process JMX query: " + qry
179 + " with MBean " + oname, e);
180 continue;
181 } catch (ReflectionException e) {
182
183
184 LOG.error("Problem while trying to process JMX query: " + qry
185 + " with MBean " + oname, e);
186 continue;
187 }
188
189 jg.writeStartObject();
190 jg.writeStringField("name", oname.toString());
191 if (description && descriptionStr != null && descriptionStr.length() > 0) {
192 jg.writeStringField("description", descriptionStr);
193 }
194 jg.writeStringField("modelerType", code);
195 if (attribute != null && attributeinfo == null) {
196 jg.writeStringField("result", "ERROR");
197 jg.writeStringField("message", "No attribute with name " + attribute + " was found.");
198 jg.writeEndObject();
199 jg.writeEndArray();
200 jg.close();
201 return -1;
202 }
203
204 if (attribute != null) {
205 writeAttribute(jg, attribute, descriptionStr, attributeinfo);
206 } else {
207 MBeanAttributeInfo[] attrs = minfo.getAttributes();
208 for (int i = 0; i < attrs.length; i++) {
209 writeAttribute(jg, mBeanServer, oname, description, attrs[i]);
210 }
211 }
212 jg.writeEndObject();
213 }
214 jg.writeEndArray();
215 return 0;
216 }
217
218 private static void writeAttribute(final JsonGenerator jg,
219 final MBeanServer mBeanServer, ObjectName oname,
220 final boolean description, final MBeanAttributeInfo attr)
221 throws IOException {
222 if (!attr.isReadable()) {
223 return;
224 }
225 String attName = attr.getName();
226 if ("modelerType".equals(attName)) {
227 return;
228 }
229 if (attName.indexOf("=") >= 0 || attName.indexOf(":") >= 0 || attName.indexOf(" ") >= 0) {
230 return;
231 }
232 String descriptionStr = description? attr.getDescription(): null;
233 Object value = null;
234 try {
235 value = mBeanServer.getAttribute(oname, attName);
236 } catch (RuntimeMBeanException e) {
237
238
239 if (e.getCause() instanceof UnsupportedOperationException) {
240 if (LOG.isTraceEnabled()) {
241 LOG.trace("Getting attribute " + attName + " of " + oname + " threw " + e);
242 }
243 } else {
244 LOG.error("getting attribute "+attName+" of "+oname+" threw an exception", e);
245 }
246 return;
247 } catch (RuntimeErrorException e) {
248
249
250 LOG.debug("getting attribute "+attName+" of "+oname+" threw an exception", e);
251 return;
252 } catch (AttributeNotFoundException e) {
253
254
255
256 return;
257 } catch (MBeanException e) {
258
259
260 LOG.error("getting attribute "+attName+" of "+oname+" threw an exception", e);
261 return;
262 } catch (RuntimeException e) {
263
264
265 LOG.error("getting attribute "+attName+" of "+oname+" threw an exception", e);
266 return;
267 } catch (ReflectionException e) {
268
269
270 LOG.error("getting attribute "+attName+" of "+oname+" threw an exception", e);
271 return;
272 } catch (InstanceNotFoundException e) {
273
274
275
276 return;
277 }
278
279 writeAttribute(jg, attName, descriptionStr, value);
280 }
281
282 private static void writeAttribute(JsonGenerator jg, String attName, final String descriptionStr,
283 Object value)
284 throws IOException {
285 boolean description = false;
286 if (descriptionStr != null && descriptionStr.length() > 0 && !attName.equals(descriptionStr)) {
287 description = true;
288 jg.writeFieldName(attName);
289 jg.writeStartObject();
290 jg.writeFieldName("description");
291 jg.writeString(descriptionStr);
292 jg.writeFieldName("value");
293 writeObject(jg, description, value);
294 jg.writeEndObject();
295 } else {
296 jg.writeFieldName(attName);
297 writeObject(jg, description, value);
298 }
299 }
300
301 private static void writeObject(final JsonGenerator jg, final boolean description, Object value)
302 throws IOException {
303 if(value == null) {
304 jg.writeNull();
305 } else {
306 Class<?> c = value.getClass();
307 if (c.isArray()) {
308 jg.writeStartArray();
309 int len = Array.getLength(value);
310 for (int j = 0; j < len; j++) {
311 Object item = Array.get(value, j);
312 writeObject(jg, description, item);
313 }
314 jg.writeEndArray();
315 } else if(value instanceof Number) {
316 Number n = (Number)value;
317 double doubleValue = n.doubleValue();
318 if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
319 jg.writeString(n.toString());
320 } else {
321 jg.writeNumber(n.toString());
322 }
323 } else if(value instanceof Boolean) {
324 Boolean b = (Boolean)value;
325 jg.writeBoolean(b);
326 } else if(value instanceof CompositeData) {
327 CompositeData cds = (CompositeData)value;
328 CompositeType comp = cds.getCompositeType();
329 Set<String> keys = comp.keySet();
330 jg.writeStartObject();
331 for (String key: keys) {
332 writeAttribute(jg, key, null, cds.get(key));
333 }
334 jg.writeEndObject();
335 } else if(value instanceof TabularData) {
336 TabularData tds = (TabularData)value;
337 jg.writeStartArray();
338 for(Object entry : tds.values()) {
339 writeObject(jg, description, entry);
340 }
341 jg.writeEndArray();
342 } else {
343 jg.writeString(value.toString());
344 }
345 }
346 }
347
348
349
350
351
352
353 public static String dumpRegionServerMetrics() throws MalformedObjectNameException, IOException {
354 StringWriter sw = new StringWriter(1024 * 100);
355 try (PrintWriter writer = new PrintWriter(sw)) {
356 JSONBean dumper = new JSONBean();
357 try (JSONBean.Writer jsonBeanWriter = dumper.open(writer)) {
358 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
359 jsonBeanWriter.write(mbeanServer,
360 new ObjectName("java.lang:type=Memory"), null, false);
361 jsonBeanWriter.write(mbeanServer,
362 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=IPC"), null, false);
363 jsonBeanWriter.write(mbeanServer,
364 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=Replication"), null, false);
365 jsonBeanWriter.write(mbeanServer,
366 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=Server"), null, false);
367 }
368 }
369 sw.close();
370 return sw.toString();
371 }
372
373
374
375
376
377
378 public static void dumpAllBeans() throws IOException, MalformedObjectNameException {
379 try (PrintWriter writer = new PrintWriter(System.out)) {
380 JSONBean dumper = new JSONBean();
381 try (JSONBean.Writer jsonBeanWriter = dumper.open(writer)) {
382 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
383 jsonBeanWriter.write(mbeanServer, new ObjectName("*:*"), null, false);
384 }
385 }
386 }
387
388 public static void main(String[] args) throws IOException, MalformedObjectNameException {
389 String str = dumpRegionServerMetrics();
390 System.out.println(str);
391 }
392 }