diff --git a/README b/README index 85206ae..c697572 100644 --- a/README +++ b/README @@ -62,7 +62,7 @@ Configuration (so that metrics from different JVMs on the same host can be determined) - XML Configuation File + XML Configuration File JMXetric schedules a number of "samples", that queries a list of "mbeans", that have "attributes". diff --git a/src/main/java/info/ganglia/jmxetric/BackgroundConfigurationRefresher.java b/src/main/java/info/ganglia/jmxetric/BackgroundConfigurationRefresher.java new file mode 100644 index 0000000..26ea905 --- /dev/null +++ b/src/main/java/info/ganglia/jmxetric/BackgroundConfigurationRefresher.java @@ -0,0 +1,113 @@ +package info.ganglia.jmxetric; + +import info.ganglia.gmetric4j.gmetric.GMetric; +import org.xml.sax.InputSource; + +import org.w3c.dom.Node; +import java.io.*; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Timer; +import java.util.TimerTask; + + +public class BackgroundConfigurationRefresher extends XMLConfigurationService { + + private JMXetricAgent agent = null; + private final InputSource inputSource; + private final CommandLineArgs args; + private final String agentArgs; + private int pollingFrequency; + private int lastHash = -1; + + public BackgroundConfigurationRefresher(String agentArgs) { + this.agentArgs = agentArgs; + this.args = new CommandLineArgs(agentArgs); + this.inputSource = new InputSource(args.getConfig()); + } + + public void initialize() throws Exception { + Node root = getXmlNode("/jmxetric-config/refreshconfig", inputSource); + + startNewAgent(); + + if (isEnabled(root)) { + pollingFrequency = getPollingFrequencySeconds(root); + startBackgroundThread(); + } + } + + private void startNewAgent() throws Exception { + if (agent != null) { + agent.stop(); + GMetric gmetric = agent.getGmetric(); + if (gmetric != null) { + gmetric.close(); + } + agent = null; + } + + agent = new JMXetricAgent(); + XMLConfigurationService.configure(agent, agentArgs); + agent.start(); + lastHash = getConfigHash(); + } + + private boolean isEnabled(Node root) { + return selectParameterFromNode(root, "enabled", "false").toLowerCase().equals("true"); + } + + private int getPollingFrequencySeconds(Node root) { + return Integer.parseInt(selectParameterFromNode(root, "frequency", "5")); + } + + private int getConfigHash() throws NoSuchAlgorithmException, IOException { + MessageDigest md = MessageDigest.getInstance("MD5"); + + File theFile = new File(args.getConfig()); + InputStream is = new FileInputStream(theFile); + + try { + DigestInputStream dis = new DigestInputStream(is, md); + try { + while (dis.read() != -1) { + // NOTE: This reads the entire file, that's why the while loop is blank. + } + + byte[] digest = md.digest(); + return new String(digest).hashCode(); + } finally { + dis.close(); + } + } finally { + is.close(); + } + } + + private void startBackgroundThread() { + TimerTask task = new TimerTask() { + @Override + public void run() { + try { + int currentHash = getConfigHash(); + if (currentHash != lastHash) { + System.out.println("The file has changed. Initializing a dynamic reload for the instance."); + startNewAgent(); + } + } catch (FileNotFoundException e) { + System.out.println(String.format("Could not find the config file: %s", args.getConfig())); + } catch (NoSuchAlgorithmException e) { + System.out.println("Your system does not contain the MD5 digest algorithm."); + } catch (Exception e) { + System.out.println("Unknown exception encountered."); + e.printStackTrace(); + } + } + }; + + Timer timer = new Timer(true); + timer.scheduleAtFixedRate(task, pollingFrequency * 1000, pollingFrequency * 1000); + } + +} diff --git a/src/main/java/info/ganglia/jmxetric/GangliaXmlConfigurationService.java b/src/main/java/info/ganglia/jmxetric/GangliaXmlConfigurationService.java index 601db29..7286665 100644 --- a/src/main/java/info/ganglia/jmxetric/GangliaXmlConfigurationService.java +++ b/src/main/java/info/ganglia/jmxetric/GangliaXmlConfigurationService.java @@ -126,9 +126,9 @@ private int getPort() { /** * UDPAddressingMode to use for reporting * - * @return {@link info.ganglia.gmetric4j.gmetric.UDPAddressingMode.UNICAST} + * @return {@link info.ganglia.gmetric4j.gmetric.GMetric.UDPAddressingMode.UNICAST} * or - * {@link info.ganglia.gmetric4j.gmetric.UDPAddressingMode.MULTICAST} + * {@link info.ganglia.gmetric4j.gmetric.GMetric.UDPAddressingMode.MULTICAST} */ private UDPAddressingMode getAddressingMode() { String mode = getGangliaConfig(args.getMode(), ganglia, "mode", @@ -206,4 +206,4 @@ String getConfigString() throws XPathExpressionException { buf.append(" spoof=").append(spoof); return buf.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/info/ganglia/jmxetric/JMXetricAgent.java b/src/main/java/info/ganglia/jmxetric/JMXetricAgent.java index fb14b8d..3c2517d 100644 --- a/src/main/java/info/ganglia/jmxetric/JMXetricAgent.java +++ b/src/main/java/info/ganglia/jmxetric/JMXetricAgent.java @@ -45,11 +45,8 @@ public static void main(String[] args) throws Exception { */ public static void premain(String agentArgs, Instrumentation inst) { System.out.println(STARTUP_NOTICE) ; - JMXetricAgent a = null ; try { - a = new JMXetricAgent(); - XMLConfigurationService.configure(a, agentArgs); - a.start(); + new BackgroundConfigurationRefresher(agentArgs).initialize(); } catch ( Exception ex ) { // log.severe("Exception starting JMXetricAgent"); ex.printStackTrace(); diff --git a/src/test/java/info/ganglia/jmxetric/JMXetricAgentIT.java b/src/test/java/info/ganglia/jmxetric/JMXetricAgentIT.java index c2412f8..0f1edf1 100644 --- a/src/test/java/info/ganglia/jmxetric/JMXetricAgentIT.java +++ b/src/test/java/info/ganglia/jmxetric/JMXetricAgentIT.java @@ -4,8 +4,6 @@ import info.ganglia.gmetric4j.gmetric.GMetricResult; -import info.ganglia.jmxetric.JMXetricAgent; -import info.ganglia.jmxetric.XMLConfigurationService; import java.lang.management.ManagementFactory; diff --git a/src/test/resources/jmxetric_test.xml b/src/test/resources/jmxetric_test.xml index 71ce6da..eb0c416 100644 --- a/src/test/resources/jmxetric_test.xml +++ b/src/test/resources/jmxetric_test.xml @@ -1,6 +1,6 @@ + @@ -28,6 +28,9 @@ + + + ]> @@ -74,11 +77,12 @@ - - - + + + +