blob: 38366b6fc2c5a91d6de4fb9e012f40ac6d4d5ac6 [file] [log] [blame]
Pavlin Radoslavov295b2962014-10-23 01:12:41 -07001package org.onlab.onos.metrics.intent;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.LinkedList;
6import java.util.List;
7
8import com.codahale.metrics.Gauge;
9import com.codahale.metrics.Meter;
10import com.google.common.collect.ImmutableList;
11import org.apache.felix.scr.annotations.Activate;
12import org.apache.felix.scr.annotations.Component;
13import org.apache.felix.scr.annotations.Deactivate;
14import org.apache.felix.scr.annotations.Reference;
15import org.apache.felix.scr.annotations.ReferenceCardinality;
16import org.apache.felix.scr.annotations.Service;
17import org.onlab.metrics.MetricsComponent;
18import org.onlab.metrics.MetricsFeature;
19import org.onlab.metrics.MetricsService;
20import org.onlab.onos.net.intent.IntentEvent;
21import org.onlab.onos.net.intent.IntentListener;
22import org.onlab.onos.net.intent.IntentService;
23import org.slf4j.Logger;
24
25/**
26 * ONOS Intent Metrics Application that collects intent-related metrics.
27 */
28@Component(immediate = true)
29@Service
30public class IntentMetrics implements IntentMetricsService,
31 IntentListener {
32 private static final Logger log = getLogger(IntentMetrics.class);
33
34 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
35 protected IntentService intentService;
36 private LinkedList<IntentEvent> lastEvents = new LinkedList<>();
37 private static final int LAST_EVENTS_MAX_N = 100;
38
39 //
40 // Metrics
41 //
42 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
43 protected MetricsService metricsService;
44 //
45 private static final String COMPONENT_NAME = "Intent";
46 private static final String FEATURE_SUBMITTED_NAME = "Submitted";
47 private static final String FEATURE_INSTALLED_NAME = "Installed";
48 private static final String FEATURE_WITHDRAW_REQUESTED_NAME =
49 "WithdrawRequested";
50 private static final String FEATURE_WITHDRAWN_NAME = "Withdrawn";
51 private static final String GAUGE_TIMESTAMP_NAME = "Timestamp.EpochMs";
52 private static final String METER_RATE_NAME = "Rate";
53 //
54 private MetricsComponent metricsComponent;
55 private MetricsFeature metricsFeatureSubmitted;
56 private MetricsFeature metricsFeatureInstalled;
57 private MetricsFeature metricsFeatureWithdrawRequested;
58 private MetricsFeature metricsFeatureWithdrawn;
59 //
60 // Timestamps:
61 // - Intent Submitted API operation (ms from the Epoch)
62 // - Intent Installed operation completion (ms from the Epoch)
63 // - Intent Withdraw Requested API operation (ms from the Epoch)
64 // - Intent Withdrawn operation completion (ms from the Epoch)
65 //
66 private volatile long intentSubmittedTimestampEpochMs = 0;
67 private volatile long intentInstalledTimestampEpochMs = 0;
68 private volatile long intentWithdrawRequestedTimestampEpochMs = 0;
69 private volatile long intentWithdrawnTimestampEpochMs = 0;
70 //
71 private Gauge<Long> intentSubmittedTimestampEpochMsGauge;
72 private Gauge<Long> intentInstalledTimestampEpochMsGauge;
73 private Gauge<Long> intentWithdrawRequestedTimestampEpochMsGauge;
74 private Gauge<Long> intentWithdrawnTimestampEpochMsGauge;
75 //
76 // Rate meters:
77 // - Rate of the Submitted Intent API operations
78 // - Rate of the Installed Intent operations
79 // - Rate of the Withdrawn Requested Intent API operations
80 // - Rate of the Withdrawn Intent operations
81 //
82 private Meter intentSubmittedRateMeter;
83 private Meter intentInstalledRateMeter;
84 private Meter intentWithdrawRequestedRateMeter;
85 private Meter intentWithdrawnRateMeter;
86
87 @Activate
88 protected void activate() {
89 clear();
90 registerMetrics();
91 intentService.addListener(this);
92 log.info("ONOS Intent Metrics started.");
93 }
94
95 @Deactivate
96 public void deactivate() {
97 intentService.removeListener(this);
98 removeMetrics();
99 clear();
100 log.info("ONOS Intent Metrics stopped.");
101 }
102
103 @Override
104 public List<IntentEvent> getEvents() {
105 synchronized (lastEvents) {
106 return ImmutableList.<IntentEvent>copyOf(lastEvents);
107 }
108 }
109
110 @Override
111 public Gauge<Long> intentSubmittedTimestampEpochMsGauge() {
112 return intentSubmittedTimestampEpochMsGauge;
113 }
114
115 @Override
116 public Gauge<Long> intentInstalledTimestampEpochMsGauge() {
117 return intentInstalledTimestampEpochMsGauge;
118 }
119
120 @Override
121 public Gauge<Long> intentWithdrawRequestedTimestampEpochMsGauge() {
122 return intentWithdrawRequestedTimestampEpochMsGauge;
123 }
124
125 @Override
126 public Gauge<Long> intentWithdrawnTimestampEpochMsGauge() {
127 return intentWithdrawnTimestampEpochMsGauge;
128 }
129
130 @Override
131 public Meter intentSubmittedRateMeter() {
132 return intentSubmittedRateMeter;
133 }
134
135 @Override
136 public Meter intentInstalledRateMeter() {
137 return intentInstalledRateMeter;
138 }
139
140 @Override
141 public Meter intentWithdrawRequestedRateMeter() {
142 return intentWithdrawRequestedRateMeter;
143 }
144
145 @Override
146 public Meter intentWithdrawnRateMeter() {
147 return intentWithdrawnRateMeter;
148 }
149
150 @Override
151 public void event(IntentEvent event) {
152 synchronized (lastEvents) {
153 //
154 // TODO: The processing below is incomplete: we don't have
155 // an event equivalent of "Withdraw Requested"
156 //
157 switch (event.type()) {
158 case SUBMITTED:
159 intentSubmittedTimestampEpochMs = System.currentTimeMillis();
160 intentSubmittedRateMeter.mark(1);
161 break;
162 case INSTALLED:
163 intentInstalledTimestampEpochMs = System.currentTimeMillis();
164 intentInstalledRateMeter.mark(1);
165 break;
166 case FAILED:
167 // TODO: Just ignore?
168 break;
169 /*
170 case WITHDRAW_REQUESTED:
171 intentWithdrawRequestedTimestampEpochMs =
172 System.currentTimeMillis();
173 intentWithdrawRequestedRateMeter.mark(1);
174 break;
175 */
176 case WITHDRAWN:
177 intentWithdrawnTimestampEpochMs = System.currentTimeMillis();
178 intentWithdrawnRateMeter.mark(1);
179 break;
180 default:
181 break;
182 }
183
184 //
185 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
186 //
187 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
188 lastEvents.remove();
189 }
190 lastEvents.add(event);
191 }
192
193 log.debug("Intent Event: time = {} type = {} event = {}",
194 event.time(), event.type(), event);
195 }
196
197 /**
198 * Clears the internal state.
199 */
200 private void clear() {
201 synchronized (lastEvents) {
202 intentSubmittedTimestampEpochMs = 0;
203 intentInstalledTimestampEpochMs = 0;
204 intentWithdrawRequestedTimestampEpochMs = 0;
205 intentWithdrawnTimestampEpochMs = 0;
206 lastEvents.clear();
207 }
208 }
209
210 /**
211 * Registers the metrics.
212 */
213 private void registerMetrics() {
214 metricsComponent = metricsService.registerComponent(COMPONENT_NAME);
215 //
216 metricsFeatureSubmitted =
217 metricsComponent.registerFeature(FEATURE_SUBMITTED_NAME);
218 metricsFeatureInstalled =
219 metricsComponent.registerFeature(FEATURE_INSTALLED_NAME);
220 metricsFeatureWithdrawRequested =
221 metricsComponent.registerFeature(FEATURE_WITHDRAW_REQUESTED_NAME);
222 metricsFeatureWithdrawn =
223 metricsComponent.registerFeature(FEATURE_WITHDRAWN_NAME);
224 //
225 intentSubmittedTimestampEpochMsGauge =
226 metricsService.registerMetric(metricsComponent,
227 metricsFeatureSubmitted,
228 GAUGE_TIMESTAMP_NAME,
229 new Gauge<Long>() {
230 @Override
231 public Long getValue() {
232 return intentSubmittedTimestampEpochMs;
233 }
234 });
235 //
236 intentInstalledTimestampEpochMsGauge =
237 metricsService.registerMetric(metricsComponent,
238 metricsFeatureInstalled,
239 GAUGE_TIMESTAMP_NAME,
240 new Gauge<Long>() {
241 @Override
242 public Long getValue() {
243 return intentInstalledTimestampEpochMs;
244 }
245 });
246 //
247 intentWithdrawRequestedTimestampEpochMsGauge =
248 metricsService.registerMetric(metricsComponent,
249 metricsFeatureWithdrawRequested,
250 GAUGE_TIMESTAMP_NAME,
251 new Gauge<Long>() {
252 @Override
253 public Long getValue() {
254 return intentWithdrawRequestedTimestampEpochMs;
255 }
256 });
257 //
258 intentWithdrawnTimestampEpochMsGauge =
259 metricsService.registerMetric(metricsComponent,
260 metricsFeatureWithdrawn,
261 GAUGE_TIMESTAMP_NAME,
262 new Gauge<Long>() {
263 @Override
264 public Long getValue() {
265 return intentWithdrawnTimestampEpochMs;
266 }
267 });
268 //
269 intentSubmittedRateMeter =
270 metricsService.createMeter(metricsComponent,
271 metricsFeatureSubmitted,
272 METER_RATE_NAME);
273 //
274 intentInstalledRateMeter =
275 metricsService.createMeter(metricsComponent,
276 metricsFeatureInstalled,
277 METER_RATE_NAME);
278 //
279 intentWithdrawRequestedRateMeter =
280 metricsService.createMeter(metricsComponent,
281 metricsFeatureWithdrawRequested,
282 METER_RATE_NAME);
283 //
284 intentWithdrawnRateMeter =
285 metricsService.createMeter(metricsComponent,
286 metricsFeatureWithdrawn,
287 METER_RATE_NAME);
288 }
289
290 /**
291 * Removes the metrics.
292 */
293 private void removeMetrics() {
294 metricsService.removeMetric(metricsComponent,
295 metricsFeatureSubmitted,
296 GAUGE_TIMESTAMP_NAME);
297 metricsService.removeMetric(metricsComponent,
298 metricsFeatureInstalled,
299 GAUGE_TIMESTAMP_NAME);
300 metricsService.removeMetric(metricsComponent,
301 metricsFeatureWithdrawRequested,
302 GAUGE_TIMESTAMP_NAME);
303 metricsService.removeMetric(metricsComponent,
304 metricsFeatureWithdrawn,
305 GAUGE_TIMESTAMP_NAME);
306 metricsService.removeMetric(metricsComponent,
307 metricsFeatureSubmitted,
308 METER_RATE_NAME);
309 metricsService.removeMetric(metricsComponent,
310 metricsFeatureInstalled,
311 METER_RATE_NAME);
312 metricsService.removeMetric(metricsComponent,
313 metricsFeatureWithdrawRequested,
314 METER_RATE_NAME);
315 metricsService.removeMetric(metricsComponent,
316 metricsFeatureWithdrawn,
317 METER_RATE_NAME);
318 }
319}