Add integration test for jmxfetch
ADD
dd-java-agent-ittests/src/test/groovy/datadog/trace/agent/JMXFetchTest.groovy
+package datadog.trace.agent
+
+import datadog.trace.agent.test.IntegrationTestUtils
+import datadog.trace.api.Config
+import org.junit.Rule
+import org.junit.contrib.java.lang.system.RestoreSystemProperties
+import spock.lang.Specification
+
+import java.lang.reflect.Method
+
+class JMXFetchTest extends Specification {
+
+ @Rule
+ public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
+
+ def "test jmxfetch"() {
+ setup:
+ def currentContextLoader = Thread.currentThread().getContextClassLoader()
+ DatagramSocket socket = new DatagramSocket(0)
+
+ System.properties.setProperty("dd.jmxfetch.enabled", "true")
+ System.properties.setProperty("dd.jmxfetch.statsd.port", Integer.toString(socket.localPort))
+ // Overwrite writer type to disable console jmxfetch reporter
+ System.properties.setProperty("dd.writer.type", "DDAgentWriter")
+
+ def classLoader = IntegrationTestUtils.getJmxFetchClassLoader()
+ // Have to set this so JMXFetch knows where to find resources
+ Thread.currentThread().setContextClassLoader(classLoader)
+ final Class<?> jmxFetchAgentClass =
+ classLoader.loadClass("datadog.trace.agent.jmxfetch.JMXFetch")
+ final Method jmxFetchInstallerMethod = jmxFetchAgentClass.getDeclaredMethod("run", Config)
+ jmxFetchInstallerMethod.setAccessible(true)
+ jmxFetchInstallerMethod.invoke(null, new Config())
+
+ byte[] buf = new byte[1500]
+ DatagramPacket packet = new DatagramPacket(buf, buf.length)
+ socket.receive(packet)
+ String received = new String(packet.getData(), 0, packet.getLength())
+
+ Set<String> threads = Thread.getAllStackTraces().keySet().collect { it.name }
+
+ expect:
+ threads.contains("dd-jmx-collector")
+ received.contains("jvm.")
+
+ cleanup:
+ jmxFetchInstallerMethod.setAccessible(false)
+ socket.close()
+ Thread.currentThread().setContextClassLoader(currentContextLoader)
+ }
+
+}

MODIFY
dd-java-agent-ittests/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java
dd-java-agent-ittests/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java
@@ -32,31 +32,21 @@ public class IntegrationTestUtils {
/** Returns the classloader the core agent is running on. */
public static ClassLoader getAgentClassLoader() {
- Field classloaderField = null;
- try {
- Class<?> tracingAgentClass =
- tracingAgentClass =
- ClassLoader.getSystemClassLoader().loadClass("datadog.trace.agent.TracingAgent");
- classloaderField = tracingAgentClass.getDeclaredField("AGENT_CLASSLOADER");
- classloaderField.setAccessible(true);
- return (ClassLoader) classloaderField.get(null);
- } catch (final Exception e) {
- throw new IllegalStateException(e);
- } finally {
- if (null != classloaderField) {
- classloaderField.setAccessible(false);
- }
- }
+ return getTracingAgentFieldClassloader("AGENT_CLASSLOADER");
}
/** Returns the classloader the jmxfetch is running on. */
public static ClassLoader getJmxFetchClassLoader() {
+ return getTracingAgentFieldClassloader("JMXFETCH_CLASSLOADER");
+ }
+
+ private static ClassLoader getTracingAgentFieldClassloader(final String fieldName) {
Field classloaderField = null;
try {
Class<?> tracingAgentClass =
tracingAgentClass =
ClassLoader.getSystemClassLoader().loadClass("datadog.trace.agent.TracingAgent");
- classloaderField = tracingAgentClass.getDeclaredField("JMXFETCH_CLASSLOADER");
+ classloaderField = tracingAgentClass.getDeclaredField(fieldName);
classloaderField.setAccessible(true);
return (ClassLoader) classloaderField.get(null);
} catch (final Exception e) {

MODIFY
dd-java-agent/agent-jmxfetch/src/main/java/datadog/trace/agent/jmxfetch/JMXFetch.java
dd-java-agent/agent-jmxfetch/src/main/java/datadog/trace/agent/jmxfetch/JMXFetch.java
@@ -16,16 +16,20 @@ public class JMXFetch {
private static final int SLEEP_AFTER_JMXFETCH_EXITS = 5000;
public static final void run() {
+ run(Config.get());
+ }
- if (!Config.get().isJmxFetchEnabled()) {
+ // This is used by tests
+ private static void run(final Config config) {
+ if (!config.isJmxFetchEnabled()) {
log.info("JMXFetch is disabled");
return;
}
- final List<String> metricsConfigs = Config.get().getJmxFetchMetricsConfigs();
- final Integer checkPeriod = Config.get().getJmxFetchCheckPeriod();
- final Integer refreshBeansPeriod = Config.get().getJmxFetchRefreshBeansPeriod();
- final String reporter = getReporter();
+ final List<String> metricsConfigs = config.getJmxFetchMetricsConfigs();
+ final Integer checkPeriod = config.getJmxFetchCheckPeriod();
+ final Integer refreshBeansPeriod = config.getJmxFetchRefreshBeansPeriod();
+ final String reporter = getReporter(config);
final String logLocation = getLogLocation();
final String logLevel = getLogLevel();
@@ -37,7 +41,7 @@ public class JMXFetch {
reporter,
logLocation,
logLevel);
- final AppConfig config =
+ final AppConfig appConfig =
AppConfig.create(
DEFAULT_CONFIGS,
metricsConfigs,
@@ -54,7 +58,7 @@ public class JMXFetch {
public void run() {
while (true) {
try {
- final int result = App.run(config);
+ final int result = App.run(appConfig);
log.error("jmx collector exited with result: " + result);
} catch (final Exception e) {
log.error("Exception in jmx collector thread", e);
@@ -74,8 +78,7 @@ public class JMXFetch {
thread.start();
}
- private static String getReporter() {
- final Config config = Config.get();
+ private static String getReporter(final Config config) {
if (Config.LOGGING_WRITER_TYPE.equals(config.getWriterType())) {
// If logging writer is enabled then also enable console reporter in JMXFetch
return "console";

Add integration test for jmxfetch