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 }