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