diff --git a/CHANGELOG.md b/CHANGELOG.md index 92080e36bb..ad8cbb4470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ NOTE: This feature is currently marked as "Incubating" and is disabled by default. In order to enable, it is required to set the [`disable_instrumentations`](https://www.elastic.co/guide/en/apm/agent/java/1.x/config-core.html#config-disable-instrumentations) configuration property to an empty string. + * Property File will now be reloaded every minute(works only for files not on the classpath) ## Bug Fixes * ClassCastException related to async instrumentation of Pilotfish Executor causing thread hang (applied workaround) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSource.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSource.java index 35bef7d206..84db17b6fb 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSource.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSource.java @@ -27,11 +27,14 @@ import org.stagemonitor.configuration.source.AbstractConfigurationSource; +import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Properties; +import java.util.Timer; +import java.util.TimerTask; /** * A variation of {@link org.stagemonitor.configuration.source.PropertyFileConfigurationSource} (under Apache license 2.0) @@ -41,12 +44,23 @@ *
*/ public final class PropertyFileConfigurationSource extends AbstractConfigurationSource { - + private static final long DEFAULT_REFRESH_TIME = 60_000;// 1 Minute private final String location; + private final File configFile; private Properties properties; + + private final Timer timer = new Timer("ApmConfigRefreshTimer", true); + private long lastmodified; public PropertyFileConfigurationSource(String location) { + this(location, DEFAULT_REFRESH_TIME); + } + + public PropertyFileConfigurationSource(String location, long refreshTimeMs) { this.location = location; + this.configFile = new File(location); + lastmodified = configFile.lastModified(); + timer.schedule(new FileWatcherTask(), refreshTimeMs); reload(); } @@ -109,5 +123,14 @@ public String getValue(String key) { return properties.getProperty(key); } + private class FileWatcherTask extends TimerTask { + + @Override + public void run() { + if(configFile.lastModified() > lastmodified) { + reload(); + } + } + } } diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSourceTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSourceTest.java new file mode 100644 index 0000000000..75cbb81b9f --- /dev/null +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSourceTest.java @@ -0,0 +1,62 @@ +/*- + * #%L + * Elastic APM Java agent + * %% + * Copyright (C) 2018 - 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.apm.agent.configuration.source; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class PropertyFileConfigurationSourceTest { + private PropertyFileConfigurationSource source = null; + private File configFile; + + void writeToFile(String text) throws FileNotFoundException { + try (PrintWriter out = new PrintWriter(configFile.getAbsolutePath())) { + out.println(text); + } + } + + @BeforeEach + void setUp() throws IOException { + configFile = File.createTempFile("elasticapm-", ".properties"); + configFile.deleteOnExit(); + writeToFile("server_urls=https://old.value.com"); + source = new PropertyFileConfigurationSource(configFile.getAbsolutePath(), 500); + } + + @Test + void testReload() throws InterruptedException, FileNotFoundException { + assertThat(source.getValue("server_urls")).isEqualTo("https://old.value.com"); + writeToFile("server_urls=https://new.value.com"); + Thread.sleep(500); + assertThat(source.getValue("server_urls")).isEqualTo("https://new.value.com"); + } +} \ No newline at end of file diff --git a/docs/configuration.asciidoc b/docs/configuration.asciidoc index 1754042c6a..3372a7e666 100644 --- a/docs/configuration.asciidoc +++ b/docs/configuration.asciidoc @@ -20,8 +20,8 @@ The first configuration sources override the configuration values of over the la No prefix is required for the configuration keys. Configuration options marked with Dynamic true can be changed at runtime -via configuration sources which support dynamic reloading. The `elasticapm.properties` file is -such source. Java system properties can be dynamic as well by being set from within the application. +via configuration sources which support dynamic reloading. The `elasticapm.properties` will be scanned +for changes every minute and reloaded if required(does not work for config on classpath). Java system properties can be dynamic as well by being set from within the application. In order to get started with Elastic APM, the most important configuration options are <