From 128aa0c8cc4b0ab202c112476723ea9a8847a373 Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan Date: Fri, 9 Dec 2022 05:19:29 -0800 Subject: [PATCH 1/6] Update JVM metrics - generate a metric for total Threads started since Jvm start time --- .../core/instrument/binder/jvm/JvmThreadMetrics.java | 5 +++++ .../core/instrument/binder/jvm/JvmThreadMetricsTest.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java index ff8cbae995..5066488949 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java @@ -66,6 +66,11 @@ public void bindTo(MeterRegistry registry) { .description("The current number of live threads including both daemon and non-daemon threads") .baseUnit(BaseUnits.THREADS).register(registry); + Gauge.builder("jvm.threads.started", threadBean, ThreadMXBean::getTotalStartedThreadCount).tags(tags) + .description( + "The total number of threads created and also started since the Java virtual machine started") + .baseUnit(BaseUnits.THREADS).register(registry); + try { threadBean.getAllThreadIds(); for (Thread.State state : Thread.State.values()) { diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java index e55adeab7a..7ae84f17b1 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java @@ -39,6 +39,7 @@ class JvmThreadMetricsTest { void threadMetrics() { MeterRegistry registry = new SimpleMeterRegistry(); new JvmThreadMetrics().bindTo(registry); + double initialThreadCount = registry.get("jvm.threads.started").gauge().value(); assertThat(registry.get("jvm.threads.live").gauge().value()).isGreaterThan(0); assertThat(registry.get("jvm.threads.daemon").gauge().value()).isGreaterThan(0); @@ -51,6 +52,7 @@ void threadMetrics() { createTimedWaitingThread(); assertThat(registry.get("jvm.threads.states").tag("state", "timed-waiting").gauge().value()).isGreaterThan(0); + assertThat(registry.get("jvm.threads.started").gauge().value()).isGreaterThan(initialThreadCount); } @Test From 641022b3b631b90ba73c98a849440a56a3b763cc Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan Date: Mon, 19 Dec 2022 22:50:23 -0800 Subject: [PATCH 2/6] Add gc as a tag for gc metrics - When observing multiple applications(which run on different java versions / use different gc's) having gc has a dimension helps in better understanding the gc metrics. --- .../core/instrument/binder/jvm/JvmGcMetrics.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java index 853d8d5cf6..d611e7975b 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java @@ -180,17 +180,19 @@ public void handleNotification(Notification notification, Object ref) { CompositeData cd = (CompositeData) notification.getUserData(); GarbageCollectionNotificationInfo notificationInfo = GarbageCollectionNotificationInfo.from(cd); + String gcName = notificationInfo.getGcName(); String gcCause = notificationInfo.getGcCause(); String gcAction = notificationInfo.getGcAction(); GcInfo gcInfo = notificationInfo.getGcInfo(); long duration = gcInfo.getDuration(); - if (isConcurrentPhase(gcCause, notificationInfo.getGcName())) { - Timer.builder("jvm.gc.concurrent.phase.time").tags(tags).tags("action", gcAction, "cause", gcCause) + if (isConcurrentPhase(gcCause, gcName)) { + Timer.builder("jvm.gc.concurrent.phase.time").tags(tags) + .tags("action", gcAction, "cause", gcCause, "gc_name", gcName) .description("Time spent in concurrent phase").register(registry) .record(duration, TimeUnit.MILLISECONDS); } else { - Timer.builder("jvm.gc.pause").tags(tags).tags("action", gcAction, "cause", gcCause) + Timer.builder("jvm.gc.pause").tags(tags).tags("action", gcAction, "cause", gcCause, "gc", gcName) .description("Time spent in GC pause").register(registry) .record(duration, TimeUnit.MILLISECONDS); } From 58395593805d15517faf4ed3cb49eaca2b73867a Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan <32874349+lenin-jaganathan@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:37:46 +0530 Subject: [PATCH 3/6] Remove changes to GC Metrics and make threads started as Function Counter. --- .../instrument/binder/jvm/JvmGcMetrics.java | 8 +++----- .../binder/jvm/JvmThreadMetrics.java | 9 +++------ .../binder/jvm/JvmThreadMetricsTest.java | 18 +++++++++--------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java index d611e7975b..853d8d5cf6 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java @@ -180,19 +180,17 @@ public void handleNotification(Notification notification, Object ref) { CompositeData cd = (CompositeData) notification.getUserData(); GarbageCollectionNotificationInfo notificationInfo = GarbageCollectionNotificationInfo.from(cd); - String gcName = notificationInfo.getGcName(); String gcCause = notificationInfo.getGcCause(); String gcAction = notificationInfo.getGcAction(); GcInfo gcInfo = notificationInfo.getGcInfo(); long duration = gcInfo.getDuration(); - if (isConcurrentPhase(gcCause, gcName)) { - Timer.builder("jvm.gc.concurrent.phase.time").tags(tags) - .tags("action", gcAction, "cause", gcCause, "gc_name", gcName) + if (isConcurrentPhase(gcCause, notificationInfo.getGcName())) { + Timer.builder("jvm.gc.concurrent.phase.time").tags(tags).tags("action", gcAction, "cause", gcCause) .description("Time spent in concurrent phase").register(registry) .record(duration, TimeUnit.MILLISECONDS); } else { - Timer.builder("jvm.gc.pause").tags(tags).tags("action", gcAction, "cause", gcCause, "gc", gcName) + Timer.builder("jvm.gc.pause").tags(tags).tags("action", gcAction, "cause", gcCause) .description("Time spent in GC pause").register(registry) .record(duration, TimeUnit.MILLISECONDS); } diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java index 5066488949..3a494a1839 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java @@ -17,10 +17,7 @@ import io.micrometer.common.lang.NonNullApi; import io.micrometer.common.lang.NonNullFields; -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.*; import io.micrometer.core.instrument.binder.BaseUnits; import io.micrometer.core.instrument.binder.MeterBinder; @@ -66,9 +63,9 @@ public void bindTo(MeterRegistry registry) { .description("The current number of live threads including both daemon and non-daemon threads") .baseUnit(BaseUnits.THREADS).register(registry); - Gauge.builder("jvm.threads.started", threadBean, ThreadMXBean::getTotalStartedThreadCount).tags(tags) + FunctionCounter.builder("jvm.threads.started", threadBean, ThreadMXBean::getTotalStartedThreadCount).tags(tags) .description( - "The total number of threads created and also started since the Java virtual machine started") + "The total number of application threads started in the JVM") .baseUnit(BaseUnits.THREADS).register(registry); try { diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java index 7ae84f17b1..0eafad2e78 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetricsTest.java @@ -39,20 +39,20 @@ class JvmThreadMetricsTest { void threadMetrics() { MeterRegistry registry = new SimpleMeterRegistry(); new JvmThreadMetrics().bindTo(registry); - double initialThreadCount = registry.get("jvm.threads.started").gauge().value(); + double initialThreadCount = registry.get("jvm.threads.started").functionCounter().count(); - assertThat(registry.get("jvm.threads.live").gauge().value()).isGreaterThan(0); - assertThat(registry.get("jvm.threads.daemon").gauge().value()).isGreaterThan(0); - assertThat(registry.get("jvm.threads.peak").gauge().value()).isGreaterThan(0); - assertThat(registry.get("jvm.threads.states").tag("state", "runnable").gauge().value()).isGreaterThan(0); + assertThat(registry.get("jvm.threads.live").gauge().value()).isPositive(); + assertThat(registry.get("jvm.threads.daemon").gauge().value()).isPositive(); + assertThat(registry.get("jvm.threads.peak").gauge().value()).isPositive(); + assertThat(registry.get("jvm.threads.states").tag("state", "runnable").gauge().value()).isPositive(); createBlockedThread(); - assertThat(registry.get("jvm.threads.states").tag("state", "blocked").gauge().value()).isGreaterThan(0); - assertThat(registry.get("jvm.threads.states").tag("state", "waiting").gauge().value()).isGreaterThan(0); + assertThat(registry.get("jvm.threads.states").tag("state", "blocked").gauge().value()).isPositive(); + assertThat(registry.get("jvm.threads.states").tag("state", "waiting").gauge().value()).isPositive(); createTimedWaitingThread(); - assertThat(registry.get("jvm.threads.states").tag("state", "timed-waiting").gauge().value()).isGreaterThan(0); - assertThat(registry.get("jvm.threads.started").gauge().value()).isGreaterThan(initialThreadCount); + assertThat(registry.get("jvm.threads.states").tag("state", "timed-waiting").gauge().value()).isPositive(); + assertThat(registry.get("jvm.threads.started").functionCounter().count()).isGreaterThan(initialThreadCount); } @Test From 6f6332b7f8ead03cf1787bfc446fd381f92c99f4 Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan Date: Thu, 16 Feb 2023 20:34:50 -0800 Subject: [PATCH 4/6] Remove changes to GC Metrics and make threads started as Function Counter. --- .../core/instrument/binder/jvm/JvmThreadMetrics.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java index 3a494a1839..7303265bb4 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java @@ -17,7 +17,11 @@ import io.micrometer.common.lang.NonNullApi; import io.micrometer.common.lang.NonNullFields; -import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.FunctionCounter; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.binder.BaseUnits; import io.micrometer.core.instrument.binder.MeterBinder; From f87a9a2227b4ed3053c64f4b60ad218cf1c18cba Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan <32874349+lenin-jaganathan@users.noreply.github.com> Date: Fri, 17 Feb 2023 13:03:31 +0530 Subject: [PATCH 5/6] Update micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java Co-authored-by: Jonatan Ivanov --- .../core/instrument/binder/jvm/JvmThreadMetrics.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java index 7303265bb4..b11a944ea1 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java @@ -68,8 +68,7 @@ public void bindTo(MeterRegistry registry) { .baseUnit(BaseUnits.THREADS).register(registry); FunctionCounter.builder("jvm.threads.started", threadBean, ThreadMXBean::getTotalStartedThreadCount).tags(tags) - .description( - "The total number of application threads started in the JVM") + .description("The total number of application threads started in the JVM") .baseUnit(BaseUnits.THREADS).register(registry); try { From b6f1cc5827435ebe913843f1632bd5e095455844 Mon Sep 17 00:00:00 2001 From: Lenin Jaganathan Date: Thu, 16 Feb 2023 23:46:48 -0800 Subject: [PATCH 6/6] Fix formatting --- .../core/instrument/binder/jvm/JvmThreadMetrics.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java index b11a944ea1..9bb7da9b95 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmThreadMetrics.java @@ -68,8 +68,8 @@ public void bindTo(MeterRegistry registry) { .baseUnit(BaseUnits.THREADS).register(registry); FunctionCounter.builder("jvm.threads.started", threadBean, ThreadMXBean::getTotalStartedThreadCount).tags(tags) - .description("The total number of application threads started in the JVM") - .baseUnit(BaseUnits.THREADS).register(registry); + .description("The total number of application threads started in the JVM").baseUnit(BaseUnits.THREADS) + .register(registry); try { threadBean.getAllThreadIds();