[ONOS-6879] Adding Controller Metrics Application, To retrive memory, Disk and CPU usage for all controller

Change-Id: I5976f0194555c1c3c42d6b6d09c468d6dfc983ff
This commit is contained in:
kdarapu 2018-05-10 12:46:32 +05:30 committed by Andrea Campanella
parent be348a3799
commit 97843dcedf
24 changed files with 1451 additions and 1 deletions

17
apps/nodemetrics/BUCK Normal file
View File

@ -0,0 +1,17 @@
BUNDLES = [
'//apps/nodemetrics/api:onos-apps-nodemetrics-api',
'//apps/nodemetrics/mgr:onos-apps-nodemetrics-mgr',
]
onos_app(
app_name = 'org.onosproject.nodemetrics',
title = 'Controller Monitor Application',
description = '1.Nodemetrics Application uses, sigar library to fetch Controller information.'+
'2. The Sigar library uses Native libraries and currently It supports Windows, Linux and MacOs platform.'+
'3. The Native libraries like .so, .dll and .dylib are packed as jar along with sigar libs.'+
'4. If the Native libraries are corrupted because of any reason,'+
'so, the controller is vulnerable to crash of the entire JVM',
category = 'Utility',
url = 'http://samsung.com',
included_bundles = BUNDLES
)

View File

@ -0,0 +1,9 @@
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:sigar',
]
osgi_jar_with_tests(
deps = COMPILE_DEPS,
)

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018 Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps-nodemetrics</artifactId>
<version>1.14.0-SNAPSHOT</version>
</parent>
<artifactId>onos-apps-nodemetrics-api</artifactId>
<packaging>bundle</packaging>
<description>ONOS Nodemetrics API</description>
<url>http://onosproject.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<onos.version>${project.version}</onos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-srcdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
</configuration>
</plugin>
<plugin>
<groupId>org.onosproject</groupId>
<artifactId>onos-maven-plugin</artifactId>
<executions>
<execution>
<id>cfg</id>
<phase>generate-resources</phase>
<goals>
<goal>cfg</goal>
</goals>
</execution>
<execution>
<id>swagger</id>
<phase>generate-sources</phase>
<goals>
<goal>swagger</goal>
</goals>
</execution>
<execution>
<id>app</id>
<phase>package</phase>
<goals>
<goal>app</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,112 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics;
import com.google.common.base.MoreObjects;
import org.onosproject.cluster.NodeId;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents CPU usage info of Cluster controllers.
*/
public final class NodeCpu {
private final NodeId node;
private final double usage;
private NodeCpu(final NodeId node, final Double usage) {
this.node = node;
this.usage = usage;
}
/**
* Overall usage of CPU includes combined usage of
* (user,sys,nice,idle,wait,irq,softIrq and stolen) etc.
* @return usage is overall usage of CPU for the Specific Node.
*/
public double usage() {
return usage;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("node", this.node)
.add("usage", String.format("%.2f%s", this.usage, "%"))
.toString();
}
@Override
public int hashCode() {
return Objects.hash(node, usage);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final NodeCpu other = (NodeCpu) obj;
return Objects.equals(this.node, other.node)
&& Objects.equals(this.usage, other.usage);
}
/**
* Builder for the DefaultNodeCpu object.
*/
public static final class Builder {
/**
* Builds the DefaultNodeCpu.
**/
private NodeId node;
private Double usage;
/**
* Sets the DefaultNodeCpu usage from Library.
*
* @param usage of CPU
* @return self for chaining
*/
public Builder usage(final Double usage) {
this.usage = usage;
return this;
}
/**
* Sets the new DefaultNodeCpu controller node id.
*
* @param node the nodeId
* @return self for chaining
*/
public Builder withNode(final NodeId node) {
this.node = node;
return this;
}
public NodeCpu build() {
checkNotNull(node, "Must specify an node id");
checkNotNull(usage, "Must specify a usage");
return new NodeCpu(node, usage);
}
}
}

View File

@ -0,0 +1,207 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics;
import com.google.common.base.MoreObjects;
import org.onosproject.cluster.NodeId;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents Disk usage of Cluster controllers.
*/
public final class NodeDiskUsage {
private final NodeId node;
private final long free;
private final long used;
private final long total;
private final Units units;
private final double usage;
private static final double PERCENTAGE_MULTIPLIER = 100.0;
private NodeDiskUsage(final NodeId node, final Long free,
final Long used, final Long total, final Units units,
final Double usage) {
this.node = node;
this.free = free;
this.used = used;
this.total = total;
this.units = units;
this.usage = usage;
}
/**
* @return free disk space available available for the specific nodeId.
*/
public long free() {
return free;
}
/**
* @return used disk space used for the specific nodeId.
*/
public long used() {
return used;
}
/**
* @return total disk space for the specific nodeId..
*/
public long total() {
return total;
}
/**
* @return units in Kbs /Mbs/ Gbs.
*/
public Units units() {
return units;
}
/**
* Percentage of Disk usage is calculated from Used,
* Available and Total Disk available in Specific Node.
* @return usage overall usage of Disk space for the specific nodeId.
*/
public double usage() {
return usage;
}
@Override
public int hashCode() {
return Objects.hash(node, free, used, total, units, usage);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("node", this.node)
.add("free", this.free)
.add("used", this.used)
.add("total", this.total)
.add("units", this.units)
.add("usage", this.usage + "%")
.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
NodeDiskUsage other = (NodeDiskUsage) obj;
return Objects.equals(this.node, other.node)
&& Objects.equals(this.free, other.free)
&& Objects.equals(this.used, other.used)
&& Objects.equals(this.total, other.total)
&& Objects.equals(this.units, other.units)
&& Objects.equals(this.usage, other.usage);
}
/**
* Builder for the NodeDiskusage object.
*/
public static final class Builder {
/**
* Builds the NodeDiskusage.
**/
private NodeId node;
private Units unit;
private Long free;
private Long used;
private Long total;
/**
* Sets the new NodeDiskusage controller nodeid.
*
* @param node the nodeId
* @return self for chaining
*/
public Builder withNode(final NodeId node) {
this.node = node;
return this;
}
/**
* Sets the new NodeDiskusage Disk size units(bytes, Kbs, Mbs,
* Gbs).
*
* @param unit the units
* @return self for chaining
*/
public Builder withUnit(final Units unit) {
this.unit = unit;
return this;
}
/**
* Sets the new NodeDiskusage controller free space.
*
* @param free the free space
* @return self for chaining
*/
public Builder free(final Long free) {
this.free = free;
return this;
}
/**
* Sets the new NodeDiskusage controller used space.
*
* @param used the used space
* @return self for chaining
*/
public Builder used(final Long used) {
this.used = used;
return this;
}
/**
* Sets the new NodeDiskusage controller total disk.
*
* @param total the total disk space
* @return self for chaining
*/
public Builder total(final Long total) {
this.total = total;
return this;
}
public NodeDiskUsage build() {
checkNotNull(node, "Must specify an node id");
checkNotNull(unit, "Must specify a unit");
checkNotNull(used, "Must specify a used Diskspace");
checkNotNull(free, "Must specify a free Diskspace");
checkNotNull(total, "Must specify a total Diskspace");
double usage = used * PERCENTAGE_MULTIPLIER / total;
return new NodeDiskUsage(node, free, used, total, unit, usage);
}
}
}

View File

@ -0,0 +1,206 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics;
import com.google.common.base.MoreObjects;
import org.onosproject.cluster.NodeId;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents Memory usage of Cluster controllers.
*/
public final class NodeMemory {
private final NodeId node;
private final Units units;
private final long free;
private final long used;
private final long total;
private final double usage;
private static final double PERCENTAGE_MULTIPLIER = 100.0;
private NodeMemory(final NodeId node, final Units units,
final Long free, final Long used, final Long total,
final Double usage) {
this.node = node;
this.units = units;
this.free = free;
this.used = used;
this.total = total;
this.usage = usage;
}
/**
* @return free memory available for the specific nodeId.
*/
public long free() {
return free;
}
/**
* @return used memory for the specific nodeId..
*/
public long used() {
return used;
}
/**
* @return total memory for the specific nodeId..
*/
public long total() {
return total;
}
/**
* @return memory in Kbs / Mbs etc.
*/
public Units units() {
return units;
}
/**
* Percentage of Memory usage is calculated from Used, Available and Total Memory.
* @return usage overall usage of memory in percentage for the specific node.
*/
public double usage() {
return usage;
}
@Override
public int hashCode() {
return Objects.hash(node, free, used, total, units, usage);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("node", this.node)
.add("free", this.free)
.add("used", this.used)
.add("total", this.total)
.add("units", this.units.toString())
.add("usage", this.usage + "%")
.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
NodeMemory other = (NodeMemory) obj;
return Objects.equals(this.node, other.node)
&& Objects.equals(this.free, other.free)
&& Objects.equals(this.used, other.used)
&& Objects.equals(this.total, other.total)
&& Objects.equals(this.units, other.units)
&& Objects.equals(this.usage, other.usage);
}
/**
* Builder for the DefaultNodeMemory object.
*/
public static final class Builder {
/**
* Builds the DefaultNodeMemory.
**/
private NodeId node;
private Units unit;
private Long free;
private Long used;
private Long total;
/**
* Sets the new DefaultNodeMemory controller nodeId.
*
* @param node nodeId
* @return self for chaining
*/
public Builder withNode(final NodeId node) {
this.node = node;
return this;
}
/**
* Sets the new DefaultNodeMemory Disk size units(bytes, Kbs, Mbs, Gbs).
*
* @param unit units
* @return self for chaining
*/
public Builder withUnit(final Units unit) {
this.unit = unit;
return this;
}
/**
* Sets the new DefaultNodeMemory controller free space.
*
* @param free free space
* @return self for chaining
*/
public Builder free(final Long free) {
this.free = free;
return this;
}
/**
* Sets the new DefaultNodeMemory controller used space.
*
* @param used used space
* @return self for chaining
*/
public Builder used(final Long used) {
this.used = used;
return this;
}
/**
* Sets the new DefaultNodeMemory controller total disk.
*
* @param total the total disk space
* @return self for chaining
*/
public Builder total(final Long total) {
this.total = total;
return this;
}
public NodeMemory build() {
checkNotNull(node, "Must specify an node id");
checkNotNull(unit, "Must specify a unit");
checkNotNull(used, "Must specify a used Diskspace");
checkNotNull(free, "Must specify a free Diskspace");
checkNotNull(total, "Must specify a total Diskspace");
double usage = used * PERCENTAGE_MULTIPLIER / total;
return new NodeMemory(node, unit, free, used, total, usage);
}
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics;
import org.onosproject.cluster.NodeId;
import java.util.Map;
/**
* Nodemetrics Application is to fetch Controller Resource metrics.
* The Control Resource metrics includes Memory,
* CPU usage and Disk usage of All the cluster nodes.
*/
public interface NodeMetricsService {
/**
* Returns may memory information of all Cluster nodes.
* @return map
*/
Map<NodeId, NodeMemory> memory();
/**
* Returns may disk information of all Cluster nodes.
* @return map
*/
Map<NodeId, NodeDiskUsage> disk();
/**
* Returns may CPU information of all Cluster nodes.
* @return map object, NodeId as key and NodeCpu information as value.
*/
Map<NodeId, NodeCpu> cpu();
/**
* Get the memory information of Specific Cluster node.
* @param nodeid to get Memory information of that respective cluster node.
* @return Nodememory object.
*/
NodeMemory memory(NodeId nodeid);
/**
* Get the disk information of Specific Cluster node.
* @param nodeid to get disk information of that respective cluster node.
* @return NodeDiskUsage object.
*/
NodeDiskUsage disk(NodeId nodeid);
/**
* Get the CPU information of Specific Cluster node.
* @param nodeid to get CPU information of that respective cluster node.
* @return NodeCpu object.
*/
NodeCpu cpu(NodeId nodeid);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics;
public enum Units {
/**
* Units for Memory and Disk.
*/
BYTES("bytes"), KBYTES("Kbs"), MBYTES("Mbs"), GBYTES("Gbs");
private final String units;
Units(String units) {
this.units = units;
}
/**
* Returns units for Memory and Diskusage.
* @return units for Memory and Diskusage
*/
public String units() {
return units;
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Module to fetch Node Metrics.
*/
package org.onosproject.nodemetrics;

13
apps/nodemetrics/mgr/BUCK Normal file
View File

@ -0,0 +1,13 @@
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:sigar',
'//lib:org.apache.karaf.shell.console',
'//apps/nodemetrics/api:onos-apps-nodemetrics-api',
'//core/store/serializers:onos-core-serializers',
'//cli:onos-cli',
'//lib:KRYO',
]
osgi_jar_with_tests(
deps = COMPILE_DEPS,
)

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018 Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps-nodemetrics</artifactId>
<version>1.14.0-SNAPSHOT</version>
</parent>
<artifactId>onos-apps-nodemetrics-mgr</artifactId>
<packaging>bundle</packaging>
<description>ONOS nodemetrics API</description>
<url>http://onosproject.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<onos.version>${project.version}</onos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-models-openconfig</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps-nodemetrics-api</artifactId>
<version>1.14.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.knowhowlab.osgi</groupId>
<artifactId>sigar</artifactId>
<version>1.6.5_01</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-serializers</artifactId>
<version>1.14.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>3.0.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-srcdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
</configuration>
</plugin>
<plugin>
<groupId>org.onosproject</groupId>
<artifactId>onos-maven-plugin</artifactId>
<executions>
<execution>
<id>cfg</id>
<phase>generate-resources</phase>
<goals>
<goal>cfg</goal>
</goals>
</execution>
<execution>
<id>swagger</id>
<phase>generate-sources</phase>
<goals>
<goal>swagger</goal>
</goals>
</execution>
<execution>
<id>app</id>
<phase>package</phase>
<goals>
<goal>app</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,61 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics.cli;
import org.apache.karaf.shell.commands.Argument;
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.NodeMetricsService;
import java.util.Collection;
import java.util.Objects;
/**
* Lists cpu usage across nodes.
*/
@Command(scope = "onos", name = "node-cpu",
description = "Lists all node cpu utilization")
public class ShowNodeCpuUsageCommand extends AbstractShellCommand {
@Argument(index = 0, name = "nodeId", description = "Node identity",
required = false, multiValued = false)
String nodeId = null;
private NodeMetricsService nodeService = AbstractShellCommand
.get(NodeMetricsService.class);
@Override
protected void execute() {
if (nodeId != null) {
NodeCpu 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();
printCpuUsage(cpu);
}
}
private void printCpuUsage(Collection<NodeCpu> cpuList) {
cpuList.forEach(cpu -> print("%s", cpu));
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.NodeId;
import org.onosproject.nodemetrics.NodeDiskUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import java.util.Collection;
import java.util.Objects;
/**
* Lists disk usage across nodes.
*/
@Command(scope = "onos", name = "node-disk",
description = "Lists all node disk utilization")
public class ShowNodeDiskUsageCommand extends AbstractShellCommand {
@Argument(index = 0, name = "nodeId", description = "Node identity",
required = false, multiValued = false)
String nodeId = null;
private NodeMetricsService nodeService = AbstractShellCommand
.get(NodeMetricsService.class);
@Override
protected void execute() {
if (nodeId != null) {
NodeDiskUsage disk = nodeService.disk(NodeId.nodeId(nodeId));
if (Objects.nonNull(disk)) {
print("Disk usage : %s", disk);
} else {
print("Node %s doesn't exists", nodeId);
}
} else {
Collection<NodeDiskUsage> disk = nodeService.disk().values();
printDiskUsage(disk);
}
}
private void printDiskUsage(Collection<NodeDiskUsage> diskList) {
diskList.forEach(disk -> print("%s", disk));
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics.cli;
import org.apache.karaf.shell.commands.Argument;
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.NodeMetricsService;
import java.util.Collection;
import java.util.Objects;
/**
* Lists memory usage across nodes.
*/
@Command(scope = "onos", name = "node-memory",
description = "Lists all node memory utilization")
public class ShowNodeMemoryCommand extends AbstractShellCommand {
@Argument(index = 0, name = "nodeId", description = "Node identity",
required = false, multiValued = false)
String nodeId = null;
private NodeMetricsService nodeService = AbstractShellCommand
.get(NodeMetricsService.class);
@Override
protected void execute() {
if (nodeId != null) {
NodeMemory 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);
}
}
private void printMemory(Collection<NodeMemory> memoryList) {
memoryList.forEach(memory -> print("%s", memory));
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Module to fetch Node Metrics using CLI.
*/
package org.onosproject.nodemetrics.cli;

View File

@ -0,0 +1,196 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.nodemetrics.impl;
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.onlab.util.KryoNamespace;
import org.onlab.util.Tools;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.nodemetrics.NodeCpu;
import org.onosproject.nodemetrics.NodeDiskUsage;
import org.onosproject.nodemetrics.NodeMemory;
import org.onosproject.nodemetrics.NodeMetricsService;
import org.onosproject.nodemetrics.Units;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
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;
@Service
@Component(immediate = true)
public class NodeMetricsManager implements NodeMetricsService {
private static final int DEFAULT_POLL_FREQUENCY_SECONDS = 15;
private static final String SLASH = "/";
private static final Double PERCENTAGE_MULTIPLIER = 100.0;
private final Logger log = LoggerFactory
.getLogger(this.getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LogicalClockService clockService;
private ScheduledExecutorService metricsExecutor;
private ScheduledFuture<?> scheduledTask;
private ApplicationId appId;
private NodeId localNodeId;
private EventuallyConsistentMap<NodeId, NodeMemory> memoryStore;
private EventuallyConsistentMap<NodeId, NodeDiskUsage> diskStore;
private EventuallyConsistentMap<NodeId, NodeCpu> cpuStore;
private Sigar sigar;
@Activate
public void activate() {
appId = coreService
.registerApplication("org.onosproject.nodemetrics");
metricsExecutor = Executors.newSingleThreadScheduledExecutor(
Tools.groupedThreads("nodemetrics/pollingStatics",
"statistics-executor-%d", log));
localNodeId = clusterService.getLocalNode().id();
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
.register(NodeMemory.class)
.register(NodeDiskUsage.class)
.register(NodeCpu.class)
.register(Units.class);
memoryStore = storageService.<NodeId, NodeMemory>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, memory) -> clockService.getTimestamp())
.withName("nodemetrics-memory")
.build();
diskStore = storageService.<NodeId, NodeDiskUsage>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, disk) -> clockService.getTimestamp())
.withName("nodemetrics-disk")
.build();
cpuStore = storageService.<NodeId, NodeCpu>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, cpu) -> clockService.getTimestamp())
.withName("nodemetrics-cpu")
.build();
scheduledTask = schedulePolling();
sigar = new Sigar();
pollMetrics();
}
@Deactivate
public void deactivate() {
scheduledTask.cancel(true);
metricsExecutor.shutdown();
sigar.close();
}
@Override
public Map<NodeId, NodeMemory> memory() {
return this.ecToMap(memoryStore);
}
@Override
public Map<NodeId, NodeDiskUsage> disk() {
return this.ecToMap(diskStore);
}
@Override
public Map<NodeId, NodeCpu> cpu() {
return this.ecToMap(cpuStore);
}
@Override
public NodeMemory memory(NodeId nodeid) {
return memoryStore.get(nodeid);
}
@Override
public NodeDiskUsage disk(NodeId nodeid) {
return diskStore.get(nodeid);
}
@Override
public NodeCpu 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);
}
private <K, V> Map<K, V> ecToMap(EventuallyConsistentMap<K, V> ecMap) {
return ecMap.entrySet()
.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())
.used(mem.getUsed()).total(mem.getTotal()).withUnit(Units.BYTES)
.withNode(localNodeId).build();
NodeCpu cpuNode = new NodeCpu.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)
.total(disk.getTotal()).build();
diskStore.put(localNodeId, diskNode);
memoryStore.put(localNodeId, memoryNode);
cpuStore.put(localNodeId, cpuNode);
} catch (SigarException e) {
log.error("Exception occurred ", e);
}
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Module to fetch Node Metrics and its Implementation.
*/
package org.onosproject.nodemetrics.impl;

View File

@ -0,0 +1,34 @@
<!--
~ /*
~ * Copyright 2017-present Open Networking Foundation
~ *
~ * Licensed under the Apache License, Version 2.0 (the "License");
~ * you may not use this file except in compliance with the License.
~ * You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS,
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ * See the License for the specific language governing permissions and
~ * limitations under the License.
~ */
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.nodemetrics.cli.ShowNodeCpuUsageCommand"/>
</command>
<command>
<action class="org.onosproject.nodemetrics.cli.ShowNodeDiskUsageCommand"/>
</command>
<command>
<action class="org.onosproject.nodemetrics.cli.ShowNodeMemoryCommand"/>
</command>
</command-bundle>
</blueprint>

37
apps/nodemetrics/pom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014-present Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.14.0-SNAPSHOT</version>
</parent>
<artifactId>onos-apps-nodemetrics</artifactId>
<packaging>pom</packaging>
<description>ONOS nodemetrics application</description>
<modules>
<module>api</module>
<module>mgr</module>
</modules>
</project>

View File

@ -105,6 +105,7 @@
<module>layout</module>
<module>imr</module>
<module>t3</module>
<module>nodemetrics</module>
</modules>
<properties>

View File

@ -42,6 +42,7 @@ osgi_feature (
'//lib:commons-jxpath', # FIXME: move xpath lib dependency to the right place
'//lib:commons-beanutils', # jxpath dependency
'//lib:jdom', # jxpath dependency
'//lib:sigar',
]
)

View File

@ -1,4 +1,5 @@
# ***** This file was auto-generated at Wed, 16 May 2018 01:37:51 GMT. Do not edit this file manually. *****
# ***** This file was auto-generated at Wed, 9 May 2018 07:17:00 GMT. Do not edit this file manually. *****
# ***** Use onos-lib-gen *****
pass_thru_pom(
@ -1670,3 +1671,12 @@ remote_jar (
visibility = [ 'PUBLIC' ],
)
remote_jar (
name = 'sigar',
out = 'sigar-1.6.5_01.jar',
url = 'mvn:org.knowhowlab.osgi:sigar:jar:1.6.5_01',
sha1 = '58eb4af0dc4a1d331cd7620767216494e2984dea',
maven_coords = 'org.knowhowlab.osgi:sigar:1.6.5_01',
visibility = [ 'PUBLIC' ],
)

View File

@ -286,6 +286,7 @@
"aalto-xml": "mvn:com.fasterxml:aalto-xml:1.0.0",
"stax2-api": "mvn:org.codehaus.woodstox:stax2-api:4.0.0",
"concurrent-hashmap": "mvn:com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.0",
"gnu-idn": "mvn:org.gnu.inet:libidn:1.15"
"gnu-idn": "mvn:org.gnu.inet:libidn:1.15",
"sigar":"mvn:org.knowhowlab.osgi:sigar:1.6.5_01"
}
}

View File

@ -251,6 +251,8 @@ ONOS_APPS = [
'//apps/mcast:onos-apps-mcast-oar',
'//apps/layout:onos-apps-layout-oar',
'//apps/imr:onos-apps-imr-oar',
# nodemetrics application
'//apps/nodemetrics:onos-apps-nodemetrics-oar',
]
PROTOCOL_APPS = [