001package org.avaje.metric; 002 003import java.util.Collection; 004import java.util.Iterator; 005import java.util.List; 006import java.util.ServiceLoader; 007 008import org.avaje.metric.spi.SpiMetricManager; 009import org.avaje.metric.statistics.MetricStatistics; 010 011/** 012 * Manages the creation and registration of Metrics. 013 * <p> 014 * Provides methods to allow agents to go through the registered metrics and gather/report the 015 * statistics. 016 * <p> 017 * This uses a service locator to initialise a underlying PluginMetricManager instance. A default 018 * implementation of PluginMetricManager is provided by <em>avaje-metric-core</em>. 019 */ 020public class MetricManager { 021 022 /** 023 * The implementation that is found via service loader. 024 */ 025 private static final SpiMetricManager mgr = initialiseProvider(); 026 027 /** 028 * The default implementation which is avaje-metric-core. 029 */ 030 private static final String DEFAULT_PROVIDER = "org.avaje.metric.core.DefaultMetricManager"; 031 032 /** 033 * Finds and returns the implementation of PluginMetricManager using the ServiceLoader. 034 */ 035 private static SpiMetricManager initialiseProvider() { 036 037 ServiceLoader<SpiMetricManager> loader = ServiceLoader.load(SpiMetricManager.class); 038 Iterator<SpiMetricManager> it = loader.iterator(); 039 if (it.hasNext()) { 040 return it.next(); 041 } 042 try { 043 Class<?> clazz = Class.forName(DEFAULT_PROVIDER); 044 return (SpiMetricManager) clazz.newInstance(); 045 046 } catch (ClassNotFoundException e) { 047 throw new RuntimeException("Provider " + DEFAULT_PROVIDER + " not found", e); 048 049 } catch (Exception e) { 050 throw new RuntimeException("Provider " + DEFAULT_PROVIDER + " could not be instantiated: " + e, e); 051 } 052 } 053 054 /** 055 * When a request completes it is reported to the manager. 056 */ 057 public static void reportTiming(RequestTiming requestTiming) { 058 mgr.reportTiming(requestTiming); 059 } 060 061 /** 062 * Add a metric supplier to the manager. These metrics are then included in the reporting. 063 */ 064 public static void addSupplier(MetricSupplier supplier) { 065 mgr.addSupplier(supplier); 066 } 067 068 /** 069 * Create a MetricName based on a class and name. 070 * <p> 071 * Often the name maps to a method name. 072 */ 073 public static MetricName name(Class<?> cls, String name) { 074 return mgr.name(cls, name); 075 } 076 077 /** 078 * Create a Metric name by parsing a name that is expected to include periods (dot notation 079 * similar to package.Class.method). 080 */ 081 public static MetricName name(String name) { 082 return mgr.name(name); 083 } 084 085 /** 086 * Return a MetricNameCache for the given class. 087 * <p> 088 * The MetricNameCache can be used to derive MetricName objects dynamically with relatively less 089 * overhead. 090 * </p> 091 */ 092 public static MetricNameCache getMetricNameCache(Class<?> cls) { 093 return mgr.getMetricNameCache(cls); 094 } 095 096 /** 097 * Return a MetricNameCache for a given base metric name. 098 * <p> 099 * The MetricNameCache can be used to derive MetricName objects dynamically with relatively less 100 * overhead. 101 * </p> 102 */ 103 public static MetricNameCache getMetricNameCache(MetricName baseName) { 104 return mgr.getMetricNameCache(baseName); 105 } 106 107 /** 108 * Return a BucketTimedMetric given the name and bucket ranges. 109 */ 110 public static TimedMetric getTimedMetric(MetricName name, int... bucketRanges) { 111 return mgr.getTimedMetric(name, bucketRanges); 112 } 113 114 /** 115 * Return a BucketTimedMetric given the name and bucket ranges. 116 */ 117 public static TimedMetric getTimedMetric(Class<?> cls, String name, int... bucketRanges) { 118 return getTimedMetric(name(cls, name), bucketRanges); 119 } 120 121 /** 122 * Return a BucketTimedMetric given the name and bucket ranges. 123 */ 124 public static TimedMetric getTimedMetric(String name, int... bucketRanges) { 125 return getTimedMetric(name(name), bucketRanges); 126 } 127 128 /** 129 * Return a TimedMetric given the name. 130 */ 131 public static TimedMetric getTimedMetric(MetricName name) { 132 return mgr.getTimedMetric(name); 133 } 134 135 /** 136 * Return a TimedMetric using the Class, name to derive the MetricName. 137 */ 138 public static TimedMetric getTimedMetric(Class<?> cls, String eventName) { 139 return getTimedMetric(name(cls, eventName)); 140 } 141 142 /** 143 * Return a TimedMetric given the name. 144 */ 145 public static TimedMetric getTimedMetric(String name) { 146 return getTimedMetric(name(name)); 147 } 148 149 /** 150 * Return a CounterMetric given the name. 151 */ 152 public static CounterMetric getCounterMetric(MetricName name) { 153 return mgr.getCounterMetric(name); 154 } 155 156 /** 157 * Return a CounterMetric given the name. 158 */ 159 public static CounterMetric getCounterMetric(String name) { 160 return getCounterMetric(name(name)); 161 } 162 163 /** 164 * Return a CounterMetric using the Class and name to derive the MetricName. 165 */ 166 public static CounterMetric getCounterMetric(Class<?> cls, String eventName) { 167 return getCounterMetric(name(cls, eventName)); 168 } 169 170 /** 171 * Return a ValueMetric given the name. 172 */ 173 public static ValueMetric getValueMetric(MetricName name) { 174 return mgr.getValueMetric(name); 175 } 176 177 /** 178 * Return a ValueMetric using the Class and name to derive the MetricName. 179 */ 180 public static ValueMetric getValueMetric(Class<?> cls, String eventName) { 181 return getValueMetric(name(cls, eventName)); 182 } 183 184 /** 185 * Return a ValueMetric given the name. 186 */ 187 public static ValueMetric getValueMetric(String name) { 188 return getValueMetric(name(name)); 189 } 190 191 /** 192 * Return the TimedMetricGroup with a based metric name. 193 */ 194 public static TimedMetricGroup getTimedMetricGroup(MetricName baseName) { 195 return mgr.getTimedMetricGroup(baseName); 196 } 197 198 /** 199 * Return the TimedMetricGroup with a class providing the base metric name. 200 * <p> 201 * The package name is the 'group' and the simple class name the 'type'. 202 */ 203 public static TimedMetricGroup getTimedMetricGroup(Class<?> cls) { 204 return getTimedMetricGroup(name(cls,"")); 205 } 206 207 /** 208 * Return a TimedMetricGroup with a common group and type name. 209 * 210 * @param name 211 * the metric name 212 * 213 * @return the TimedMetricGroup used to create TimedMetric's that have a common base name. 214 */ 215 public static TimedMetricGroup getTimedMetricGroup(String name) { 216 return getTimedMetricGroup(MetricName.of(name)); 217 } 218 219 /** 220 * Create and register a GaugeMetric using the gauge supplied. 221 */ 222 public static GaugeDoubleMetric register(MetricName name, GaugeDouble gauge) { 223 return mgr.register(name, gauge); 224 } 225 226 /** 227 * Create and register a GaugeMetric using the gauge supplied. 228 */ 229 public static GaugeDoubleMetric register(String name, GaugeDouble gauge) { 230 return mgr.register(name(name), gauge); 231 } 232 233 /** 234 * Create and register a GaugeCounterMetric using the gauge supplied. 235 */ 236 public static GaugeLongMetric register(MetricName name, GaugeLong gauge) { 237 return mgr.register(name, gauge); 238 } 239 240 /** 241 * Create and register a GaugeCounterMetric using the gauge supplied. 242 */ 243 public static GaugeLongMetric register(String name, GaugeLong gauge) { 244 return mgr.register(name(name), gauge); 245 } 246 247 /** 248 * Return all the non-JVM registered metrics. 249 */ 250 public static Collection<Metric> getMetrics() { 251 return mgr.getMetrics(); 252 } 253 254 /** 255 * Return the core JVM metrics. 256 */ 257 public static Collection<Metric> getJvmMetrics() { 258 return mgr.getJvmMetrics(); 259 } 260 261 /** 262 * Return all the non-JVM registered metrics that are not empty. 263 */ 264 public static List<MetricStatistics> collectNonEmptyMetrics() { 265 return mgr.collectNonEmptyMetrics(); 266 } 267 268 /** 269 * Return JVM metrics that are not empty. 270 */ 271 public static List<MetricStatistics> collectNonEmptyJvmMetrics() { 272 return mgr.collectNonEmptyJvmMetrics(); 273 } 274 275 /** 276 * Return the built in JVM metrics support to register collection of all or some 277 * of the built in JVM metrics. 278 */ 279 public static JvmMetrics jvmMetrics() { 280 return mgr; 281 } 282 283 /** 284 * Return the API for managing request timing. 285 */ 286 public static RequestTimingManager requestTimingManager() { 287 return mgr; 288 } 289 290}