From 3061a19e7d34d3961134188d33ef0f1c28228076 Mon Sep 17 00:00:00 2001 From: Mateusz Rzeszutek Date: Thu, 1 Dec 2022 13:18:44 +0100 Subject: [PATCH] removed some more stuff --- .../jvmmetrics/JvmMetricsInstaller.java | 23 +- .../jvmmetrics/otel/OtelJvmGcMetrics.java | 207 ------------------ .../otel/OtelJvmHeapPressureMetrics.java | 112 ---------- .../jvmmetrics/OtelJvmMetricsTest.java | 4 - 4 files changed, 19 insertions(+), 327 deletions(-) delete mode 100644 instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmGcMetrics.java delete mode 100644 instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmHeapPressureMetrics.java diff --git a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/JvmMetricsInstaller.java b/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/JvmMetricsInstaller.java index 8c5d4c36d..a9e0d1036 100644 --- a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/JvmMetricsInstaller.java +++ b/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/JvmMetricsInstaller.java @@ -25,8 +25,6 @@ import com.splunk.opentelemetry.instrumentation.jvmmetrics.micrometer.MicrometerGcMemoryMetrics; import com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.OtelAllocatedMemoryMetrics; import com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.OtelGcMemoryMetrics; -import com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.OtelJvmGcMetrics; -import com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.OtelJvmHeapPressureMetrics; import com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.OtelJvmThreadMetrics; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; @@ -59,8 +57,25 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetr new JvmThreadMetrics().bindTo(Metrics.globalRegistry); } if (useOtelMetrics(metricsImplementation)) { - new OtelJvmGcMetrics().install(); - new OtelJvmHeapPressureMetrics().install(); + // gc metrics were removed: + // runtime.jvm.gc.concurrent.phase.time is replaced by OTel + // process.runtime.jvm.gc.duration{gc=} + // runtime.jvm.gc.pause is replaced by OTel + // process.runtime.jvm.gc.duration{gc!=} + // runtime.jvm.gc.max.data.size is replaced by OTel + // process.runtime.jvm.memory.limit{pool=} + // runtime.jvm.gc.live.data.size is replaced by OTel + // process.runtime.jvm.memory.usage_after_last_gc{pool=} + // runtime.jvm.gc.memory.allocated is replaced by memory profiling metric + // process.runtime.jvm.memory.allocated + // runtime.jvm.gc.memory.promoted is removed with no direct replacement + + // heap pressure metrics were removed: + // runtime.jvm.memory.usage.after.gc is replaced by OTel + // process.runtime.jvm.memory.usage_after_last_gc{pool=,type=heap} / + // process.runtime.jvm.memory.limit{pool=,type=heap} + // runtime.jvm.gc.overhead is something that should to done in a dashboard, not here + new OtelJvmThreadMetrics().install(); } diff --git a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmGcMetrics.java b/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmGcMetrics.java deleted file mode 100644 index 94d4b4721..000000000 --- a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmGcMetrics.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * 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. - */ - -// Includes work from: -/* - * Copyright 2019 VMware, Inc. - * - * 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 - * - * https://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 com.splunk.opentelemetry.instrumentation.jvmmetrics.otel; - -import static com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.JvmMemory.isAllocationPool; -import static com.splunk.opentelemetry.instrumentation.jvmmetrics.otel.JvmMemory.isLongLivedPool; - -import com.sun.management.GarbageCollectionNotificationInfo; -import com.sun.management.GcInfo; -import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.Meter; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryUsage; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; -import javax.management.Notification; -import javax.management.NotificationEmitter; -import javax.management.NotificationListener; -import javax.management.openmbean.CompositeData; - -public class OtelJvmGcMetrics { - private static final Logger logger = Logger.getLogger(OtelJvmGcMetrics.class.getName()); - - private final boolean managementExtensionsPresent = isManagementExtensionsPresent(); - private final boolean isGenerationalGc = isGenerationalGcConfigured(); - private String allocationPoolName; - private final Set longLivedPoolNames = new HashSet<>(); - - private LongCounter allocatedBytes; - private LongCounter promotedBytes; - private AtomicLong allocationPoolSizeAfter; - - public OtelJvmGcMetrics() { - for (MemoryPoolMXBean mbean : ManagementFactory.getMemoryPoolMXBeans()) { - String name = mbean.getName(); - if (isAllocationPool(name)) { - allocationPoolName = name; - } - if (isLongLivedPool(name)) { - longLivedPoolNames.add(name); - } - } - } - - public void install() { - if (!this.managementExtensionsPresent) { - return; - } - - Meter meter = OtelMeterProvider.get(); - - GcMetricsNotificationListener gcNotificationListener = new GcMetricsNotificationListener(); - - // runtime.jvm.gc.max.data.size is replaced by OTel - // process.runtime.jvm.memory.limit{pool=} - - // runtime.jvm.gc.live.data.size is replaced by OTel - // process.runtime.jvm.memory.usage_after_last_gc{pool=} - - allocatedBytes = - meter - .counterBuilder("runtime.jvm.gc.memory.allocated") - .setUnit("bytes") - .setDescription("Size of long-lived heap memory pool after reclamation.") - .build(); - - if (isGenerationalGc) { - promotedBytes = - meter - .counterBuilder("runtime.jvm.gc.memory.promoted") - .setUnit("bytes") - .setDescription( - "Count of positive increases in the size of the old generation memory pool before GC to after GC.") - .build(); - } - - allocationPoolSizeAfter = new AtomicLong(0L); - - for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { - if (!(gcBean instanceof NotificationEmitter)) { - continue; - } - NotificationEmitter notificationEmitter = (NotificationEmitter) gcBean; - notificationEmitter.addNotificationListener( - gcNotificationListener, - notification -> - notification - .getType() - .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION), - null); - } - } - - private class GcMetricsNotificationListener implements NotificationListener { - - // runtime.jvm.gc.concurrent.phase.time is replaced by OTel - // process.runtime.jvm.gc.duration{gc=} - // runtime.jvm.gc.pause is replaced by OTel - // process.runtime.jvm.gc.duration{gc!=} - - @Override - public void handleNotification(Notification notification, Object ref) { - CompositeData cd = (CompositeData) notification.getUserData(); - GarbageCollectionNotificationInfo notificationInfo = - GarbageCollectionNotificationInfo.from(cd); - - GcInfo gcInfo = notificationInfo.getGcInfo(); - final Map before = gcInfo.getMemoryUsageBeforeGc(); - final Map after = gcInfo.getMemoryUsageAfterGc(); - - countPoolSizeDelta(before, after); - - final long longLivedBefore = - longLivedPoolNames.stream().mapToLong(pool -> before.get(pool).getUsed()).sum(); - final long longLivedAfter = - longLivedPoolNames.stream().mapToLong(pool -> after.get(pool).getUsed()).sum(); - if (isGenerationalGc) { - final long delta = longLivedAfter - longLivedBefore; - if (delta > 0L) { - promotedBytes.add(delta); - } - } - } - - private void countPoolSizeDelta( - Map before, Map after) { - if (allocationPoolName == null) { - return; - } - final long beforeBytes = before.get(allocationPoolName).getUsed(); - final long afterBytes = after.get(allocationPoolName).getUsed(); - final long delta = beforeBytes - allocationPoolSizeAfter.get(); - allocationPoolSizeAfter.set(afterBytes); - if (delta > 0L) { - allocatedBytes.add(delta); - } - } - } - - private boolean isGenerationalGcConfigured() { - return ManagementFactory.getMemoryPoolMXBeans().stream() - .filter(JvmMemory::isHeap) - .map(MemoryPoolMXBean::getName) - .filter(name -> !name.contains("tenured")) - .count() - > 1; - } - - private static boolean isManagementExtensionsPresent() { - if (ManagementFactory.getMemoryPoolMXBeans().isEmpty()) { - // Substrate VM, for example, doesn't provide or support these beans (yet) - logger.warning( - "GC notifications will not be available because MemoryPoolMXBeans are not provided by the JVM"); - return false; - } - - try { - Class.forName( - "com.sun.management.GarbageCollectionNotificationInfo", - false, - MemoryPoolMXBean.class.getClassLoader()); - return true; - } catch (Throwable e) { - // We are operating in a JVM without access to this level of detail - logger.warning( - "GC notifications will not be available because " - + "com.sun.management.GarbageCollectionNotificationInfo is not present"); - return false; - } - } -} diff --git a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmHeapPressureMetrics.java b/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmHeapPressureMetrics.java deleted file mode 100644 index 3d22cfce7..000000000 --- a/instrumentation/jvm-metrics/src/main/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/otel/OtelJvmHeapPressureMetrics.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * 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. - */ - -// Includes work from: -/* - * Copyright 2019 VMware, Inc. - * - * 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 - * - * https://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 com.splunk.opentelemetry.instrumentation.jvmmetrics.otel; - -import com.sun.management.GarbageCollectionNotificationInfo; -import com.sun.management.GcInfo; -import io.opentelemetry.api.metrics.Meter; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.time.Duration; -import javax.management.NotificationEmitter; -import javax.management.NotificationListener; -import javax.management.openmbean.CompositeData; - -public class OtelJvmHeapPressureMetrics { - private final long startOfMonitoring = System.nanoTime(); - private final Duration lookback; - private final TimeWindowSum gcPauseSum; - - public OtelJvmHeapPressureMetrics() { - this(Duration.ofMinutes(5), Duration.ofMinutes(1)); - } - - private OtelJvmHeapPressureMetrics(Duration lookback, Duration testEvery) { - this.lookback = lookback; - this.gcPauseSum = - new TimeWindowSum((int) lookback.dividedBy(testEvery.toMillis()).toMillis(), testEvery); - - monitor(); - } - - public void install() { - Meter meter = OtelMeterProvider.get(); - - // runtime.jvm.memory.usage.after.gc is replaced by OTel - // process.runtime.jvm.memory.usage_after_last_gc{pool=,type=heap} / - // process.runtime.jvm.memory.limit{pool=,type=heap} - - meter - .gaugeBuilder("runtime.jvm.gc.overhead") - .setUnit("percent") - .setDescription( - "An approximation of the percent of CPU time used by GC activities over the last lookback period or since monitoring began, whichever is shorter, in the range [0..1].") - .buildWithCallback( - measurement -> { - double overIntervalMillis = - Math.min(System.nanoTime() - startOfMonitoring, lookback.toNanos()) / 1e6; - measurement.record(gcPauseSum.poll() / overIntervalMillis); - }); - } - - private void monitor() { - for (GarbageCollectorMXBean mbean : ManagementFactory.getGarbageCollectorMXBeans()) { - if (!(mbean instanceof NotificationEmitter)) { - continue; - } - NotificationListener notificationListener = - (notification, ref) -> { - CompositeData cd = (CompositeData) notification.getUserData(); - GarbageCollectionNotificationInfo notificationInfo = - GarbageCollectionNotificationInfo.from(cd); - - String gcCause = notificationInfo.getGcCause(); - GcInfo gcInfo = notificationInfo.getGcInfo(); - long duration = gcInfo.getDuration(); - - if (!JvmMemory.isConcurrentPhase(gcCause, notificationInfo.getGcName())) { - gcPauseSum.record(duration); - } - }; - NotificationEmitter notificationEmitter = (NotificationEmitter) mbean; - notificationEmitter.addNotificationListener( - notificationListener, - notification -> - notification - .getType() - .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION), - null); - } - } -} diff --git a/instrumentation/jvm-metrics/src/test/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/OtelJvmMetricsTest.java b/instrumentation/jvm-metrics/src/test/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/OtelJvmMetricsTest.java index d022f3306..64c92dcfc 100644 --- a/instrumentation/jvm-metrics/src/test/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/OtelJvmMetricsTest.java +++ b/instrumentation/jvm-metrics/src/test/java/com/splunk/opentelemetry/instrumentation/jvmmetrics/OtelJvmMetricsTest.java @@ -44,10 +44,6 @@ void shouldRegisterOtelJvmMeters() { } System.gc(); - // GC metrics - assertOtelMetricPresent("runtime.jvm.gc.memory.allocated"); - // GC pressure metrics - assertOtelMetricPresent("runtime.jvm.gc.overhead"); // thread metrics assertOtelMetricPresent("runtime.jvm.threads.states"); // allocated memory metrics