001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 * */ 018package org.apache.hadoop.hbase.util; 019 020import java.beans.IntrospectionException; 021import java.io.IOException; 022import java.io.PrintWriter; 023import java.io.StringWriter; 024import java.lang.management.GarbageCollectorMXBean; 025import java.lang.management.ManagementFactory; 026import java.lang.management.MemoryPoolMXBean; 027import java.lang.management.RuntimeMXBean; 028import java.util.Hashtable; 029import java.util.List; 030import java.util.Set; 031import javax.management.InstanceNotFoundException; 032import javax.management.MBeanAttributeInfo; 033import javax.management.MBeanInfo; 034import javax.management.MBeanServer; 035import javax.management.MalformedObjectNameException; 036import javax.management.ObjectName; 037import javax.management.ReflectionException; 038import javax.management.openmbean.CompositeData; 039import org.apache.yetus.audience.InterfaceAudience; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043@InterfaceAudience.Private 044public final class JSONMetricUtil { 045 046 private static final Logger LOG = LoggerFactory.getLogger(JSONMetricUtil.class); 047 048 private static MBeanServer mbServer = ManagementFactory.getPlatformMBeanServer(); 049 // MBeans ObjectName domain names 050 public static final String JAVA_LANG_DOMAIN = "java.lang"; 051 public static final String JAVA_NIO_DOMAIN = "java.nio"; 052 public static final String SUN_MGMT_DOMAIN = "com.sun.management"; 053 public static final String HADOOP_DOMAIN = "Hadoop"; 054 055 // MBeans ObjectName properties key names 056 public static final String TYPE_KEY = "type"; 057 public static final String NAME_KEY = "name"; 058 public static final String SERVICE_KEY = "service"; 059 public static final String SUBSYSTEM_KEY = "sub"; 060 061 /** 062 * Utility for getting metric values. Collection of static methods intended for easier access to 063 * metric values. 064 */ 065 private JSONMetricUtil() { 066 // Not to be called 067 } 068 069 public static MBeanAttributeInfo[] getMBeanAttributeInfo(ObjectName bean) 070 throws IntrospectionException, InstanceNotFoundException, ReflectionException, 071 IntrospectionException, javax.management.IntrospectionException { 072 MBeanInfo mbinfo = mbServer.getMBeanInfo(bean); 073 return mbinfo.getAttributes(); 074 } 075 076 public static Object getValueFromMBean(ObjectName bean, String attribute) { 077 Object value = null; 078 try { 079 value = mbServer.getAttribute(bean, attribute); 080 } catch (Exception e) { 081 LOG.error("Unable to get value from MBean= " + bean.toString() + "for attribute=" + 082 attribute + " " + e.getMessage()); 083 } 084 return value; 085 } 086 087 /** 088 * Returns a subset of mbeans defined by qry. Modeled after DumpRegionServerMetrics#dumpMetrics. 089 * Example: String qry= "java.lang:type=Memory" 090 * @throws MalformedObjectNameException if json have bad format 091 * @throws IOException / 092 * @return String representation of json array. 093 */ 094 public static String dumpBeanToString(String qry) 095 throws MalformedObjectNameException, IOException { 096 StringWriter sw = new StringWriter(1024 * 100); // Guess this size 097 try (PrintWriter writer = new PrintWriter(sw)) { 098 JSONBean dumper = new JSONBean(); 099 try (JSONBean.Writer jsonBeanWriter = dumper.open(writer)) { 100 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); 101 jsonBeanWriter.write(mbeanServer, new ObjectName(qry), null, false); 102 } 103 } 104 sw.close(); 105 return sw.toString(); 106 } 107 108 /** 109 * Method for building map used for constructing ObjectName. Mapping is done with arrays indices 110 * @param keys Map keys 111 * @param values Map values 112 * @return Map or null if arrays are empty * or have different number of elements 113 */ 114 public static Hashtable<String, String> buldKeyValueTable(String[] keys, String[] values) { 115 if (keys.length != values.length) { 116 LOG.error("keys and values arrays must be same size"); 117 return null; 118 } 119 if (keys.length == 0 || values.length == 0) { 120 LOG.error("keys and values arrays can not be empty;"); 121 return null; 122 } 123 Hashtable<String, String> table = new Hashtable<>(); 124 for (int i = 0; i < keys.length; i++) { 125 table.put(keys[i], values[i]); 126 } 127 return table; 128 } 129 130 public static ObjectName buildObjectName(String pattern) throws MalformedObjectNameException { 131 return new ObjectName(pattern); 132 } 133 134 public static ObjectName buildObjectName(String domain, Hashtable<String, String> keyValueTable) 135 throws MalformedObjectNameException { 136 return new ObjectName(domain, keyValueTable); 137 } 138 139 public static Set<ObjectName> getRegistredMBeans(ObjectName name, MBeanServer mbs) { 140 return mbs.queryNames(name, null); 141 } 142 143 public static String getProcessPID() { 144 return ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; 145 } 146 147 public static String getCommmand() throws MalformedObjectNameException, IOException { 148 RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); 149 return runtimeBean.getSystemProperties().get("sun.java.command"); 150 } 151 152 public static List<GarbageCollectorMXBean> getGcCollectorBeans() { 153 List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); 154 return gcBeans; 155 } 156 157 public static long getLastGcDuration(ObjectName gcCollector) { 158 long lastGcDuration = 0; 159 Object lastGcInfo = getValueFromMBean(gcCollector, "LastGcInfo"); 160 if (lastGcInfo != null && lastGcInfo instanceof CompositeData) { 161 CompositeData cds = (CompositeData) lastGcInfo; 162 lastGcDuration = (long) cds.get("duration"); 163 } 164 return lastGcDuration; 165 } 166 167 public static List<MemoryPoolMXBean> getMemoryPools() { 168 List<MemoryPoolMXBean> mPools = ManagementFactory.getMemoryPoolMXBeans(); 169 return mPools; 170 } 171 172 public static float calcPercentage(long a, long b) { 173 if (a == 0 || b == 0) { 174 return 0; 175 } 176 return ((float) a / (float) b) * 100; 177 } 178}