1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.giraph.metrics; 20 21 import org.apache.giraph.conf.GiraphConfiguration; 22 23 import com.yammer.metrics.core.Counter; 24 import com.yammer.metrics.core.Gauge; 25 import com.yammer.metrics.core.Histogram; 26 import com.yammer.metrics.core.Meter; 27 import com.yammer.metrics.core.Metric; 28 import com.yammer.metrics.core.MetricName; 29 import com.yammer.metrics.core.MetricPredicate; 30 import com.yammer.metrics.core.MetricsRegistry; 31 import com.yammer.metrics.core.Timer; 32 import com.yammer.metrics.reporting.ConsoleReporter; 33 import com.yammer.metrics.reporting.JmxReporter; 34 35 import java.io.PrintStream; 36 import java.util.Map; 37 import java.util.concurrent.TimeUnit; 38 39 /** 40 * A holder for MetricsRegistry together with a JmxReporter. 41 */ 42 public class GiraphMetricsRegistry { 43 /** String name of group to use for metrics created */ 44 private String groupName; 45 /** String type to use for metrics created */ 46 private String type; 47 /** Internal Yammer registry used */ 48 private final MetricsRegistry registry; 49 /** JmxReporter that send metrics to JMX */ 50 private final JmxReporter jmxReporter; 51 52 /** 53 * Constructor 54 * @param registry {@link MetricsRegistry} to use 55 * @param reporter {@link JmxReporter} to use 56 * @param groupName String grouping for metrics 57 * @param type String type name for metrics 58 */ 59 protected GiraphMetricsRegistry(MetricsRegistry registry, 60 JmxReporter reporter, String groupName, String type) { 61 this.registry = registry; 62 this.jmxReporter = reporter; 63 this.groupName = groupName; 64 this.type = type; 65 if (jmxReporter != null) { 66 jmxReporter.start(); 67 } 68 } 69 70 /** 71 * Create no-op empty registry that makes no-op metrics. 72 * @return fake registry that makes no-op metrics 73 */ 74 public static GiraphMetricsRegistry createFake() { 75 return new GiraphMetricsRegistry(new NoOpMetricsRegistry(), null, "", ""); 76 } 77 78 /** 79 * Create registry with group to use for metrics. 80 * 81 * @param groupName String group to use for metrics. 82 * @param type String type to use for metrics. 83 * @return new metrics registry 84 */ 85 public static GiraphMetricsRegistry createWithOptional(String groupName, 86 String type) { 87 MetricsRegistry registry = new MetricsRegistry(); 88 return new GiraphMetricsRegistry(registry, new JmxReporter(registry), 89 groupName, type); 90 } 91 92 /** 93 * Create registry with Hadoop Configuration and group to use for metrics. 94 * Checks the configuration object for whether the optional metrics are 95 * enabled, and optionally creates those. 96 * 97 * @param conf Hadoop Configuration to use. 98 * @param groupName String group to use for metrics. 99 * @param type String type to use for metrics. 100 * @return new metrics registry 101 */ 102 public static GiraphMetricsRegistry create(GiraphConfiguration conf, 103 String groupName, String type) { 104 if (conf.metricsEnabled()) { 105 return createWithOptional(groupName, type); 106 } else { 107 return createFake(); 108 } 109 } 110 111 /** 112 * Get map of all metrics. 113 * 114 * @return Map of all metrics held. 115 */ 116 public Map<MetricName, Metric> getAll() { 117 return registry.allMetrics(); 118 } 119 120 /** 121 * Get group name used for metrics. 122 * 123 * @return String group name. 124 */ 125 public String getGroupName() { 126 return groupName; 127 } 128 129 /** 130 * Set group name used by this MetricsRegistry. Used for incrementing 131 * superstep number to create a new hierarchy of metrics per superstep. 132 * 133 * @param groupName String group name to use. 134 */ 135 protected void setGroupName(String groupName) { 136 this.groupName = groupName; 137 } 138 139 /** 140 * Get type used for new metrics created 141 * 142 * @return String type to use for metrics 143 */ 144 public String getType() { 145 return type; 146 } 147 148 /** 149 * Set type to use for new metrics 150 * 151 * @param type String type to use 152 */ 153 public void setType(String type) { 154 this.type = type; 155 } 156 157 /** 158 * Dump all the metrics to the PrintStream provided. 159 * 160 * @param out PrintStream to write metrics to. 161 */ 162 public void printToStream(PrintStream out) { 163 out.println(""); 164 new ConsoleReporter(registry, out, MetricPredicate.ALL).run(); 165 } 166 167 /** 168 * Get internal MetricsRegistry used. 169 * 170 * @return MetricsRegistry being used. 171 */ 172 protected MetricsRegistry getInternalRegistry() { 173 return registry; 174 } 175 176 /** 177 * Creates a new {@link com.yammer.metrics.core.Counter} and registers it 178 * under the given group and name. 179 * 180 * @param name the name of the metric 181 * @return a new {@link com.yammer.metrics.core.Counter} 182 */ 183 public Counter getCounter(String name) { 184 return registry.newCounter(makeMetricName(name)); 185 } 186 187 /** 188 * Given a new {@link com.yammer.metrics.core.Gauge}, registers it under the 189 * given group and name. 190 * 191 * @param name the name of the metric 192 * @param metric the metric 193 * @param <T> the type of the value returned by the metric 194 * @return {@code metric} 195 */ 196 public <T> Gauge<T> getGauge(String name, Gauge<T> metric) { 197 return registry.newGauge(makeMetricName(name), metric); 198 } 199 200 /** 201 * Creates a new biased {@link Histogram} and registers it under the given 202 * group and name 203 * 204 * @param name name of metric 205 * @return new {@link Histogram} 206 */ 207 public Histogram getBiasedHistogram(String name) { 208 return getHistogram(name, true); 209 } 210 211 /** 212 * Creates a new uniform {@link Histogram} and registers it under the given 213 * group and name 214 * 215 * @param name name of metric 216 * @return new {@link Histogram} 217 */ 218 public Histogram getUniformHistogram(String name) { 219 return getHistogram(name, false); 220 } 221 222 /** 223 * Creates a new {@link Histogram} and registers it under the given group 224 * and name. 225 * 226 * @param name the name of the metric 227 * @param biased whether or not the histogram should be biased 228 * @return a new {@link Histogram} 229 */ 230 private Histogram getHistogram(String name, boolean biased) { 231 return registry.newHistogram(makeMetricName(name), biased); 232 } 233 234 /** 235 * Creates a new {@link com.yammer.metrics.core.Meter} and registers it under 236 * the given group and name. 237 * 238 * @param meterDesc description of meter 239 * @return new {@link com.yammer.metrics.core.Meter} 240 */ 241 public Meter getMeter(MeterDesc meterDesc) { 242 return getMeter(meterDesc.getName(), meterDesc.getType(), 243 meterDesc.getTimeUnit()); 244 } 245 246 /** 247 * Creates a new {@link com.yammer.metrics.core.Meter} and registers it under 248 * the given group and name. 249 * 250 * @param name the name of the metric 251 * @param eventType the plural name of the type of events the meter is 252 * measuring (e.g., {@code "requests"}) 253 * @param timeUnit the rate unit of the new meter 254 * @return a new {@link com.yammer.metrics.core.Meter} 255 */ 256 public Meter getMeter(String name, String eventType, TimeUnit timeUnit) { 257 return registry.newMeter(makeMetricName(name), eventType, timeUnit); 258 } 259 260 /** 261 * Creates a new {@link Timer} and registers it under the given 262 * group and name. 263 * 264 * @param name the name of the metric 265 * @param durationUnit the duration scale unit of the new timer 266 * @param rateUnit the rate scale unit of the new timer 267 * @return a new {@link Timer} 268 */ 269 public Timer getTimer(String name, TimeUnit durationUnit, TimeUnit rateUnit) { 270 return registry.newTimer(makeMetricName(name), durationUnit, rateUnit); 271 } 272 273 /** 274 * Get a Gauge that is already present in the MetricsRegistry 275 * 276 * @param name String name of Gauge 277 * @param <T> type of gauge 278 * @return Gauge, from MetricsRegistry 279 */ 280 public <T> Gauge<T> getExistingGauge(String name) { 281 Metric metric = registry.allMetrics().get(makeMetricName(name)); 282 return metric instanceof Gauge ? (Gauge<T>) metric : null; 283 } 284 285 /** 286 * Create a MetricName using the job ID, group, and name. 287 * 288 * @param name String name given to metric 289 * @return MetricName for use with MetricsRegistry 290 */ 291 protected MetricName makeMetricName(String name) { 292 return new MetricName(groupName, type, name); 293 } 294 295 /** 296 * Nothing will be captured after this is called. 297 */ 298 public void shutdown() { 299 registry.shutdown(); 300 } 301 }