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