From 2ce3627123bccdc7e7e32d1453f351cc95ea5206 Mon Sep 17 00:00:00 2001 From: Hippolyte HENRY Date: Mon, 27 Feb 2017 16:05:55 -0500 Subject: [PATCH] Fix JMXFetch issue when several instances on the same host (#124) * Remove storage of connections in the connection manager The connection will now be stored by the instance. No more shared connections * Change ConnectionManager into ConnectionFactory --- .../datadog/jmxfetch/ConnectionFactory.java | 33 +++++++++ .../datadog/jmxfetch/ConnectionManager.java | 73 ------------------- .../java/org/datadog/jmxfetch/Instance.java | 14 +++- 3 files changed, 46 insertions(+), 74 deletions(-) create mode 100644 src/main/java/org/datadog/jmxfetch/ConnectionFactory.java delete mode 100644 src/main/java/org/datadog/jmxfetch/ConnectionManager.java diff --git a/src/main/java/org/datadog/jmxfetch/ConnectionFactory.java b/src/main/java/org/datadog/jmxfetch/ConnectionFactory.java new file mode 100644 index 000000000..f76cb1490 --- /dev/null +++ b/src/main/java/org/datadog/jmxfetch/ConnectionFactory.java @@ -0,0 +1,33 @@ +package org.datadog.jmxfetch; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.apache.log4j.Logger; + + +/** + * Singleton used to create connections to the MBeanServer + */ +public class ConnectionFactory { + private final static Logger LOGGER = Logger.getLogger(ConnectionFactory.class.getName()); + public static final String PROCESS_NAME_REGEX = "process_name_regex"; + private static ConnectionFactory connectionFactory = null; + + public static Connection createConnection(LinkedHashMap connectionParams) throws IOException { + if (connectionParams.get(PROCESS_NAME_REGEX) != null) { + try { + Class.forName( "com.sun.tools.attach.AttachNotSupportedException" ); + } catch (ClassNotFoundException e) { + throw new IOException("Unable to find tools.jar. Are you using a JDK and did you set the pass to tools.jar ?"); + } + LOGGER.info("Connecting using Attach API"); + return new AttachApiConnection(connectionParams); + + } + LOGGER.info("Connecting using JMX Remote"); + return new RemoteConnection(connectionParams); + + } + +} \ No newline at end of file diff --git a/src/main/java/org/datadog/jmxfetch/ConnectionManager.java b/src/main/java/org/datadog/jmxfetch/ConnectionManager.java deleted file mode 100644 index 02ec90dd6..000000000 --- a/src/main/java/org/datadog/jmxfetch/ConnectionManager.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.datadog.jmxfetch; - -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedHashMap; - -import org.apache.log4j.Logger; - - -/** - * Singleton used to share connections across instances in case you have multiple instances configured to the save MBeanServer (e.g. Solr and Tomcat) - */ -public class ConnectionManager { - private final static Logger LOGGER = Logger.getLogger(ConnectionManager.class.getName()); - public static final String PROCESS_NAME_REGEX = "process_name_regex"; - private static ConnectionManager connectionManager = null; - private HashMap cache; - - private ConnectionManager() { - cache = new HashMap(); - } - - public static ConnectionManager getInstance() { - if (connectionManager == null) { - connectionManager = new ConnectionManager(); - } - return connectionManager; - } - - private static String generateKey(LinkedHashMap connectionParams) { - if (connectionParams.get(PROCESS_NAME_REGEX) != null) { - return (String) connectionParams.get(PROCESS_NAME_REGEX); - } else if (connectionParams.get("jmx_url") != null) { - return (String) connectionParams.get("jmx_url"); - } - return connectionParams.get("host") + ":" + connectionParams.get("port") + ":" + connectionParams.get("user"); - } - - private Connection createConnection(LinkedHashMap connectionParams) throws IOException { - if (connectionParams.get(PROCESS_NAME_REGEX) != null) { - try { - Class.forName( "com.sun.tools.attach.AttachNotSupportedException" ); - } catch (ClassNotFoundException e) { - throw new IOException("Unable to find tools.jar. Are you using a JDK and did you set the pass to tools.jar ?"); - } - LOGGER.info("Connecting using Attach API"); - return new AttachApiConnection(connectionParams); - - } - LOGGER.info("Connecting using JMX Remote"); - return new RemoteConnection(connectionParams); - - } - - public Connection getConnection(LinkedHashMap connectionParams, boolean forceNewConnection) throws IOException { - String key = generateKey(connectionParams); - Connection existingConnection = cache.get(key); - if (existingConnection == null || !existingConnection.isAlive()) { - LOGGER.info("Connection closed or does not exist. Creating a new connection!"); - cache.put(key, createConnection(connectionParams)); - } else { - if (forceNewConnection) { - LOGGER.info("Forcing the creation of a new connection"); - cache.get(key).closeConnector(); - cache.put(key, createConnection(connectionParams)); - } else { - LOGGER.info("Connection already exists for key: " + key + " . Using it..."); - } - } - return cache.get(key); - } - -} \ No newline at end of file diff --git a/src/main/java/org/datadog/jmxfetch/Instance.java b/src/main/java/org/datadog/jmxfetch/Instance.java index 0f84e32fe..628f99e4d 100644 --- a/src/main/java/org/datadog/jmxfetch/Instance.java +++ b/src/main/java/org/datadog/jmxfetch/Instance.java @@ -125,9 +125,21 @@ public Instance(LinkedHashMap yamlInstance, LinkedHashMap) new YamlParser(this.getClass().getResourceAsStream("/jmx-2.yaml")).getParsedYaml())); } + public Connection getConnection(LinkedHashMap connectionParams, boolean forceNewConnection) throws IOException { + if (connection == null || !connection.isAlive()) { + LOGGER.info("Connection closed or does not exist. Creating a new connection!"); + return ConnectionFactory.createConnection(connectionParams); + } else if (forceNewConnection) { + LOGGER.info("Forcing the creation of a new connection"); + connection.closeConnector(); + return ConnectionFactory.createConnection(connectionParams); + } + return connection; + } + public void init(boolean forceNewConnection) throws IOException, FailedLoginException, SecurityException { LOGGER.info("Trying to connect to JMX Server at " + this.toString()); - connection = ConnectionManager.getInstance().getConnection(yaml, forceNewConnection); + connection = getConnection(yaml, forceNewConnection); LOGGER.info("Connected to JMX Server at " + this.toString()); this.refreshBeansList(); this.getMatchingAttributes();