From 639e302326a9d526905313ea7ee5cb2139dc546a Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Thu, 28 Dec 2023 10:43:51 -0500 Subject: [PATCH 1/7] Initial stab at application-level telemetry --- src/main/java/org/datadog/jmxfetch/App.java | 72 +++++++++++++++++++ .../datadog/jmxfetch/util/AppTelemetry.java | 40 +++++++++++ .../jmxfetch/util/AppTelemetryMBean.java | 11 +++ .../java/org/datadog/jmxfetch/TestApp.java | 8 +++ 4 files changed, 131 insertions(+) create mode 100644 src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java create mode 100644 src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index 6d2d2e16b..aba9cf43b 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -16,6 +16,17 @@ import org.datadog.jmxfetch.util.LogLevel; import org.datadog.jmxfetch.util.MetadataHelper; import org.datadog.jmxfetch.util.ServiceCheckHelper; +import org.datadog.jmxfetch.util.AppTelemetry; + +import java.lang.management.ManagementFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.NotCompliantMBeanException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MBeanInfo; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; import java.io.ByteArrayInputStream; import java.io.File; @@ -86,6 +97,8 @@ public class App { private final AppConfig appConfig; private HttpClient client; + private AppTelemetry appTelemetry; + /** * Main method for backwards compatibility in case someone is launching process by class * instead of by jar IE: java -classpath jmxfetch.jar org.datadog.jmxfetch.App @@ -118,8 +131,39 @@ public App(final AppConfig appConfig) { this.appConfig.getIpcHost(), this.appConfig.getIpcPort(), false); } this.configs = getConfigs(this.appConfig); + + this.initTelemetryBean(); } + private void initTelemetryBean() { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + AppTelemetry bean = new AppTelemetry(); + ObjectName appTelemetryBeanName; + + try { + appTelemetryBeanName = new ObjectName(appConfig.getJmxfetchTelemetryDomain() + ":name=jmxfetch_app" + ",version=" + MetadataHelper.getVersion()); + } catch (MalformedObjectNameException e) { + log.warn( + "Could not construct bean name for jmxfetch_telemetry_domain '{}' and name 'JMXFetch'", + appConfig.getJmxfetchTelemetryDomain()); + return; + } + + try { + mbs.registerMBean(bean, appTelemetryBeanName); + log.debug("Succesfully registered app telemetry bean"); + } catch (InstanceAlreadyExistsException + | MBeanRegistrationException + | NotCompliantMBeanException e) { + log.warn("Could not register bean named '{}' for instance: ", + appTelemetryBeanName.toString(), e); + } + + this.appTelemetry = bean; + return; + } + + /** * Main entry point of JMXFetch that returns integer on exit instead of calling {@code * System#exit}. @@ -467,6 +511,9 @@ public void doIteration() { for (Instance instance : this.instances) { getMetricsTasks.add(new MetricCollectionTask(instance)); } + if (this.appTelemetry != null) { + this.appTelemetry.setNumRunningInstances(this.instances.size()); + } if (!this.collectionProcessor.ready()) { log.warn( @@ -1104,6 +1151,11 @@ private void processInstantiationStatus( "Could not initialize instance: {}:", instance.getName(), e); instance.cleanUpAsync(); this.brokenInstanceMap.put(instance.toString(), instance); + if (this.appTelemetry != null) { + this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); + int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); + this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + } } } } @@ -1124,6 +1176,11 @@ private void processFixedStatus( this.brokenInstanceMap.remove(instance.toString()); this.instances.add(instance); + if (this.appTelemetry != null) { + this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); + this.appTelemetry.setNumRunningInstances(this.instances.size()); + } + } catch (Throwable e) { // Not much to do here, instance didn't recover } finally { @@ -1235,6 +1292,11 @@ private void processCollectionStatus( this.brokenInstanceMap.put(instance.toString(), instance); log.debug("Adding broken instance to list: " + instance.getName()); + if (this.appTelemetry != null) { + this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); + int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); + this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + } log.warn(instanceMessage, ee.getCause()); } catch (Throwable t) { @@ -1242,6 +1304,12 @@ private void processCollectionStatus( log.debug("Adding broken instance to list: " + instance.getName()); this.brokenInstanceMap.put(instance.toString(), instance); + if (this.appTelemetry != null) { + this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); + int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); + this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + } + instanceStatus = Status.STATUS_ERROR; instanceMessage = task.getWarning() + ": " + t.toString(); @@ -1264,4 +1332,8 @@ private void processCollectionStatus( } } } + + public AppTelemetry getAppTelemetryBean() { + return this.appTelemetry; + } } diff --git a/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java b/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java new file mode 100644 index 000000000..6caaffe95 --- /dev/null +++ b/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java @@ -0,0 +1,40 @@ +package org.datadog.jmxfetch.util; + + +/** Jmxfetch telemetry JMX MBean. */ +public class AppTelemetry implements AppTelemetryMBean { + private int numRunningInstances; + private int numBrokenInstances; + private int numBrokenInstancesTotal; + + /** Jmxfetch telemetry bean constructor. */ + public AppTelemetry() { + numRunningInstances = 0; + numBrokenInstances = 0; + numBrokenInstancesTotal = 0; + } + + public int getNumRunningInstances() { + return numRunningInstances; + } + + public int getNumBrokenInstances() { + return numBrokenInstances; + } + + public int getNumBrokenInstancesTotal() { + return numBrokenInstancesTotal; + } + + public void setNumRunningInstances(int count) { + numRunningInstances = count; + } + + public void setNumBrokenInstances(int count) { + numBrokenInstances = count; + } + + public void setNumBrokenInstancesTotal(int count) { + numBrokenInstancesTotal = count; + } +} diff --git a/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java b/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java new file mode 100644 index 000000000..af5670ddd --- /dev/null +++ b/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java @@ -0,0 +1,11 @@ +package org.datadog.jmxfetch.util; + +public interface AppTelemetryMBean { + + int getNumRunningInstances(); + + int getNumBrokenInstances(); + + int getNumBrokenInstancesTotal(); + +} diff --git a/src/test/java/org/datadog/jmxfetch/TestApp.java b/src/test/java/org/datadog/jmxfetch/TestApp.java index f857d9673..d53bd903c 100644 --- a/src/test/java/org/datadog/jmxfetch/TestApp.java +++ b/src/test/java/org/datadog/jmxfetch/TestApp.java @@ -5,6 +5,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import org.datadog.jmxfetch.util.AppTelemetry; + import java.io.File; import java.util.Arrays; import java.util.Collections; @@ -43,6 +45,9 @@ public void testBeanRegexTags() throws Exception { "nonRegexTag:value"); assertMetric("this.is.100", tags, 10); + + AppTelemetry tlm = app.getAppTelemetryBean(); + assertEquals(1, tlm.getNumRunningInstances()); } /** Tag metrics with MBeans parameters. */ @@ -72,6 +77,9 @@ public void testBeanTags() throws Exception { "component"); assertMetric("this.is.100", tags, 7); + + AppTelemetry tlm = app.getAppTelemetryBean(); + assertEquals(1, tlm.getNumRunningInstances()); } /** Tag metrics with MBeans parameters with normalize_bean_param_tags option enabled. */ From c44740955b4fced2d66501148b553e4e64f6349e Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Thu, 28 Dec 2023 12:49:32 -0500 Subject: [PATCH 2/7] Renames telemetry fields to be more specific --- src/main/java/org/datadog/jmxfetch/App.java | 22 +++++------ .../datadog/jmxfetch/util/AppTelemetry.java | 37 ++++++++++--------- .../jmxfetch/util/AppTelemetryMBean.java | 6 +-- .../java/org/datadog/jmxfetch/TestApp.java | 4 +- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index aba9cf43b..b7f290b35 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -24,7 +24,6 @@ import javax.management.NotCompliantMBeanException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; -import javax.management.MBeanInfo; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; @@ -512,7 +511,7 @@ public void doIteration() { getMetricsTasks.add(new MetricCollectionTask(instance)); } if (this.appTelemetry != null) { - this.appTelemetry.setNumRunningInstances(this.instances.size()); + this.appTelemetry.setRunningInstanceCount(this.instances.size()); } if (!this.collectionProcessor.ready()) { @@ -1152,9 +1151,8 @@ private void processInstantiationStatus( instance.cleanUpAsync(); this.brokenInstanceMap.put(instance.toString(), instance); if (this.appTelemetry != null) { - this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); - int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); - this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + this.appTelemetry.setBrokenInstanceCount(this.brokenInstanceMap.size()); + this.appTelemetry.incrementBrokenInstanceEventCount(); } } } @@ -1177,8 +1175,8 @@ private void processFixedStatus( this.instances.add(instance); if (this.appTelemetry != null) { - this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); - this.appTelemetry.setNumRunningInstances(this.instances.size()); + this.appTelemetry.setBrokenInstanceCount(this.brokenInstanceMap.size()); + this.appTelemetry.setRunningInstanceCount(this.instances.size()); } } catch (Throwable e) { @@ -1293,9 +1291,8 @@ private void processCollectionStatus( this.brokenInstanceMap.put(instance.toString(), instance); log.debug("Adding broken instance to list: " + instance.getName()); if (this.appTelemetry != null) { - this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); - int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); - this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + this.appTelemetry.setBrokenInstanceCount(this.brokenInstanceMap.size()); + this.appTelemetry.incrementBrokenInstanceEventCount(); } log.warn(instanceMessage, ee.getCause()); @@ -1305,9 +1302,8 @@ private void processCollectionStatus( this.brokenInstanceMap.put(instance.toString(), instance); if (this.appTelemetry != null) { - this.appTelemetry.setNumBrokenInstances(this.brokenInstanceMap.size()); - int numBrokenInstancesTotal = this.appTelemetry.getNumBrokenInstancesTotal(); - this.appTelemetry.setNumBrokenInstancesTotal(numBrokenInstancesTotal + 1); + this.appTelemetry.setBrokenInstanceCount(this.brokenInstanceMap.size()); + this.appTelemetry.incrementBrokenInstanceEventCount(); } instanceStatus = Status.STATUS_ERROR; diff --git a/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java b/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java index 6caaffe95..77308c3ca 100644 --- a/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java +++ b/src/main/java/org/datadog/jmxfetch/util/AppTelemetry.java @@ -1,40 +1,41 @@ package org.datadog.jmxfetch.util; +import java.util.concurrent.atomic.AtomicInteger; /** Jmxfetch telemetry JMX MBean. */ public class AppTelemetry implements AppTelemetryMBean { - private int numRunningInstances; - private int numBrokenInstances; - private int numBrokenInstancesTotal; + private AtomicInteger runningInstanceCount; + private AtomicInteger brokenInstanceCount; + private AtomicInteger brokenInstanceEventCount; /** Jmxfetch telemetry bean constructor. */ public AppTelemetry() { - numRunningInstances = 0; - numBrokenInstances = 0; - numBrokenInstancesTotal = 0; + runningInstanceCount = new AtomicInteger(0); + brokenInstanceCount = new AtomicInteger(0); + brokenInstanceEventCount = new AtomicInteger(0); } - public int getNumRunningInstances() { - return numRunningInstances; + public int getRunningInstanceCount() { + return runningInstanceCount.get(); } - public int getNumBrokenInstances() { - return numBrokenInstances; + public int getBrokenInstanceCount() { + return brokenInstanceCount.get(); } - public int getNumBrokenInstancesTotal() { - return numBrokenInstancesTotal; + public int getBrokenInstanceEventCount() { + return brokenInstanceEventCount.get(); } - public void setNumRunningInstances(int count) { - numRunningInstances = count; + public void setRunningInstanceCount(int count) { + this.runningInstanceCount.set(count); } - public void setNumBrokenInstances(int count) { - numBrokenInstances = count; + public void setBrokenInstanceCount(int count) { + brokenInstanceCount.set(count); } - public void setNumBrokenInstancesTotal(int count) { - numBrokenInstancesTotal = count; + public void incrementBrokenInstanceEventCount() { + brokenInstanceEventCount.incrementAndGet(); } } diff --git a/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java b/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java index af5670ddd..66028b12a 100644 --- a/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java +++ b/src/main/java/org/datadog/jmxfetch/util/AppTelemetryMBean.java @@ -2,10 +2,10 @@ public interface AppTelemetryMBean { - int getNumRunningInstances(); + int getRunningInstanceCount(); - int getNumBrokenInstances(); + int getBrokenInstanceCount(); - int getNumBrokenInstancesTotal(); + int getBrokenInstanceEventCount(); } diff --git a/src/test/java/org/datadog/jmxfetch/TestApp.java b/src/test/java/org/datadog/jmxfetch/TestApp.java index d53bd903c..1ef2e54d2 100644 --- a/src/test/java/org/datadog/jmxfetch/TestApp.java +++ b/src/test/java/org/datadog/jmxfetch/TestApp.java @@ -47,7 +47,7 @@ public void testBeanRegexTags() throws Exception { assertMetric("this.is.100", tags, 10); AppTelemetry tlm = app.getAppTelemetryBean(); - assertEquals(1, tlm.getNumRunningInstances()); + assertEquals(1, tlm.getRunningInstanceCount()); } /** Tag metrics with MBeans parameters. */ @@ -79,7 +79,7 @@ public void testBeanTags() throws Exception { assertMetric("this.is.100", tags, 7); AppTelemetry tlm = app.getAppTelemetryBean(); - assertEquals(1, tlm.getNumRunningInstances()); + assertEquals(1, tlm.getRunningInstanceCount()); } /** Tag metrics with MBeans parameters with normalize_bean_param_tags option enabled. */ From 00f18a71d675d4b0df90d80d8df2350b9c8d6109 Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Thu, 28 Dec 2023 13:01:15 -0500 Subject: [PATCH 3/7] Hopefully address linting errors --- src/main/java/org/datadog/jmxfetch/App.java | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index b7f290b35..cdbd6615b 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -10,23 +10,16 @@ import org.datadog.jmxfetch.tasks.TaskProcessException; import org.datadog.jmxfetch.tasks.TaskProcessor; import org.datadog.jmxfetch.tasks.TaskStatusHandler; +import org.datadog.jmxfetch.util.AppTelemetry; import org.datadog.jmxfetch.util.ByteArraySearcher; import org.datadog.jmxfetch.util.CustomLogger; import org.datadog.jmxfetch.util.FileHelper; import org.datadog.jmxfetch.util.LogLevel; import org.datadog.jmxfetch.util.MetadataHelper; import org.datadog.jmxfetch.util.ServiceCheckHelper; -import org.datadog.jmxfetch.util.AppTelemetry; import java.lang.management.ManagementFactory; -import javax.management.InstanceAlreadyExistsException; -import javax.management.NotCompliantMBeanException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; @@ -58,8 +51,17 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; + import javax.security.auth.login.FailedLoginException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + + @SuppressWarnings("unchecked") @Slf4j @@ -140,10 +142,13 @@ private void initTelemetryBean() { ObjectName appTelemetryBeanName; try { - appTelemetryBeanName = new ObjectName(appConfig.getJmxfetchTelemetryDomain() + ":name=jmxfetch_app" + ",version=" + MetadataHelper.getVersion()); + appTelemetryBeanName = new ObjectName( + appConfig.getJmxfetchTelemetryDomain() + ":name=jmxfetch_app" + + ",version=" + MetadataHelper.getVersion()); } catch (MalformedObjectNameException e) { log.warn( - "Could not construct bean name for jmxfetch_telemetry_domain '{}' and name 'JMXFetch'", + "Could not construct bean name for jmxfetch_telemetry_domain" + + " '{}' and name 'jmxfetch_app'", appConfig.getJmxfetchTelemetryDomain()); return; } From f9dd599d418786fd9ee597d9db4fa9b80f9a8400 Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Thu, 28 Dec 2023 13:03:25 -0500 Subject: [PATCH 4/7] Fix remaining lint errors --- src/main/java/org/datadog/jmxfetch/App.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index cdbd6615b..7541b744d 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -18,14 +18,13 @@ import org.datadog.jmxfetch.util.MetadataHelper; import org.datadog.jmxfetch.util.ServiceCheckHelper; -import java.lang.management.ManagementFactory; - import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.lang.management.ManagementFactory; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; @@ -36,8 +35,8 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import java.util.Map; import java.util.Map.Entry; +import java.util.Map; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentHashMap; @@ -52,8 +51,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.security.auth.login.FailedLoginException; - import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; @@ -61,6 +58,8 @@ import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; +import javax.security.auth.login.FailedLoginException; + @SuppressWarnings("unchecked") From 9f759eb2db60a2a42b40740c49ccc992cf9bf92c Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Tue, 2 Jan 2024 11:48:07 -0500 Subject: [PATCH 5/7] Adds teardown to de-register app telemetry bean --- src/main/java/org/datadog/jmxfetch/App.java | 36 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index 7541b744d..d65def3ae 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -52,6 +52,7 @@ import java.util.regex.Pattern; import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; @@ -135,20 +136,28 @@ public App(final AppConfig appConfig) { this.initTelemetryBean(); } - private void initTelemetryBean() { - MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - AppTelemetry bean = new AppTelemetry(); + private ObjectName getAppTelemetryBeanName() { ObjectName appTelemetryBeanName; try { appTelemetryBeanName = new ObjectName( - appConfig.getJmxfetchTelemetryDomain() + ":name=jmxfetch_app" - + ",version=" + MetadataHelper.getVersion()); + appConfig.getJmxfetchTelemetryDomain() + ":name=jmxfetch_app"); } catch (MalformedObjectNameException e) { log.warn( "Could not construct bean name for jmxfetch_telemetry_domain" + " '{}' and name 'jmxfetch_app'", appConfig.getJmxfetchTelemetryDomain()); + return null; + } + + return appTelemetryBeanName; + } + + private void initTelemetryBean() { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + AppTelemetry bean = new AppTelemetry(); + ObjectName appTelemetryBeanName = getAppTelemetryBeanName(); + if (appTelemetryBeanName == null) { return; } @@ -166,6 +175,22 @@ private void initTelemetryBean() { return; } + private void teardownTelemetry() { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + ObjectName appTelemetryBeanName = getAppTelemetryBeanName(); + if (appTelemetryBeanName == null) { + return; + } + + try { + mbs.unregisterMBean(appTelemetryBeanName); + log.debug("Succesfully unregistered app telemetry bean"); + } catch (MBeanRegistrationException | InstanceNotFoundException e) { + log.warn("Could not unregister bean named '{}' for instance: ", + appTelemetryBeanName.toString(), e); + } + } + /** * Main entry point of JMXFetch that returns integer on exit instead of calling {@code @@ -495,6 +520,7 @@ void start() { } void stop() { + this.teardownTelemetry(); this.collectionProcessor.stop(); this.recoveryProcessor.stop(); } From 0be81fe32da92bc6ff898aa14ab58a83fcf2242c Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Tue, 2 Jan 2024 11:49:33 -0500 Subject: [PATCH 6/7] Moves version from bean name to explicitly added tags (plus small refactor for testing) --- src/main/java/org/datadog/jmxfetch/App.java | 3 ++- .../java/org/datadog/jmxfetch/AppConfig.java | 5 ++++ .../java/org/datadog/jmxfetch/TestApp.java | 25 +++++++++++++++++++ src/test/resources/jmx_telemetry_tags.yaml | 14 +++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/jmx_telemetry_tags.yaml diff --git a/src/main/java/org/datadog/jmxfetch/App.java b/src/main/java/org/datadog/jmxfetch/App.java index d65def3ae..8c78e8ac3 100644 --- a/src/main/java/org/datadog/jmxfetch/App.java +++ b/src/main/java/org/datadog/jmxfetch/App.java @@ -225,7 +225,7 @@ public int run() { return 0; } - log.info("JMX Fetch " + MetadataHelper.getVersion() + " has started"); + log.info("JMX Fetch " + this.appConfig.getVersion() + " has started"); // set up the config status this.appConfig.updateStatus(); @@ -1082,6 +1082,7 @@ private Map getTelemetryInstanceConfig() { config.put("conf",conf); List tags = new ArrayList(); + tags.add("version:" + this.appConfig.getVersion()); config.put("tags", tags); return config; diff --git a/src/main/java/org/datadog/jmxfetch/AppConfig.java b/src/main/java/org/datadog/jmxfetch/AppConfig.java index a03842d03..a01ff561d 100644 --- a/src/main/java/org/datadog/jmxfetch/AppConfig.java +++ b/src/main/java/org/datadog/jmxfetch/AppConfig.java @@ -10,6 +10,7 @@ import org.datadog.jmxfetch.reporter.Reporter; import org.datadog.jmxfetch.reporter.ReporterFactory; import org.datadog.jmxfetch.service.ServiceNameProvider; +import org.datadog.jmxfetch.util.MetadataHelper; import org.datadog.jmxfetch.validator.LogLevelValidator; import org.datadog.jmxfetch.validator.PositiveIntegerValidator; import org.datadog.jmxfetch.validator.ReporterValidator; @@ -513,4 +514,8 @@ public int getStatsdBufferSize() { public int getSocketTimeout() { return statsdSocketTimeout; } + + public String getVersion() { + return MetadataHelper.getVersion(); + } } diff --git a/src/test/java/org/datadog/jmxfetch/TestApp.java b/src/test/java/org/datadog/jmxfetch/TestApp.java index 1ef2e54d2..5fec8d252 100644 --- a/src/test/java/org/datadog/jmxfetch/TestApp.java +++ b/src/test/java/org/datadog/jmxfetch/TestApp.java @@ -1168,4 +1168,29 @@ public void testNestedCompositeData() throws Exception { assertCoverage(); } + + @Test + public void testTelemetryTags() throws Exception { + SimpleTestJavaApp testApp = new SimpleTestJavaApp(); + registerMBean(testApp, "org.datadog.jmxfetch.test:type=SimpleTestJavaApp"); + + when(appConfig.isTargetDirectInstances()).thenReturn(true); + when(appConfig.getJmxfetchTelemetry()).thenReturn(true); + when(appConfig.getVersion()).thenReturn("MOCKED_VERSION"); + + initApplication("jmx_telemetry_tags.yaml"); + + run(); + + List telemetryTags = Arrays.asList( + "instance:jmxfetch_telemetry_instance", + "name:jmxfetch_app", + "jmx_domain:jmx_fetch", + "version:MOCKED_VERSION"); + + assertMetric("jmx.jmx_fetch.running_instance_count", 2, telemetryTags, -1); + + // not asserting coverage, this is intended to test the tags present on telemetry + // not the set metrics collected + } } diff --git a/src/test/resources/jmx_telemetry_tags.yaml b/src/test/resources/jmx_telemetry_tags.yaml new file mode 100644 index 000000000..f7c10f848 --- /dev/null +++ b/src/test/resources/jmx_telemetry_tags.yaml @@ -0,0 +1,14 @@ +--- +init_config: + +instances: + - jvm_direct: true + refresh_beans: 4 + collect_default_jvm_metrics: false + name: jmx_test_instance + tags: + - "env:stage" + - "newTag:test" + conf: + - include: + domain: org.datadog.jmxfetch.test \ No newline at end of file From 8f68cb57597c6978eacc9191925510adbebf4a5a Mon Sep 17 00:00:00 2001 From: Scott Opell Date: Tue, 2 Jan 2024 12:04:45 -0500 Subject: [PATCH 7/7] Tears down application in between each test --- src/test/java/org/datadog/jmxfetch/TestCommon.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/datadog/jmxfetch/TestCommon.java b/src/test/java/org/datadog/jmxfetch/TestCommon.java index 49fb77a12..9503eff25 100644 --- a/src/test/java/org/datadog/jmxfetch/TestCommon.java +++ b/src/test/java/org/datadog/jmxfetch/TestCommon.java @@ -109,12 +109,13 @@ public void unregisterMBean() throws MBeanRegistrationException, InstanceNotFoun } /** - * Clear instances and their instance telemetry bean after execution of every test. + * Tear down instances and application. */ @After - public void clearInstances() { + public void teardown() { if (app != null) { app.clearAllInstances(); + app.stop(); } } @@ -176,7 +177,7 @@ protected void initApplication(String yamlFileName) throws FileNotFoundException } /* - * Init JMXFetch with the given YAML configuration template + * Init JMXFetch with the given YAML configuration template * The configuration can be specified as a yaml literal with each arg * representing one line of the Yaml file * Does not support any SD/AD features. @@ -188,7 +189,7 @@ protected void initApplicationWithYamlLines(String... yamlLines) String confdDirectory = tempFile.getParent().toString(); String yamlFileName = tempFile.getFileName().toString(); - + List params = new ArrayList(); params.add("--reporter"); params.add("console");