[onos-6879] Adding configuration property to node metrics app
Change-Id: I64f7a42c44be7b61ec2db291ed90a02434844041
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
index a122791..12dd649 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
@@ -20,7 +20,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.NodeId;
-import org.onosproject.nodemetrics.NodeCpu;
+import org.onosproject.nodemetrics.NodeCpuUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import java.util.Collection;
@@ -42,19 +42,19 @@
@Override
protected void execute() {
if (nodeId != null) {
- NodeCpu cpu = nodeService.cpu(NodeId.nodeId(nodeId));
+ NodeCpuUsage cpu = nodeService.cpu(NodeId.nodeId(nodeId));
if (Objects.nonNull(cpu)) {
print("CPU usage : %s ", cpu);
} else {
print("Node %s doesn't exists", nodeId);
}
} else {
- Collection<NodeCpu> cpu = nodeService.cpu().values();
+ Collection<NodeCpuUsage> cpu = nodeService.cpu().values();
printCpuUsage(cpu);
}
}
- private void printCpuUsage(Collection<NodeCpu> cpuList) {
+ private void printCpuUsage(Collection<NodeCpuUsage> cpuList) {
cpuList.forEach(cpu -> print("%s", cpu));
}
}
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
similarity index 81%
rename from apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java
rename to apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
index 3c6ec5b..2f18c43 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
@@ -20,7 +20,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.NodeId;
-import org.onosproject.nodemetrics.NodeMemory;
+import org.onosproject.nodemetrics.NodeMemoryUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import java.util.Collection;
@@ -31,7 +31,7 @@
*/
@Command(scope = "onos", name = "node-memory",
description = "Lists all node memory utilization")
-public class ShowNodeMemoryCommand extends AbstractShellCommand {
+public class ShowNodeMemoryUsageCommand extends AbstractShellCommand {
@Argument(index = 0, name = "nodeId", description = "Node identity",
required = false, multiValued = false)
@@ -42,19 +42,19 @@
@Override
protected void execute() {
if (nodeId != null) {
- NodeMemory memory = nodeService.memory(NodeId.nodeId(nodeId));
+ NodeMemoryUsage memory = nodeService.memory(NodeId.nodeId(nodeId));
if (Objects.nonNull(memory)) {
print("Memory usage : %s", memory.toString());
} else {
print("Node %s doesn't exists");
}
} else {
- Collection<NodeMemory> memory = nodeService.memory().values();
- printMemory(memory);
+ Collection<NodeMemoryUsage> memory = nodeService.memory().values();
+ printMemoryUsage(memory);
}
}
- private void printMemory(Collection<NodeMemory> memoryList) {
+ private void printMemoryUsage(Collection<NodeMemoryUsage> memoryList) {
memoryList.forEach(memory -> print("%s", memory));
}
}
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
index c91f9d8..812ebb7 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
@@ -18,9 +18,13 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.osgi.service.component.ComponentContext;
+import org.onosproject.cfg.ComponentConfigService;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
@@ -32,9 +36,9 @@
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.nodemetrics.NodeCpu;
+import org.onosproject.nodemetrics.NodeCpuUsage;
import org.onosproject.nodemetrics.NodeDiskUsage;
-import org.onosproject.nodemetrics.NodeMemory;
+import org.onosproject.nodemetrics.NodeMemoryUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import org.onosproject.nodemetrics.Units;
import org.onosproject.store.serializers.KryoNamespaces;
@@ -45,11 +49,15 @@
import org.slf4j.LoggerFactory;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import java.util.Dictionary;
+import static org.onlab.util.Tools.getIntegerProperty;
+
@Service
@Component(immediate = true)
@@ -72,22 +80,30 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LogicalClockService clockService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService cfgService;
+
private ScheduledExecutorService metricsExecutor;
private ScheduledFuture<?> scheduledTask;
private ApplicationId appId;
private NodeId localNodeId;
- private EventuallyConsistentMap<NodeId, NodeMemory> memoryStore;
+ private EventuallyConsistentMap<NodeId, NodeMemoryUsage> memoryStore;
private EventuallyConsistentMap<NodeId, NodeDiskUsage> diskStore;
- private EventuallyConsistentMap<NodeId, NodeCpu> cpuStore;
+ private EventuallyConsistentMap<NodeId, NodeCpuUsage> cpuStore;
private Sigar sigar;
+ @Property(name = "metricPollFrequencySeconds", intValue = DEFAULT_POLL_FREQUENCY_SECONDS,
+ label = "Frequency (in seconds) for polling controller metrics")
+ protected int metricPollFrequencySeconds = DEFAULT_POLL_FREQUENCY_SECONDS;
+
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
appId = coreService
.registerApplication("org.onosproject.nodemetrics");
+ cfgService.registerProperties(getClass());
metricsExecutor = Executors.newSingleThreadScheduledExecutor(
Tools.groupedThreads("nodemetrics/pollingStatics",
"statistics-executor-%d", log));
@@ -95,11 +111,11 @@
localNodeId = clusterService.getLocalNode().id();
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
- .register(NodeMemory.class)
+ .register(NodeMemoryUsage.class)
.register(NodeDiskUsage.class)
- .register(NodeCpu.class)
+ .register(NodeCpuUsage.class)
.register(Units.class);
- memoryStore = storageService.<NodeId, NodeMemory>eventuallyConsistentMapBuilder()
+ memoryStore = storageService.<NodeId, NodeMemoryUsage>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, memory) -> clockService.getTimestamp())
.withName("nodemetrics-memory")
@@ -111,26 +127,50 @@
.withName("nodemetrics-disk")
.build();
- cpuStore = storageService.<NodeId, NodeCpu>eventuallyConsistentMapBuilder()
+ cpuStore = storageService.<NodeId, NodeCpuUsage>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, cpu) -> clockService.getTimestamp())
.withName("nodemetrics-cpu")
.build();
-
- scheduledTask = schedulePolling();
+ modified(context);
sigar = new Sigar();
pollMetrics();
}
@Deactivate
public void deactivate() {
+ cfgService.unregisterProperties(getClass(), false);
scheduledTask.cancel(true);
metricsExecutor.shutdown();
sigar.close();
}
+ @Modified
+ public void modified(ComponentContext context) {
+ if (context == null) {
+ log.info("No component configuration");
+ return;
+ }
+
+ Dictionary<?, ?> properties = context.getProperties();
+ int newPollFrequency = getNewPollFrequency(properties);
+ //First time call to this modified method is when app activates
+ if (Objects.isNull(scheduledTask)) {
+ metricPollFrequencySeconds = newPollFrequency;
+ scheduledTask = schedulePolling();
+ } else {
+ if (newPollFrequency != metricPollFrequencySeconds) {
+ metricPollFrequencySeconds = newPollFrequency;
+ //stops the old scheduled task
+ scheduledTask.cancel(true);
+ //schedules new task at the new polling rate
+ scheduledTask = schedulePolling();
+ }
+ }
+ }
+
@Override
- public Map<NodeId, NodeMemory> memory() {
+ public Map<NodeId, NodeMemoryUsage> memory() {
return this.ecToMap(memoryStore);
}
@@ -140,12 +180,12 @@
}
@Override
- public Map<NodeId, NodeCpu> cpu() {
+ public Map<NodeId, NodeCpuUsage> cpu() {
return this.ecToMap(cpuStore);
}
@Override
- public NodeMemory memory(NodeId nodeid) {
+ public NodeMemoryUsage memory(NodeId nodeid) {
return memoryStore.get(nodeid);
}
@@ -155,14 +195,26 @@
}
@Override
- public NodeCpu cpu(NodeId nodeid) {
+ public NodeCpuUsage cpu(NodeId nodeid) {
return cpuStore.get(nodeid);
}
private ScheduledFuture schedulePolling() {
return metricsExecutor.scheduleAtFixedRate(this::pollMetrics,
- DEFAULT_POLL_FREQUENCY_SECONDS / 4,
- DEFAULT_POLL_FREQUENCY_SECONDS, TimeUnit.SECONDS);
+ metricPollFrequencySeconds / 4,
+ metricPollFrequencySeconds, TimeUnit.SECONDS);
+ }
+
+ private int getNewPollFrequency(Dictionary<?, ?> properties) {
+ int newPollFrequency;
+ try {
+ newPollFrequency = getIntegerProperty(properties, "metricPollFrequencySeconds");
+ //String s = getIntegerProperty(properties, "metricPollFrequencySeconds");
+ //newPollFrequency = isNullOrEmpty(s) ? pollFrequency : Integer.parseInt(s.trim());
+ } catch (NumberFormatException | ClassCastException e) {
+ newPollFrequency = DEFAULT_POLL_FREQUENCY_SECONDS;
+ }
+ return newPollFrequency;
}
private <K, V> Map<K, V> ecToMap(EventuallyConsistentMap<K, V> ecMap) {
@@ -170,16 +222,17 @@
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
+
private void pollMetrics() {
try {
CpuPerc cpu = sigar.getCpuPerc();
Mem mem = sigar.getMem();
FileSystemUsage disk = sigar.getFileSystemUsage(SLASH);
- NodeMemory memoryNode = new NodeMemory.Builder().free(mem.getFree())
+ NodeMemoryUsage memoryNode = new NodeMemoryUsage.Builder().free(mem.getFree())
.used(mem.getUsed()).total(mem.getTotal()).withUnit(Units.BYTES)
.withNode(localNodeId).build();
- NodeCpu cpuNode = new NodeCpu.Builder().withNode(localNodeId)
+ NodeCpuUsage cpuNode = new NodeCpuUsage.Builder().withNode(localNodeId)
.usage(cpu.getCombined() * PERCENTAGE_MULTIPLIER).build();
NodeDiskUsage diskNode = new NodeDiskUsage.Builder().withNode(localNodeId)
.free(disk.getFree()).used(disk.getUsed()).withUnit(Units.KBYTES)