From 46d2ed50354ad4bd214edd4f77c60069f2f790b9 Mon Sep 17 00:00:00 2001
From: Jean Bisutti <jean.bisutti@gmail.com>
Date: Thu, 3 Apr 2025 16:51:15 +0200
Subject: [PATCH 1/2] Log as warn invalid JMX metrics

---
 .../AbstractJmxPerformanceCounter.java            | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
index 0c1104ae17e..16925131bb0 100644
--- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
+++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
@@ -7,7 +7,9 @@
 
 import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -24,6 +26,8 @@ public abstract class AbstractJmxPerformanceCounter implements PerformanceCounte
   private final Collection<JmxAttributeData> attributes;
   private boolean alreadyLogged = false;
 
+  private final Set<String> invalidJmxMetrics = new HashSet<>();
+
   /**
    * The main method. The method will fetch the data and send it. The method will not do anything if
    * there was a major problem accessing the needed counter.
@@ -38,6 +42,7 @@ public synchronized void report(TelemetryClient telemetryClient) {
       for (Map.Entry<String, Collection<Object>> displayAndValues : result.entrySet()) {
         boolean ok = true;
         double value = 0.0;
+        String metricName = displayAndValues.getKey();
         for (Object obj : displayAndValues.getValue()) {
           try {
             if (obj instanceof Boolean) {
@@ -46,6 +51,14 @@ public synchronized void report(TelemetryClient telemetryClient) {
               value += Double.parseDouble(String.valueOf(obj));
             }
           } catch (RuntimeException e) {
+            if (!invalidJmxMetrics.contains(metricName)) {
+              invalidJmxMetrics.add(metricName);
+              try (MDC.MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR.makeActive()) {
+                logger.warn(
+                    "{} JMX metric is invalid because only numeric and boolean JMX metric values are supported.",
+                    metricName);
+              }
+            }
             ok = false;
             break;
           }
@@ -53,7 +66,7 @@ public synchronized void report(TelemetryClient telemetryClient) {
 
         if (ok) {
           try {
-            send(telemetryClient, displayAndValues.getKey(), value);
+            send(telemetryClient, metricName, value);
           } catch (RuntimeException e) {
             try (MDC.MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR.makeActive()) {
               logger.error("Error while sending JMX data: '{}'", e.toString());

From 213ccb5472fa1bd7de6c0fac95f37a8f63fd09fe Mon Sep 17 00:00:00 2001
From: Jean Bisutti <jean.bisutti@gmail.com>
Date: Tue, 8 Apr 2025 17:29:52 +0200
Subject: [PATCH 2/2] Feedback and put the code at the right place

---
 .../init/PerformanceCounterInitializer.java       | 11 +++++++++++
 .../AbstractJmxPerformanceCounter.java            | 15 +--------------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/PerformanceCounterInitializer.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/PerformanceCounterInitializer.java
index ff488d94aad..79673393197 100644
--- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/PerformanceCounterInitializer.java
+++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/PerformanceCounterInitializer.java
@@ -31,6 +31,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -41,6 +43,8 @@ public class PerformanceCounterInitializer {
   private static final String METRIC_NAME_REGEXP = "[a-zA-Z0-9_.-/]+";
   private static final String INVALID_CHARACTER_REGEXP = "[^a-zA-Z0-9_.-/]";
 
+  private static final Set<String> invalidJmxMetrics = ConcurrentHashMap.newKeySet();
+
   public static void initialize(Configuration configuration) {
 
     PerformanceCounterContainer.INSTANCE.setCollectionFrequencyInSec(
@@ -209,6 +213,13 @@ private static void calculateAndRecordValueForAttribute(
             value += Double.parseDouble(String.valueOf(obj));
           }
         } catch (RuntimeException e) {
+          if (invalidJmxMetrics.add(jmxAttributeData.metricName)) {
+            try (MDC.MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR.makeActive()) {
+              logger.warn(
+                  "{} JMX metric is invalid because only numeric and boolean JMX metric values are supported.",
+                  jmxAttributeData.metricName);
+            }
+          }
           ok = false;
           break;
         }
diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
index 16925131bb0..0c1104ae17e 100644
--- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
+++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AbstractJmxPerformanceCounter.java
@@ -7,9 +7,7 @@
 
 import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -26,8 +24,6 @@ public abstract class AbstractJmxPerformanceCounter implements PerformanceCounte
   private final Collection<JmxAttributeData> attributes;
   private boolean alreadyLogged = false;
 
-  private final Set<String> invalidJmxMetrics = new HashSet<>();
-
   /**
    * The main method. The method will fetch the data and send it. The method will not do anything if
    * there was a major problem accessing the needed counter.
@@ -42,7 +38,6 @@ public synchronized void report(TelemetryClient telemetryClient) {
       for (Map.Entry<String, Collection<Object>> displayAndValues : result.entrySet()) {
         boolean ok = true;
         double value = 0.0;
-        String metricName = displayAndValues.getKey();
         for (Object obj : displayAndValues.getValue()) {
           try {
             if (obj instanceof Boolean) {
@@ -51,14 +46,6 @@ public synchronized void report(TelemetryClient telemetryClient) {
               value += Double.parseDouble(String.valueOf(obj));
             }
           } catch (RuntimeException e) {
-            if (!invalidJmxMetrics.contains(metricName)) {
-              invalidJmxMetrics.add(metricName);
-              try (MDC.MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR.makeActive()) {
-                logger.warn(
-                    "{} JMX metric is invalid because only numeric and boolean JMX metric values are supported.",
-                    metricName);
-              }
-            }
             ok = false;
             break;
           }
@@ -66,7 +53,7 @@ public synchronized void report(TelemetryClient telemetryClient) {
 
         if (ok) {
           try {
-            send(telemetryClient, metricName, value);
+            send(telemetryClient, displayAndValues.getKey(), value);
           } catch (RuntimeException e) {
             try (MDC.MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR.makeActive()) {
               logger.error("Error while sending JMX data: '{}'", e.toString());