Added initial implementation of Topology-related event and
event metrics collector. It can be loaded by one of the following two (new) features: onos-app-metrics, onos-app-metrics-topology After loading the module, it subscribes for topology-related events and keeps the following state: (a) The last 10 events (b) The timestamp of the last event (ms after epoch) as observed by this module (c) The rate of the topology events: count, median rate, average rate over the last 1, 5 or 15 minutes The following CLI commands are added: * onos:topology-events Shows the last 10 topology events * onos:topology-events-metrics Shows the timestamp of the last event, and the rate of the topology events: see (b) and (c) above
Showing
11 changed files
with
473 additions
and
1 deletions
apps/metrics/pom.xml
0 → 100644
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-apps</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-app-metrics</artifactId> | ||
15 | + <packaging>pom</packaging> | ||
16 | + | ||
17 | + <description>ONOS metrics applications</description> | ||
18 | + | ||
19 | + <modules> | ||
20 | + <module>topology</module> | ||
21 | + </modules> | ||
22 | + | ||
23 | + <dependencies> | ||
24 | + <dependency> | ||
25 | + <groupId>org.onlab.onos</groupId> | ||
26 | + <artifactId>onlab-misc</artifactId> | ||
27 | + </dependency> | ||
28 | + | ||
29 | + <dependency> | ||
30 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
31 | + <artifactId>jackson-databind</artifactId> | ||
32 | + </dependency> | ||
33 | + <dependency> | ||
34 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
35 | + <artifactId>jackson-annotations</artifactId> | ||
36 | + </dependency> | ||
37 | + | ||
38 | + </dependencies> | ||
39 | + | ||
40 | +</project> |
apps/metrics/topology/pom.xml
0 → 100644
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-topology</artifactId> | ||
15 | + <packaging>bundle</packaging> | ||
16 | + | ||
17 | + <description>ONOS topology 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.topology; | ||
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.event.Event; | ||
21 | +import org.onlab.onos.net.topology.TopologyEvent; | ||
22 | +import org.onlab.onos.net.topology.TopologyListener; | ||
23 | +import org.onlab.onos.net.topology.TopologyService; | ||
24 | +import org.slf4j.Logger; | ||
25 | + | ||
26 | +/** | ||
27 | + * ONOS Topology Metrics Application that collects topology-related metrics. | ||
28 | + */ | ||
29 | +@Component(immediate = true) | ||
30 | +@Service | ||
31 | +public class TopologyMetrics implements TopologyMetricsService, | ||
32 | + TopologyListener { | ||
33 | + private static final Logger log = getLogger(TopologyMetrics.class); | ||
34 | + | ||
35 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
36 | + protected TopologyService topologyService; | ||
37 | + private LinkedList<TopologyEvent> lastEvents = new LinkedList<>(); | ||
38 | + private static final int LAST_EVENTS_MAX_N = 10; | ||
39 | + | ||
40 | + // | ||
41 | + // Metrics | ||
42 | + // | ||
43 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
44 | + protected MetricsService metricsService; | ||
45 | + // | ||
46 | + private static final String COMPONENT_NAME = "Topology"; | ||
47 | + private static final String FEATURE_NAME = "EventNotification"; | ||
48 | + private static final String GAUGE_NAME = "LastEventTimestamp.EpochMs"; | ||
49 | + private static final String METER_NAME = "EventRate"; | ||
50 | + // | ||
51 | + private MetricsComponent metricsComponent; | ||
52 | + private MetricsFeature metricsFeatureEventNotification; | ||
53 | + // | ||
54 | + // Timestamp of the last Topology event (ms from the Epoch) | ||
55 | + private volatile long lastEventTimestampEpochMs = 0; | ||
56 | + private Gauge<Long> lastEventTimestampEpochMsGauge; | ||
57 | + // Rate of the Topology events published to the Topology listeners | ||
58 | + private Meter eventRateMeter; | ||
59 | + | ||
60 | + @Activate | ||
61 | + protected void activate() { | ||
62 | + clear(); | ||
63 | + registerMetrics(); | ||
64 | + topologyService.addListener(this); | ||
65 | + log.info("ONOS Topology Metrics started."); | ||
66 | + } | ||
67 | + | ||
68 | + @Deactivate | ||
69 | + public void deactivate() { | ||
70 | + topologyService.removeListener(this); | ||
71 | + removeMetrics(); | ||
72 | + clear(); | ||
73 | + log.info("ONOS Topology Metrics stopped."); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public List<TopologyEvent> getEvents() { | ||
78 | + synchronized (lastEvents) { | ||
79 | + return ImmutableList.<TopologyEvent>copyOf(lastEvents); | ||
80 | + } | ||
81 | + } | ||
82 | + | ||
83 | + @Override | ||
84 | + public Gauge<Long> lastEventTimestampEpochMsGauge() { | ||
85 | + return lastEventTimestampEpochMsGauge; | ||
86 | + } | ||
87 | + | ||
88 | + @Override | ||
89 | + public Meter eventRateMeter() { | ||
90 | + return eventRateMeter; | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public void event(TopologyEvent event) { | ||
95 | + lastEventTimestampEpochMs = System.currentTimeMillis(); | ||
96 | + // | ||
97 | + // NOTE: If we want to count each "reason" as a separate event, | ||
98 | + // then we should use 'event.reason().size()' instead of '1' to | ||
99 | + // mark the meter below. | ||
100 | + // | ||
101 | + eventRateMeter.mark(1); | ||
102 | + | ||
103 | + log.debug("Topology Event: time = {} type = {} subject = {}", | ||
104 | + event.time(), event.type(), event.subject()); | ||
105 | + for (Event reason : event.reasons()) { | ||
106 | + log.debug("Topology Event Reason: time = {} type = {} subject = {}", | ||
107 | + reason.time(), reason.type(), reason.subject()); | ||
108 | + } | ||
109 | + | ||
110 | + // | ||
111 | + // Keep only the last N events, where N = LAST_EVENTS_MAX_N | ||
112 | + // | ||
113 | + synchronized (lastEvents) { | ||
114 | + while (lastEvents.size() >= LAST_EVENTS_MAX_N) { | ||
115 | + lastEvents.remove(); | ||
116 | + } | ||
117 | + lastEvents.add(event); | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + /** | ||
122 | + * Clears the internal state. | ||
123 | + */ | ||
124 | + private void clear() { | ||
125 | + lastEventTimestampEpochMs = 0; | ||
126 | + synchronized (lastEvents) { | ||
127 | + lastEvents.clear(); | ||
128 | + } | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * Registers the metrics. | ||
133 | + */ | ||
134 | + private void registerMetrics() { | ||
135 | + metricsComponent = metricsService.registerComponent(COMPONENT_NAME); | ||
136 | + metricsFeatureEventNotification = | ||
137 | + metricsComponent.registerFeature(FEATURE_NAME); | ||
138 | + lastEventTimestampEpochMsGauge = | ||
139 | + metricsService.registerMetric(metricsComponent, | ||
140 | + metricsFeatureEventNotification, | ||
141 | + GAUGE_NAME, | ||
142 | + new Gauge<Long>() { | ||
143 | + @Override | ||
144 | + public Long getValue() { | ||
145 | + return lastEventTimestampEpochMs; | ||
146 | + } | ||
147 | + }); | ||
148 | + eventRateMeter = | ||
149 | + metricsService.createMeter(metricsComponent, | ||
150 | + metricsFeatureEventNotification, | ||
151 | + METER_NAME); | ||
152 | + | ||
153 | + } | ||
154 | + | ||
155 | + /** | ||
156 | + * Removes the metrics. | ||
157 | + */ | ||
158 | + private void removeMetrics() { | ||
159 | + metricsService.removeMetric(metricsComponent, | ||
160 | + metricsFeatureEventNotification, | ||
161 | + GAUGE_NAME); | ||
162 | + metricsService.removeMetric(metricsComponent, | ||
163 | + metricsFeatureEventNotification, | ||
164 | + METER_NAME); | ||
165 | + } | ||
166 | +} |
apps/metrics/topology/src/main/java/org/onlab/onos/metrics/topology/TopologyMetricsService.java
0 → 100644
1 | +package org.onlab.onos.metrics.topology; | ||
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.topology.TopologyEvent; | ||
8 | + | ||
9 | +/** | ||
10 | + * Service interface exported by TopologyMetrics. | ||
11 | + */ | ||
12 | +public interface TopologyMetricsService { | ||
13 | + /** | ||
14 | + * Gets the last saved topology events. | ||
15 | + * | ||
16 | + * @return the last saved topology events. | ||
17 | + */ | ||
18 | + public List<TopologyEvent> getEvents(); | ||
19 | + | ||
20 | + /** | ||
21 | + * Gets the Metrics' Gauge for the last topology event timestamp | ||
22 | + * (ms from the epoch). | ||
23 | + * | ||
24 | + * @return the Metrics' Gauge for the last topology event timestamp | ||
25 | + * (ms from the epoch) | ||
26 | + */ | ||
27 | + public Gauge<Long> lastEventTimestampEpochMsGauge(); | ||
28 | + | ||
29 | + /** | ||
30 | + * Gets the Metrics' Meter for the topology events rate. | ||
31 | + * | ||
32 | + * @return the Metrics' Meter for the topology events rate | ||
33 | + */ | ||
34 | + public Meter eventRateMeter(); | ||
35 | +} |
1 | +package org.onlab.onos.metrics.topology.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.event.Event; | ||
12 | +import org.onlab.onos.metrics.topology.TopologyMetricsService; | ||
13 | +import org.onlab.onos.net.topology.TopologyEvent; | ||
14 | + | ||
15 | +/** | ||
16 | + * Command to show the list of last topology events. | ||
17 | + */ | ||
18 | +@Command(scope = "onos", name = "topology-events", | ||
19 | + description = "Lists the last topology events") | ||
20 | +public class TopologyEventsListCommand extends AbstractShellCommand { | ||
21 | + | ||
22 | + private static final String FORMAT_EVENT = | ||
23 | + "Topology Event time=%d type=%s subject=%s"; | ||
24 | + private static final String FORMAT_REASON = | ||
25 | + " Reason time=%d type=%s subject=%s"; | ||
26 | + | ||
27 | + @Override | ||
28 | + protected void execute() { | ||
29 | + TopologyMetricsService service = get(TopologyMetricsService.class); | ||
30 | + | ||
31 | + if (outputJson()) { | ||
32 | + print("%s", json(service.getEvents())); | ||
33 | + } else { | ||
34 | + for (TopologyEvent event : service.getEvents()) { | ||
35 | + print(FORMAT_EVENT, event.time(), event.type(), | ||
36 | + event.subject()); | ||
37 | + for (Event reason : event.reasons()) { | ||
38 | + print(FORMAT_REASON, reason.time(), reason.type(), | ||
39 | + reason.subject()); | ||
40 | + } | ||
41 | + print(""); // Extra empty line for clarity | ||
42 | + } | ||
43 | + } | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Produces a JSON array of topology events. | ||
48 | + * | ||
49 | + * @param topologyEvents the topology events with the data | ||
50 | + * @return JSON array with the topology events | ||
51 | + */ | ||
52 | + private JsonNode json(List<TopologyEvent> topologyEvents) { | ||
53 | + ObjectMapper mapper = new ObjectMapper(); | ||
54 | + ArrayNode result = mapper.createArrayNode(); | ||
55 | + | ||
56 | + for (TopologyEvent event : topologyEvents) { | ||
57 | + result.add(json(mapper, event)); | ||
58 | + } | ||
59 | + return result; | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Produces JSON object for a topology event. | ||
64 | + * | ||
65 | + * @param mapper the JSON object mapper to use | ||
66 | + * @param topologyEvent the topology event with the data | ||
67 | + * @return JSON object for the topology event | ||
68 | + */ | ||
69 | + private ObjectNode json(ObjectMapper mapper, TopologyEvent topologyEvent) { | ||
70 | + ObjectNode result = mapper.createObjectNode(); | ||
71 | + ArrayNode reasons = mapper.createArrayNode(); | ||
72 | + | ||
73 | + for (Event reason : topologyEvent.reasons()) { | ||
74 | + reasons.add(json(mapper, reason)); | ||
75 | + } | ||
76 | + result.put("time", topologyEvent.time()) | ||
77 | + .put("type", topologyEvent.type().toString()) | ||
78 | + .put("subject", topologyEvent.subject().toString()) | ||
79 | + .put("reasons", reasons); | ||
80 | + return result; | ||
81 | + } | ||
82 | + | ||
83 | + /** | ||
84 | + * Produces JSON object for a generic event. | ||
85 | + * | ||
86 | + * @param event the generic event with the data | ||
87 | + * @return JSON object for the generic event | ||
88 | + */ | ||
89 | + private ObjectNode json(ObjectMapper mapper, Event event) { | ||
90 | + ObjectNode result = mapper.createObjectNode(); | ||
91 | + | ||
92 | + result.put("time", event.time()) | ||
93 | + .put("type", event.type().toString()) | ||
94 | + .put("subject", event.subject().toString()); | ||
95 | + return result; | ||
96 | + } | ||
97 | +} |
1 | +package org.onlab.onos.metrics.topology.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.topology.TopologyMetricsService; | ||
16 | + | ||
17 | +/** | ||
18 | + * Command to show the topology events metrics. | ||
19 | + */ | ||
20 | +@Command(scope = "onos", name = "topology-events-metrics", | ||
21 | + description = "Lists topology events metrics") | ||
22 | +public class TopologyEventsMetricsCommand extends AbstractShellCommand { | ||
23 | + | ||
24 | + private static final String FORMAT_GAUGE = | ||
25 | + "Last Topology Event Timestamp (ms from epoch)=%d"; | ||
26 | + private static final String FORMAT_METER = | ||
27 | + "Topology Events count=%d rate(events/sec) mean=%f m1=%f m5=%f m15=%f"; | ||
28 | + | ||
29 | + @Override | ||
30 | + protected void execute() { | ||
31 | + TopologyMetricsService service = get(TopologyMetricsService.class); | ||
32 | + Gauge<Long> gauge = service.lastEventTimestampEpochMsGauge(); | ||
33 | + Meter meter = service.eventRateMeter(); | ||
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 | + try { | ||
42 | + // | ||
43 | + // NOTE: The API for custom serializers is incomplete, | ||
44 | + // hence we have to parse the JSON string to create JsonNode. | ||
45 | + // | ||
46 | + final String gaugeJson = mapper.writeValueAsString(gauge); | ||
47 | + final String meterJson = mapper.writeValueAsString(meter); | ||
48 | + JsonNode gaugeNode = mapper.readTree(gaugeJson); | ||
49 | + JsonNode meterNode = mapper.readTree(meterJson); | ||
50 | + result.put("lastTopologyEventTimestamp", gaugeNode); | ||
51 | + result.put("listenerEventRate", meterNode); | ||
52 | + } catch (JsonProcessingException e) { | ||
53 | + log.error("Error writing value as JSON string", e); | ||
54 | + } catch (IOException e) { | ||
55 | + log.error("Error writing value as JSON string", e); | ||
56 | + } | ||
57 | + print("%s", result); | ||
58 | + } else { | ||
59 | + TimeUnit rateUnit = TimeUnit.SECONDS; | ||
60 | + double rateFactor = rateUnit.toSeconds(1); | ||
61 | + print(FORMAT_GAUGE, gauge.getValue()); | ||
62 | + print(FORMAT_METER, meter.getCount(), | ||
63 | + meter.getMeanRate() * rateFactor, | ||
64 | + meter.getOneMinuteRate() * rateFactor, | ||
65 | + meter.getFiveMinuteRate() * rateFactor, | ||
66 | + meter.getFifteenMinuteRate() * rateFactor); | ||
67 | + } | ||
68 | + } | ||
69 | +} |
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.topology.cli.TopologyEventsListCommand"/> | ||
6 | + </command> | ||
7 | + <command> | ||
8 | + <action class="org.onlab.onos.metrics.topology.cli.TopologyEventsMetricsCommand"/> | ||
9 | + </command> | ||
10 | + </command-bundle> | ||
11 | + | ||
12 | +</blueprint> |
... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
27 | <module>sdnip</module> | 27 | <module>sdnip</module> |
28 | <module>calendar</module> | 28 | <module>calendar</module> |
29 | <module>optical</module> | 29 | <module>optical</module> |
30 | + <module>metrics</module> | ||
30 | </modules> | 31 | </modules> |
31 | 32 | ||
32 | <properties> | 33 | <properties> | ... | ... |
... | @@ -37,6 +37,7 @@ | ... | @@ -37,6 +37,7 @@ |
37 | 37 | ||
38 | <bundle>mvn:com.hazelcast/hazelcast/3.3</bundle> | 38 | <bundle>mvn:com.hazelcast/hazelcast/3.3</bundle> |
39 | <bundle>mvn:io.dropwizard.metrics/metrics-core/3.1.0</bundle> | 39 | <bundle>mvn:io.dropwizard.metrics/metrics-core/3.1.0</bundle> |
40 | + <bundle>mvn:io.dropwizard.metrics/metrics-json/3.1.0</bundle> | ||
40 | <bundle>mvn:com.eclipsesource.minimal-json/minimal-json/0.9.1</bundle> | 41 | <bundle>mvn:com.eclipsesource.minimal-json/minimal-json/0.9.1</bundle> |
41 | 42 | ||
42 | <bundle>mvn:com.esotericsoftware/kryo/3.0.0</bundle> | 43 | <bundle>mvn:com.esotericsoftware/kryo/3.0.0</bundle> |
... | @@ -183,7 +184,6 @@ | ... | @@ -183,7 +184,6 @@ |
183 | <bundle>mvn:org.onlab.onos/onos-app-optical/1.0.0-SNAPSHOT</bundle> | 184 | <bundle>mvn:org.onlab.onos/onos-app-optical/1.0.0-SNAPSHOT</bundle> |
184 | </feature> | 185 | </feature> |
185 | 186 | ||
186 | - | ||
187 | <feature name="onos-app-sdnip" version="1.0.0" | 187 | <feature name="onos-app-sdnip" version="1.0.0" |
188 | description="SDN-IP peering application"> | 188 | description="SDN-IP peering application"> |
189 | <feature>onos-api</feature> | 189 | <feature>onos-api</feature> |
... | @@ -197,4 +197,15 @@ | ... | @@ -197,4 +197,15 @@ |
197 | <bundle>mvn:org.onlab.onos/onos-app-calendar/1.0.0-SNAPSHOT</bundle> | 197 | <bundle>mvn:org.onlab.onos/onos-app-calendar/1.0.0-SNAPSHOT</bundle> |
198 | </feature> | 198 | </feature> |
199 | 199 | ||
200 | + <feature name="onos-app-metrics" version="1.0.0" | ||
201 | + description="ONOS metrics applications"> | ||
202 | + <feature>onos-app-metrics-topology</feature> | ||
203 | + </feature> | ||
204 | + | ||
205 | + <feature name="onos-app-metrics-topology" version="1.0.0" | ||
206 | + description="ONOS topology metrics application"> | ||
207 | + <feature>onos-api</feature> | ||
208 | + <bundle>mvn:org.onlab.onos/onos-app-metrics-topology/1.0.0-SNAPSHOT</bundle> | ||
209 | + </feature> | ||
210 | + | ||
200 | </features> | 211 | </features> | ... | ... |
... | @@ -53,6 +53,11 @@ | ... | @@ -53,6 +53,11 @@ |
53 | <version>3.1.0</version> | 53 | <version>3.1.0</version> |
54 | </dependency> | 54 | </dependency> |
55 | <dependency> | 55 | <dependency> |
56 | + <groupId>io.dropwizard.metrics</groupId> | ||
57 | + <artifactId>metrics-json</artifactId> | ||
58 | + <version>3.1.0</version> | ||
59 | + </dependency> | ||
60 | + <dependency> | ||
56 | <groupId>org.apache.felix</groupId> | 61 | <groupId>org.apache.felix</groupId> |
57 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 62 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
58 | </dependency> | 63 | </dependency> | ... | ... |
-
Please register or login to post a comment