From dbc30d321bd385e5cd5bce1e6f567ade9ca1aa25 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Tue, 12 Sep 2017 08:22:07 +0200 Subject: HONEYCOMB-392 - Footprint measuring support Change-Id: I079c8ceef84cda43159e1823fe42ad77cdc981e8 Signed-off-by: Jan Srnicek --- infra/footprint/asciidoc/Readme.adoc | 3 + infra/footprint/footprint-api/asciidoc/Readme.adoc | 3 + infra/footprint/footprint-api/pom.xml | 34 ++++++++++ .../footprint-api/src/main/yang/footprint.yang | 28 ++++++++ .../footprint/footprint-impl/asciidoc/Readme.adoc | 19 ++++++ infra/footprint/footprint-impl/pom.xml | 69 ++++++++++++++++++++ .../honeycomb/footprint/FootprintCustomizer.java | 55 ++++++++++++++++ .../io/fd/honeycomb/footprint/FootprintModule.java | 31 +++++++++ .../io/fd/honeycomb/footprint/FootprintReader.java | 33 ++++++++++ .../footprint/FootprintReaderFactory.java | 37 +++++++++++ .../honeycomb/footprint/FootprintReaderImpl.java | 74 ++++++++++++++++++++++ infra/footprint/pom.xml | 35 ++++++++++ infra/minimal-distribution/pom.xml | 8 ++- infra/pom.xml | 1 + 14 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 infra/footprint/asciidoc/Readme.adoc create mode 100644 infra/footprint/footprint-api/asciidoc/Readme.adoc create mode 100644 infra/footprint/footprint-api/pom.xml create mode 100644 infra/footprint/footprint-api/src/main/yang/footprint.yang create mode 100644 infra/footprint/footprint-impl/asciidoc/Readme.adoc create mode 100644 infra/footprint/footprint-impl/pom.xml create mode 100644 infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintCustomizer.java create mode 100644 infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintModule.java create mode 100644 infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReader.java create mode 100644 infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderFactory.java create mode 100644 infra/footprint/footprint-impl/src/main/java/io/fd/honeycomb/footprint/FootprintReaderImpl.java create mode 100644 infra/footprint/pom.xml 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 @@ + + + + + + io.fd.honeycomb.common + api-parent + 1.17.10-SNAPSHOT + ../../../common/api-parent + + 4.0.0 + + io.fd.honeycomb.footprint + api + 1.17.10-SNAPSHOT + ${project.artifactId} + jar + \ 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 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 @@ + + + + + + io.fd.honeycomb.common + impl-parent + 1.17.10-SNAPSHOT + ../../../common/impl-parent + + 4.0.0 + + io.fd.honeycomb.footprint + impl + 1.17.10-SNAPSHOT + ${project.artifactId} + + + + io.fd.honeycomb.footprint + api + ${project.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + io.fd.honeycomb + translate-api + ${project.version} + + + io.fd.honeycomb + translate-spi + ${project.version} + + + io.fd.honeycomb + translate-impl + ${project.version} + + + com.google.inject + guice + + + com.google.inject.extensions + guice-multibindings + + + \ 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 { + + private final FootprintReader footprintReader; + + public FootprintCustomizer(@Nonnull final FootprintReader footprintReader) { + this.footprintReader = footprintReader; + } + + @Nonnull + @Override + public MemoryFootprintStateBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new MemoryFootprintStateBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier 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 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 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 @@ + + + + + + infra-aggregator + io.fd.honeycomb + 1.17.10-SNAPSHOT + + 4.0.0 + + io.fd.honeycomb.footprint + footprint-aggregator + pom + + footprint-api + footprint-impl + + \ 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 @@ -83,5 +84,10 @@ bgp ${project.version} + + io.fd.honeycomb.footprint + impl + ${project.version} + 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 @@ minimal-distribution-core northbound binding-init + footprint -- cgit 1.2.3-korg