Skip to content

Commit

Permalink
Better support for running JMXFetch in the JVM.
Browse files Browse the repository at this point in the history
More consistent file config with existing format.
  • Loading branch information
tylerbenson committed May 16, 2019
1 parent 7baa1e3 commit 3c2aa4f
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 12 deletions.
12 changes: 11 additions & 1 deletion src/main/java/org/datadog/jmxfetch/App.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.datadog.jmxfetch;

import static org.datadog.jmxfetch.Instance.isDirectInstance;

import com.google.common.primitives.Bytes;

import com.beust.jcommander.JCommander;
Expand Down Expand Up @@ -827,8 +829,16 @@ public void init(boolean forceNewConnection) {
}

for (LinkedHashMap<String, Object> configInstance : configInstances) {
if (appConfig.isAllowDirectInstances() != isDirectInstance(configInstance)) {
log.debug("Skipping instance '{}'. allowDirectInstances={} jvm_direct={}",
name,
appConfig.isAllowDirectInstances(),
isDirectInstance(configInstance));
continue;
}

// Create a new Instance object
log.info("Instantiating instance for: " + name);
log.info("Instantiating instance for: {}", name);
Instance instance =
instantiate(
configInstance,
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/datadog/jmxfetch/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ public class AppConfig {
@Builder.Default
private int ipcPort = 0;

/**
* Boolean setting to determine whether to ignore jvm_direct instances.
* If set to true, other instances will be ignored.
*/
@Builder.Default
private boolean allowDirectInstances = false;

// This is used by things like APM agent to provide configuration from resources
private List<String> instanceConfigResources;
// This is used by things like APM agent to provide metric configuration from resources
Expand Down Expand Up @@ -339,6 +346,10 @@ public String getJmxLaunchFile() {
return getTmpDirectory() + "/" + AD_LAUNCH_FILE;
}

public boolean isAllowDirectInstances() {
return allowDirectInstances;
}

public List<String> getInstanceConfigResources() {
return instanceConfigResources;
}
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/org/datadog/jmxfetch/ConnectionFactory.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.datadog.jmxfetch;

import static org.datadog.jmxfetch.Instance.isDirectInstance;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
Expand All @@ -9,11 +11,17 @@
@Slf4j
public class ConnectionFactory {
public static final String PROCESS_NAME_REGEX = "process_name_regex";
private static ConnectionFactory connectionFactory = null;

/** Factory method to create connections, both remote and local to the target JVM. */
public static Connection createConnection(LinkedHashMap<String, Object> connectionParams)
throws IOException {
// This is used by dd-java-agent to enable directly connecting to the mbean server.
// This works since jmxfetch is being run as a library inside the process being monitored.
if (isDirectInstance(connectionParams)) {
log.info("Connecting to JMX directly on the JVM");
return new JvmDirectConnection();
}

if (connectionParams.get(PROCESS_NAME_REGEX) != null) {
try {
Class.forName("com.sun.tools.attach.AttachNotSupportedException");
Expand All @@ -26,13 +34,6 @@ public static Connection createConnection(LinkedHashMap<String, Object> connecti
return new AttachApiConnection(connectionParams);
}

// This is used by dd-java-agent to enable directly connecting to the mbean server.
// This works because jmxfetch is being run as a library inside the process.
if ("service:jmx:local:///".equals(connectionParams.get("jmx_url"))) {
log.info("Connecting using JMX Local");
return new LocalConnection();
}

log.info("Connecting using JMX Remote");
return new RemoteConnection(connectionParams);
}
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/datadog/jmxfetch/Instance.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class Instance {
private static final int MAX_RETURNED_METRICS = 350;
private static final int DEFAULT_REFRESH_BEANS_PERIOD = 600;
public static final String PROCESS_NAME_REGEX = "process_name_regex";
public static final String JVM_DIRECT = "jvm_direct";
public static final String ATTRIBUTE = "Attribute: ";

private static final ThreadLocal<Yaml> YAML =
Expand Down Expand Up @@ -209,6 +210,11 @@ public Instance(
loadDefaultConfig(gcMetricConfig);
}

public static boolean isDirectInstance(LinkedHashMap<String, Object> configInstance) {
Object directInstance = configInstance.get(JVM_DIRECT);
return directInstance instanceof Boolean && (Boolean) directInstance;
}

private void loadDefaultConfig(String configResourcePath) {
ArrayList<LinkedHashMap<String, Object>> defaultConf =
(ArrayList<LinkedHashMap<String, Object>>)
Expand All @@ -222,6 +228,8 @@ private void loadDefaultConfig(String configResourcePath) {
static void loadMetricConfigFiles(
AppConfig appConfig, LinkedList<Configuration> configurationList) {
if (appConfig.getMetricConfigFiles() != null) {
log.warn("Loading files via metricConfigFiles setting is deprecated. Please "
+ "migrate to using standard agent config files in the conf.d directory.");
for (String fileName : appConfig.getMetricConfigFiles()) {
String yamlPath = new File(fileName).getAbsolutePath();
FileInputStream yamlInputStream = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import java.lang.management.ManagementFactory;

@Slf4j
public class LocalConnection extends Connection {
public class JvmDirectConnection extends Connection {

public LocalConnection() throws IOException {
public JvmDirectConnection() throws IOException {
createConnection();
}

Expand Down
2 changes: 2 additions & 0 deletions src/test/java/org/datadog/jmxfetch/TestApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.io.File;
import java.util.ArrayList;
Expand Down Expand Up @@ -490,6 +491,7 @@ public void testApp() throws Exception {
registerMBean(testApp, "org.datadog.jmxfetch.test:type=SimpleTestJavaApp");

// We do a first collection
when(appConfig.isAllowDirectInstances()).thenReturn(true);
initApplication("jmx.yaml");

run();
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/org/datadog/jmxfetch/TestServiceChecks.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.HashMap;
Expand All @@ -19,6 +20,7 @@ public void testServiceCheckOK() throws Exception {
registerMBean(new SimpleTestJavaApp(), "org.datadog.jmxfetch.test:type=ServiceCheckTest");

// We do a first collection
when(appConfig.isAllowDirectInstances()).thenReturn(true);
initApplication("jmx.yaml");

run();
Expand Down Expand Up @@ -153,6 +155,7 @@ public void testServiceCheckCRITICAL() throws Exception {

@Test
public void testServiceCheckCounter() throws Exception {
when(appConfig.isAllowDirectInstances()).thenReturn(true);
initApplication("jmx.yaml");

Reporter repo = getReporter();
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/jmx.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
init_config:

instances:
- process_name_regex: .*surefire.*
- jvm_direct: true
refresh_beans: 4
name: jmx_test_instance
tags:
Expand Down

0 comments on commit 3c2aa4f

Please sign in to comment.