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 jg.writeNumber(n.toString());
318 } else if(value instanceof Boolean) {
319 Boolean b = (Boolean)value;
320 jg.writeBoolean(b);
321 } else if(value instanceof CompositeData) {
322 CompositeData cds = (CompositeData)value;
323 CompositeType comp = cds.getCompositeType();
324 Set<String> keys = comp.keySet();
325 jg.writeStartObject();
326 for (String key: keys) {
327 writeAttribute(jg, key, null, cds.get(key));
328 }
329 jg.writeEndObject();
330 } else if(value instanceof TabularData) {
331 TabularData tds = (TabularData)value;
332 jg.writeStartArray();
333 for(Object entry : tds.values()) {
334 writeObject(jg, description, entry);
335 }
336 jg.writeEndArray();
337 } else {
338 jg.writeString(value.toString());
339 }
340 }
341 }
342
343
344
345
346
347
348 public static String dumpRegionServerMetrics() throws MalformedObjectNameException, IOException {
349 StringWriter sw = new StringWriter(1024 * 100);
350 try (PrintWriter writer = new PrintWriter(sw)) {
351 JSONBean dumper = new JSONBean();
352 try (JSONBean.Writer jsonBeanWriter = dumper.open(writer)) {
353 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
354 jsonBeanWriter.write(mbeanServer,
355 new ObjectName("java.lang:type=Memory"), null, false);
356 jsonBeanWriter.write(mbeanServer,
357 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=IPC"), null, false);
358 jsonBeanWriter.write(mbeanServer,
359 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=Replication"), null, false);
360 jsonBeanWriter.write(mbeanServer,
361 new ObjectName("Hadoop:service=HBase,name=RegionServer,sub=Server"), null, false);
362 }
363 }
364 sw.close();
365 return sw.toString();
366 }
367
368
369
370
371
372
373 public static void dumpAllBeans() throws IOException, MalformedObjectNameException {
374 try (PrintWriter writer = new PrintWriter(System.out)) {
375 JSONBean dumper = new JSONBean();
376 try (JSONBean.Writer jsonBeanWriter = dumper.open(writer)) {
377 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
378 jsonBeanWriter.write(mbeanServer, new ObjectName("*:*"), null, false);
379 }
380 }
381 }
382
383 public static void main(String[] args) throws IOException, MalformedObjectNameException {
384 String str = dumpRegionServerMetrics();
385 System.out.println(str);
386 }
387 }