blob: 4e983400aa22f1bd94993a47bf46e0346753e77e [file] [log] [blame]
Flavio Castro41b1f3a2015-07-31 13:51:32 -07001package org.onosproject.store.consistent.impl;
2
3/*
4 * Copyright 2015 Open Networking Laboratory
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * 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
19import com.codahale.metrics.Timer;
20import com.google.common.collect.Maps;
21import org.onlab.metrics.MetricsComponent;
22import org.onlab.metrics.MetricsFeature;
23import org.onlab.metrics.MetricsService;
24import org.onlab.osgi.DefaultServiceDirectory;
25
26import java.util.Map;
27import java.util.concurrent.TimeUnit;
28
29import static com.google.common.base.Preconditions.checkNotNull;
30
31/**
32 * Agent that implements usage and performance monitoring via the metrics service.
33 */
34public class MeteringAgent {
35
36 private MetricsService metricsService;
37 private MetricsComponent metricsComponent;
38 private MetricsFeature metricsFeature;
39 private final Map<String, Timer> perObjOpTimers = Maps.newConcurrentMap();
40 private final Map<String, Timer> perOpTimers = Maps.newConcurrentMap();
41 private Timer perPrimitiveTimer;
42 private Timer perObjTimer;
43 private MetricsFeature wildcard;
44 private final boolean activated;
45 private Context nullTimer;
46
47 /**
48 * Constructs a new MeteringAgent for a given distributed primitive.
49 * Instantiates the metrics service
50 * Initializes all the general metrics for that object
51 *
52 * @param primitiveName Type of primitive to be metered
53 * @param objName Global name of the primitive
54 * @param activated
55 */
56 public MeteringAgent(String primitiveName, String objName, boolean activated) {
57 checkNotNull(objName, "Object name cannot be null");
58 this.activated = activated;
59 nullTimer = new Context(null, "");
60 if (this.activated) {
61 this.metricsService = DefaultServiceDirectory.getService(MetricsService.class);
62 this.metricsComponent = metricsService.registerComponent(primitiveName);
63 this.metricsFeature = metricsComponent.registerFeature(objName);
64 this.wildcard = metricsComponent.registerFeature("*");
65 this.perObjTimer = metricsService.createTimer(metricsComponent, metricsFeature, "*");
66 this.perPrimitiveTimer = metricsService.createTimer(metricsComponent, wildcard, "*");
67 }
68 }
69
70 /**
71 * Initializes a specific timer for a given operation.
72 *
73 * @param op Specific operation being metered
74 */
75 public Context startTimer(String op) {
76 if (!activated) {
77 return nullTimer;
78 }
79 // Check if timer exists, if it doesn't creates it
80 final Timer currTimer = perObjOpTimers.computeIfAbsent(op, timer ->
81 metricsService.createTimer(metricsComponent, metricsFeature, op));
82 perOpTimers.computeIfAbsent(op, timer -> metricsService.createTimer(metricsComponent, wildcard, op));
83 // Starts timer
84 return new Context(currTimer.time(), op);
85 }
86
87 /**
88 * Timer.Context with a specific operation.
89 */
90 public class Context {
91 private final Timer.Context context;
92 private final String operation;
93
94 /**
95 * Constructs Context.
96 *
97 * @param context
98 * @param operation
99 */
100 public Context(Timer.Context context, String operation) {
101 this.context = context;
102 this.operation = operation;
103 }
104
105 /**
106 * Stops timer given a specific context and updates all related metrics.
107 */
108 public void stop() {
109 if (!activated) {
110 return;
111 }
112 //Stop and updates timer with specific measurements per map, per operation
113 final long time = context.stop();
114 //updates timer with aggregated measurements per map
115 perOpTimers.get(operation).update(time, TimeUnit.NANOSECONDS);
116 //updates timer with aggregated measurements per map
117 perObjTimer.update(time, TimeUnit.NANOSECONDS);
118 //updates timer with aggregated measurements per all Consistent Maps
119 perPrimitiveTimer.update(time, TimeUnit.NANOSECONDS);
120 }
121 }
122
123}