Pavlin Radoslavov

Added a new module: ONOS intent metrics application

It can be used as an Intent-related event and event metrics collector.
It can be loaded by one of the following two (new) features:
     onos-app-metrics, onos-app-metrics-intent

After loading the module, it subscribes for intent-related events
and keeps the following state:
 (a) The last 100 events
 (b) The timestamp of the last event (ms after epoch) as observed by this
     module for each event type: SUBMITTED, INSTALLED, WITHDRAWN.
     The missing event type is the equivalent of "Withdraw Requested"
 (c) The rate of each intent event type: count, median rate, average rate
      over the last 1, 5 or 15 minutes

The following CLI commands are added:
 * onos:intents-events
   Shows the last 100 intent events
 * onos:intents-events-metrics
   Shows the timestamp of the last event (ms after epoch) as observed by
   this module for each event type, and the rate of the topology
   events (for each event type): see (b) and (c) above

Change-Id: I9f23e9086bbd433b8f24283539abdeb97e199e2e
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5 + <modelVersion>4.0.0</modelVersion>
6 +
7 + <parent>
8 + <groupId>org.onlab.onos</groupId>
9 + <artifactId>onos-app-metrics</artifactId>
10 + <version>1.0.0-SNAPSHOT</version>
11 + <relativePath>../pom.xml</relativePath>
12 + </parent>
13 +
14 + <artifactId>onos-app-metrics-intent</artifactId>
15 + <packaging>bundle</packaging>
16 +
17 + <description>ONOS intent metrics application</description>
18 +
19 + <dependencies>
20 + <dependency>
21 + <groupId>org.onlab.onos</groupId>
22 + <artifactId>onos-cli</artifactId>
23 + <version>${project.version}</version>
24 + </dependency>
25 +
26 + <dependency>
27 + <groupId>org.apache.karaf.shell</groupId>
28 + <artifactId>org.apache.karaf.shell.console</artifactId>
29 + </dependency>
30 + </dependencies>
31 +
32 +</project>
1 +package org.onlab.onos.metrics.intent;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.LinkedList;
6 +import java.util.List;
7 +
8 +import com.codahale.metrics.Gauge;
9 +import com.codahale.metrics.Meter;
10 +import com.google.common.collect.ImmutableList;
11 +import org.apache.felix.scr.annotations.Activate;
12 +import org.apache.felix.scr.annotations.Component;
13 +import org.apache.felix.scr.annotations.Deactivate;
14 +import org.apache.felix.scr.annotations.Reference;
15 +import org.apache.felix.scr.annotations.ReferenceCardinality;
16 +import org.apache.felix.scr.annotations.Service;
17 +import org.onlab.metrics.MetricsComponent;
18 +import org.onlab.metrics.MetricsFeature;
19 +import org.onlab.metrics.MetricsService;
20 +import org.onlab.onos.net.intent.IntentEvent;
21 +import org.onlab.onos.net.intent.IntentListener;
22 +import org.onlab.onos.net.intent.IntentService;
23 +import org.slf4j.Logger;
24 +
25 +/**
26 + * ONOS Intent Metrics Application that collects intent-related metrics.
27 + */
28 +@Component(immediate = true)
29 +@Service
30 +public 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 +}
1 +package org.onlab.onos.metrics.intent;
2 +
3 +import java.util.List;
4 +
5 +import com.codahale.metrics.Gauge;
6 +import com.codahale.metrics.Meter;
7 +import org.onlab.onos.net.intent.IntentEvent;
8 +
9 +/**
10 + * Service interface exported by IntentMetrics.
11 + */
12 +public interface IntentMetricsService {
13 + /**
14 + * Gets the last saved intent events.
15 + *
16 + * @return the last saved intent events.
17 + */
18 + public List<IntentEvent> getEvents();
19 +
20 + /**
21 + * Gets the Metrics' Gauge for the intent SUBMITTED event timestamp
22 + * (ms from the epoch).
23 + *
24 + * @return the Metrics' Gauge for the intent SUBMITTED event timestamp
25 + * (ms from the epoch)
26 + */
27 + public Gauge<Long> intentSubmittedTimestampEpochMsGauge();
28 +
29 + /**
30 + * Gets the Metrics' Gauge for the intent INSTALLED event timestamp
31 + * (ms from the epoch).
32 + *
33 + * @return the Metrics' Gauge for the intent INSTALLED event timestamp
34 + * (ms from the epoch)
35 + */
36 + public Gauge<Long> intentInstalledTimestampEpochMsGauge();
37 +
38 + /**
39 + * Gets the Metrics' Gauge for the intent WITHDRAW_REQUESTED event
40 + * timestamp (ms from the epoch).
41 + *
42 + * TODO: This intent event is not implemented yet.
43 + *
44 + * @return the Metrics' Gauge for the intent WITHDRAW_REQUESTED event
45 + * timestamp (ms from the epoch)
46 + */
47 + public Gauge<Long> intentWithdrawRequestedTimestampEpochMsGauge();
48 +
49 + /**
50 + * Gets the Metrics' Gauge for the intent WITHDRAWN event timestamp
51 + * (ms from the epoch).
52 + *
53 + * @return the Metrics' Gauge for the intent WITHDRAWN event timestamp
54 + * (ms from the epoch)
55 + */
56 + public Gauge<Long> intentWithdrawnTimestampEpochMsGauge();
57 +
58 + /**
59 + * Gets the Metrics' Meter for the submitted intents event rate.
60 + *
61 + * @return the Metrics' Meter for the submitted intents event rate
62 + */
63 + public Meter intentSubmittedRateMeter();
64 +
65 + /**
66 + * Gets the Metrics' Meter for the installed intents event rate.
67 + *
68 + * @return the Metrics' Meter for the installed intent event rate
69 + */
70 + public Meter intentInstalledRateMeter();
71 +
72 + /**
73 + * Gets the Metrics' Meter for the withdraw requested intents event rate.
74 + *
75 + * @return the Metrics' Meter for the withdraw requested intents event rate
76 + */
77 + public Meter intentWithdrawRequestedRateMeter();
78 +
79 + /**
80 + * Gets the Metrics' Meter for the withdraw completed intents event rate.
81 + *
82 + * @return the Metrics' Meter for the withdraw completed intents event rate
83 + */
84 + public Meter intentWithdrawnRateMeter();
85 +}
1 +package org.onlab.onos.metrics.intent.cli;
2 +
3 +import java.util.List;
4 +
5 +import com.fasterxml.jackson.databind.JsonNode;
6 +import com.fasterxml.jackson.databind.ObjectMapper;
7 +import com.fasterxml.jackson.databind.node.ArrayNode;
8 +import com.fasterxml.jackson.databind.node.ObjectNode;
9 +import org.apache.karaf.shell.commands.Command;
10 +import org.onlab.onos.cli.AbstractShellCommand;
11 +import org.onlab.onos.metrics.intent.IntentMetricsService;
12 +import org.onlab.onos.net.intent.IntentEvent;
13 +
14 +/**
15 + * Command to show the list of last intent events.
16 + */
17 +@Command(scope = "onos", name = "intents-events",
18 + description = "Lists the last intent events")
19 +public class IntentEventsListCommand extends AbstractShellCommand {
20 +
21 + private static final String FORMAT_EVENT = "Event=%s";
22 +
23 + @Override
24 + protected void execute() {
25 + IntentMetricsService service = get(IntentMetricsService.class);
26 +
27 + if (outputJson()) {
28 + print("%s", json(service.getEvents()));
29 + } else {
30 + for (IntentEvent event : service.getEvents()) {
31 + print(FORMAT_EVENT, event);
32 + print(""); // Extra empty line for clarity
33 + }
34 + }
35 + }
36 +
37 + /**
38 + * Produces a JSON array of intent events.
39 + *
40 + * @param intentEvents the intent events with the data
41 + * @return JSON array with the intent events
42 + */
43 + private JsonNode json(List<IntentEvent> intentEvents) {
44 + ObjectMapper mapper = new ObjectMapper();
45 + ArrayNode result = mapper.createArrayNode();
46 +
47 + for (IntentEvent event : intentEvents) {
48 + result.add(json(mapper, event));
49 + }
50 + return result;
51 + }
52 +
53 + /**
54 + * Produces JSON object for a intent event.
55 + *
56 + * @param mapper the JSON object mapper to use
57 + * @param intentEvent the intent event with the data
58 + * @return JSON object for the intent event
59 + */
60 + private ObjectNode json(ObjectMapper mapper, IntentEvent intentEvent) {
61 + ObjectNode result = mapper.createObjectNode();
62 +
63 + result.put("time", intentEvent.time())
64 + .put("type", intentEvent.type().toString())
65 + .put("event", intentEvent.toString());
66 + return result;
67 + }
68 +}
1 +package org.onlab.onos.metrics.intent.cli;
2 +
3 +import java.io.IOException;
4 +import java.util.concurrent.TimeUnit;
5 +
6 +import com.codahale.metrics.Gauge;
7 +import com.codahale.metrics.Meter;
8 +import com.codahale.metrics.json.MetricsModule;
9 +import com.fasterxml.jackson.core.JsonProcessingException;
10 +import com.fasterxml.jackson.databind.JsonNode;
11 +import com.fasterxml.jackson.databind.ObjectMapper;
12 +import com.fasterxml.jackson.databind.node.ObjectNode;
13 +import org.apache.karaf.shell.commands.Command;
14 +import org.onlab.onos.cli.AbstractShellCommand;
15 +import org.onlab.onos.metrics.intent.IntentMetricsService;
16 +
17 +/**
18 + * Command to show the intent events metrics.
19 + */
20 +@Command(scope = "onos", name = "intents-events-metrics",
21 + description = "Lists intent events metrics")
22 +public class IntentEventsMetricsCommand extends AbstractShellCommand {
23 +
24 + private static final String FORMAT_GAUGE =
25 + "Intent %s Event Timestamp (ms from epoch)=%d";
26 + private static final String FORMAT_METER =
27 + "Intent %s Events count=%d rate(events/sec) mean=%f m1=%f m5=%f m15=%f";
28 +
29 + @Override
30 + protected void execute() {
31 + IntentMetricsService service = get(IntentMetricsService.class);
32 + Gauge<Long> gauge;
33 + Meter meter;
34 +
35 + if (outputJson()) {
36 + ObjectMapper mapper = new ObjectMapper()
37 + .registerModule(new MetricsModule(TimeUnit.SECONDS,
38 + TimeUnit.MILLISECONDS,
39 + false));
40 + ObjectNode result = mapper.createObjectNode();
41 + //
42 + gauge = service.intentSubmittedTimestampEpochMsGauge();
43 + result.put("intentSubmittedTimestamp", json(mapper, gauge));
44 + gauge = service.intentInstalledTimestampEpochMsGauge();
45 + result.put("intentInstalledTimestamp", json(mapper, gauge));
46 + gauge = service.intentWithdrawRequestedTimestampEpochMsGauge();
47 + result.put("intentWithdrawRequestedTimestamp",
48 + json(mapper, gauge));
49 + gauge = service.intentWithdrawnTimestampEpochMsGauge();
50 + result.put("intentWithdrawnTimestamp", json(mapper, gauge));
51 + //
52 + meter = service.intentSubmittedRateMeter();
53 + result.put("intentSubmittedRate", json(mapper, meter));
54 + meter = service.intentInstalledRateMeter();
55 + result.put("intentInstalledRate", json(mapper, meter));
56 + meter = service.intentWithdrawRequestedRateMeter();
57 + result.put("intentWithdrawRequestedRate", json(mapper, meter));
58 + meter = service.intentWithdrawnRateMeter();
59 + result.put("intentWithdrawnRate", json(mapper, meter));
60 + //
61 + print("%s", result);
62 + } else {
63 + gauge = service.intentSubmittedTimestampEpochMsGauge();
64 + printGauge("Submitted", gauge);
65 + gauge = service.intentInstalledTimestampEpochMsGauge();
66 + printGauge("Installed", gauge);
67 + gauge = service.intentWithdrawRequestedTimestampEpochMsGauge();
68 + printGauge("Withdraw Requested", gauge);
69 + gauge = service.intentWithdrawnTimestampEpochMsGauge();
70 + printGauge("Withdrawn", gauge);
71 + //
72 + meter = service.intentSubmittedRateMeter();
73 + printMeter("Submitted", meter);
74 + meter = service.intentInstalledRateMeter();
75 + printMeter("Installed", meter);
76 + meter = service.intentWithdrawRequestedRateMeter();
77 + printMeter("Withdraw Requested", meter);
78 + meter = service.intentWithdrawnRateMeter();
79 + printMeter("Withdrawn", meter);
80 + }
81 + }
82 +
83 + /**
84 + * Produces JSON node for an Object.
85 + *
86 + * @param mapper the JSON object mapper to use
87 + * @param object the Object with the data
88 + * @return JSON node for the Object
89 + */
90 + private JsonNode json(ObjectMapper mapper, Object object) {
91 + //
92 + // NOTE: The API for custom serializers is incomplete,
93 + // hence we have to parse the JSON string to create JsonNode.
94 + //
95 + try {
96 + final String objectJson = mapper.writeValueAsString(object);
97 + JsonNode objectNode = mapper.readTree(objectJson);
98 + return objectNode;
99 + } catch (JsonProcessingException e) {
100 + log.error("Error writing value as JSON string", e);
101 + } catch (IOException e) {
102 + log.error("Error writing value as JSON string", e);
103 + }
104 + return null;
105 + }
106 +
107 + /**
108 + * Prints a Gauge.
109 + *
110 + * @param operationStr the string with the intent operation to print
111 + * @param gauge the Gauge to print
112 + */
113 + private void printGauge(String operationStr, Gauge<Long> gauge) {
114 + print(FORMAT_GAUGE, operationStr, gauge.getValue());
115 + }
116 +
117 + /**
118 + * Prints a Meter.
119 + *
120 + * @param operationStr the string with the intent operation to print
121 + * @param meter the Meter to print
122 + */
123 + private void printMeter(String operationStr, Meter meter) {
124 + TimeUnit rateUnit = TimeUnit.SECONDS;
125 + double rateFactor = rateUnit.toSeconds(1);
126 + print(FORMAT_METER, operationStr, meter.getCount(),
127 + meter.getMeanRate() * rateFactor,
128 + meter.getOneMinuteRate() * rateFactor,
129 + meter.getFiveMinuteRate() * rateFactor,
130 + meter.getFifteenMinuteRate() * rateFactor);
131 + }
132 +}
1 +/**
2 + * ONOS Intent Metrics Application that collects intent-related metrics.
3 + */
4 +package org.onlab.onos.metrics.intent;
1 +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
2 +
3 + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
4 + <command>
5 + <action class="org.onlab.onos.metrics.intent.cli.IntentEventsListCommand"/>
6 + </command>
7 + <command>
8 + <action class="org.onlab.onos.metrics.intent.cli.IntentEventsMetricsCommand"/>
9 + </command>
10 + </command-bundle>
11 +
12 +</blueprint>
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 <description>ONOS metrics applications</description> 17 <description>ONOS metrics applications</description>
18 18
19 <modules> 19 <modules>
20 + <module>intent</module>
20 <module>topology</module> 21 <module>topology</module>
21 </modules> 22 </modules>
22 23
......
...@@ -199,9 +199,16 @@ ...@@ -199,9 +199,16 @@
199 199
200 <feature name="onos-app-metrics" version="1.0.0" 200 <feature name="onos-app-metrics" version="1.0.0"
201 description="ONOS metrics applications"> 201 description="ONOS metrics applications">
202 + <feature>onos-app-metrics-intent</feature>
202 <feature>onos-app-metrics-topology</feature> 203 <feature>onos-app-metrics-topology</feature>
203 </feature> 204 </feature>
204 205
206 + <feature name="onos-app-metrics-intent" version="1.0.0"
207 + description="ONOS intent metrics application">
208 + <feature>onos-api</feature>
209 + <bundle>mvn:org.onlab.onos/onos-app-metrics-intent/1.0.0-SNAPSHOT</bundle>
210 + </feature>
211 +
205 <feature name="onos-app-metrics-topology" version="1.0.0" 212 <feature name="onos-app-metrics-topology" version="1.0.0"
206 description="ONOS topology metrics application"> 213 description="ONOS topology metrics application">
207 <feature>onos-api</feature> 214 <feature>onos-api</feature>
......