diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2017-09-12 08:22:07 +0200 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-09-12 06:48:17 +0000 |
commit | dbc30d321bd385e5cd5bce1e6f567ade9ca1aa25 (patch) | |
tree | 80620eb992e8ee12254b8162e369ceee469d07d0 | |
parent | 61ae76644a2d68823aaeabf4c0310c1717f52236 (diff) |
HONEYCOMB-392 - Footprint measuring support
Change-Id: I079c8ceef84cda43159e1823fe42ad77cdc981e8
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
14 files changed, 429 insertions, 1 deletions
diff --git a/infra/footprint/asciidoc/Readme.adoc b/infra/footprint/asciidoc/Readme.adoc new file mode 100644 index 000000000..a64af09cd --- /dev/null +++ b/infra/footprint/asciidoc/Readme.adoc @@ -0,0 +1,3 @@ += footprint-aggregator + +Overview of footprint-aggregator
\ No newline at end of file diff --git a/infra/footprint/footprint-api/asciidoc/Readme.adoc b/infra/footprint/footprint-api/asciidoc/Readme.adoc new file mode 100644 index 000000000..45c884491 --- /dev/null +++ b/infra/footprint/footprint-api/asciidoc/Readme.adoc @@ -0,0 +1,3 @@ += api + +Provides api for reading honeycomb memory footprint.
\ No newline at end of file diff --git a/infra/footprint/footprint-api/pom.xml b/infra/footprint/footprint-api/pom.xml new file mode 100644 index 000000000..cd9347a0d --- /dev/null +++ b/infra/footprint/footprint-api/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2017 Cisco and/or its affiliates. + ~ + ~ 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"> + <parent> + <groupId>io.fd.honeycomb.common</groupId> + <artifactId>api-parent</artifactId> + <version>1.17.10-SNAPSHOT</version> + <relativePath>../../../common/api-parent</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>io.fd.honeycomb.footprint</groupId> + <artifactId>api</artifactId> + <version>1.17.10-SNAPSHOT</version> + <name>${project.artifactId}</name> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/infra/footprint/footprint-api/src/main/yang/footprint.yang b/infra/footprint/footprint-api/src/main/yang/footprint.yang new file mode 100644 index 000000000..680f15c2a --- /dev/null +++ b/infra/footprint/footprint-api/src/main/yang/footprint.yang @@ -0,0 +1,28 @@ +module footprint { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:footprint"; + prefix "footprint"; + + revision "2017-08-30" { + description "HC model for requesting current memory consumption"; + } + + container memory-footprint-state { + config false; + + leaf footprint { + type uint32; + description "Memory footprint in kilobytes. Footprint is parsed as output of ps command, where RSS field is + read. + + RSS is the Resident Set Size and is used to show how much memory is allocated to that process and is in RAM. + It does not include memory that is swapped out. It does include memory from shared libraries + as long as the pages from those libraries are actually in memory. It does include all stack and heap memory."; + } + + leaf pid { + type uint32; + description "Process id of honeycomb"; + } + } +} diff --git a/infra/footprint/footprint-impl/asciidoc/Readme.adoc b/infra/footprint/footprint-impl/asciidoc/Readme.adoc new file mode 100644 index 000000000..79306b52e --- /dev/null +++ b/infra/footprint/footprint-impl/asciidoc/Readme.adoc @@ -0,0 +1,19 @@ += impl + +== To read footprint + +[source,java] +---- +HttpResponse<String> response = Unirest.get("http://localhost:8183/restconf/operational/footprint:memory-footprint-state") + .header("authorization", "Basic YWRtaW46YWRtaW4=") + .header("content-type", "application/json") + .asString(); +---- + +[source,shell] +---- +curl --request GET \ + --url http://localhost:8183/restconf/operational/footprint:memory-footprint-state \ + --header 'authorization: Basic YWRtaW46YWRtaW4=' \ + --header 'content-type: application/json' +----
\ No newline at end of file diff --git a/infra/footprint/footprint-impl/pom.xml b/infra/footprint/footprint-impl/pom.xml new file mode 100644 index 000000000..6649f7f5c --- /dev/null +++ b/infra/footprint/footprint-impl/pom.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2017 Cisco and/or its affiliates. + ~ + ~ 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"> + <parent> + <groupId>io.fd.honeycomb.common</groupId> + <artifactId>impl-parent</artifactId> + <version>1.17.10-SNAPSHOT</version> + <relativePath>../../../common/impl-parent</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>io.fd.honeycomb.footprint</groupId> + <artifactId>impl</artifactId> + <version>1.17.10-SNAPSHOT</version> + <name>${project.artifactId}</name> + + <dependencies> + <dependency> + <groupId>io.fd.honeycomb.footprint</groupId> + <artifactId>api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>io.fd.honeycomb</groupId> + <artifactId>translate-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.fd.honeycomb</groupId> + <artifactId>translate-spi</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.fd.honeycomb</groupId> + <artifactId>translate-impl</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + </dependency> + <dependency> + <groupId>com.google.inject.extensions</groupId> + <artifactId>guice-multibindings</artifactId> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintCustomizer.java b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintCustomizer.java new file mode 100644 index 000000000..6d1db6776 --- /dev/null +++ b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintCustomizer.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.honeycomb.footprint; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.footprint.rev170830.MemoryFootprintState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.footprint.rev170830.MemoryFootprintStateBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class FootprintCustomizer implements ReaderCustomizer<MemoryFootprintState, MemoryFootprintStateBuilder> { + + private final FootprintReader footprintReader; + + public FootprintCustomizer(@Nonnull final FootprintReader footprintReader) { + this.footprintReader = footprintReader; + } + + @Nonnull + @Override + public MemoryFootprintStateBuilder getBuilder(@Nonnull final InstanceIdentifier<MemoryFootprintState> id) { + return new MemoryFootprintStateBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<MemoryFootprintState> id, + @Nonnull final MemoryFootprintStateBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + builder.setFootprint((long) footprintReader.readCurrentFootprint()).setPid((long) footprintReader.getPid()); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, + @Nonnull final MemoryFootprintState readValue) { + //NOOP + } +} diff --git a/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintModule.java b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintModule.java new file mode 100644 index 000000000..6792d71df --- /dev/null +++ b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintModule.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.honeycomb.footprint; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.translate.read.ReaderFactory; + +public class FootprintModule extends AbstractModule { + @Override + protected void configure() { + final Multibinder<ReaderFactory> setBinder = + Multibinder.newSetBinder(binder(), ReaderFactory.class); + setBinder.addBinding().to(FootprintReaderFactory.class); + bind(FootprintReader.class).to(FootprintReaderImpl.class).asEagerSingleton(); + } +} diff --git a/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReader.java b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReader.java new file mode 100644 index 000000000..28e5f77f2 --- /dev/null +++ b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReader.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.honeycomb.footprint; + +/** + * Allows reading of footprint of its own JVM + */ +public interface FootprintReader { + + /** + * @return Nr of kilobytes occupied by this JVM + */ + int readCurrentFootprint(); + + /** + * @return Process id associated with this JVM + */ + int getPid(); +} diff --git a/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderFactory.java b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderFactory.java new file mode 100644 index 000000000..0ff54c8ee --- /dev/null +++ b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.honeycomb.footprint; + +import com.google.inject.Inject; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.footprint.rev170830.MemoryFootprintState; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class FootprintReaderFactory implements ReaderFactory { + + @Inject + private FootprintReader footprintReader; + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + registry.add(new GenericReader(InstanceIdentifier.create(MemoryFootprintState.class), + new FootprintCustomizer(footprintReader))); + } +} diff --git a/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderImpl.java b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderImpl.java new file mode 100644 index 000000000..817c5d4c4 --- /dev/null +++ b/infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.honeycomb.footprint; + +import static java.lang.String.format; + +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class FootprintReaderImpl implements FootprintReader { + + private static final Logger LOG = LoggerFactory.getLogger(FootprintReaderImpl.class); + + private final int pid; + + public FootprintReaderImpl() { + pid = initPID(); + LOG.info("Footprint marker initialized for pid {}", pid); + } + + + private static int initPID() { + final String processName = ManagementFactory.getRuntimeMXBean().getName(); + return Integer.parseInt(processName.substring(0, processName.indexOf("@"))); + } + + @Override + public int readCurrentFootprint() { + try { + final Process process = Runtime.getRuntime().exec(" ps -eo rss,pid"); + + final BufferedInputStream input = new BufferedInputStream(process.getInputStream()); + final String processOut = CharStreams.toString(new InputStreamReader(input, Charsets.UTF_8)); + + final String pidLine = Arrays.stream(processOut.split(System.lineSeparator())) + .skip(1)// skip header + .map(String::trim) + .filter(line -> Integer.parseInt(line.split("\\s+")[1]) == pid) + .findFirst() + .orElseThrow( + () -> new IllegalStateException(format("Unable to find memory stats for pid %s", pid))); + + return Integer.parseInt(pidLine.split(" ")[0]); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Override + public int getPid() { + return pid; + } +} diff --git a/infra/footprint/pom.xml b/infra/footprint/pom.xml new file mode 100644 index 000000000..adb72749e --- /dev/null +++ b/infra/footprint/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2017 Cisco and/or its affiliates. + ~ + ~ 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"> + <parent> + <artifactId>infra-aggregator</artifactId> + <groupId>io.fd.honeycomb</groupId> + <version>1.17.10-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>io.fd.honeycomb.footprint</groupId> + <artifactId>footprint-aggregator</artifactId> + <packaging>pom</packaging> + <modules> + <module>footprint-api</module> + <module>footprint-impl</module> + </modules> +</project>
\ No newline at end of file diff --git a/infra/minimal-distribution/pom.xml b/infra/minimal-distribution/pom.xml index d8d1fc3e4..94e230a6a 100644 --- a/infra/minimal-distribution/pom.xml +++ b/infra/minimal-distribution/pom.xml @@ -43,7 +43,8 @@ io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule, // io.fd.honeycomb.infra.bgp.BgpModule, // io.fd.honeycomb.infra.bgp.BgpReadersModule, - // io.fd.honeycomb.infra.bgp.BgpWritersModule + // io.fd.honeycomb.infra.bgp.BgpWritersModule, + // io.fd.honeycomb.footprint.FootprintModule </distribution.modules> </properties> @@ -83,5 +84,10 @@ <artifactId>bgp</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>io.fd.honeycomb.footprint</groupId> + <artifactId>impl</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> diff --git a/infra/pom.xml b/infra/pom.xml index 040fc93ed..57fcb8fa4 100644 --- a/infra/pom.xml +++ b/infra/pom.xml @@ -51,6 +51,7 @@ <module>minimal-distribution-core</module> <module>northbound</module> <module>binding-init</module> + <module>footprint</module> </modules> <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build --> |