Skip to content

Commit 38e92dc

Browse files
authored
Use temp properties file instead of providing agent arguments (#865)
closes #864
1 parent d54da16 commit 38e92dc

File tree

8 files changed

+104
-16
lines changed

8 files changed

+104
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* Error in log when setting [server_urls](https://www.elastic.co/guide/en/apm/agent/java/current/config-reporter.html#config-server-urls)
1919
to an empty string - `co.elastic.apm.agent.configuration.ApmServerConfigurationSource - Expected previousException not to be null`
2020
* Avoid terminating the TCP connection to APM Server when polling for configuration updates (#823)
21+
* Fixes potential segfault if attaching the agent with long arguments (#865)
2122

2223
# 1.9.0
2324

apm-agent-attach/src/main/java/co/elastic/apm/attach/ElasticApmAttacher.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -46,6 +46,13 @@
4646
*/
4747
public class ElasticApmAttacher {
4848

49+
/**
50+
* This key is very short on purpose.
51+
* The longer the agent argument ({@code -javaagent:<path>=<args>}), the greater the chance that the max length of the agent argument is reached.
52+
* Because of a bug in the {@linkplain ByteBuddyAgent.AttachmentProvider.ForEmulatedAttachment emulated attachment},
53+
* this can even lead to segfaults.
54+
*/
55+
private static final String TEMP_PROPERTIES_FILE_KEY = "c";
4956
private static final ByteBuddyAgent.AttachmentProvider ATTACHMENT_PROVIDER = new ByteBuddyAgent.AttachmentProvider.Compound(
5057
ByteBuddyAgent.AttachmentProvider.ForEmulatedAttachment.INSTANCE,
5158
ByteBuddyAgent.AttachmentProvider.ForModularizedVm.INSTANCE,
@@ -97,7 +104,32 @@ public static void attach(Map<String, String> configuration) {
97104
if (Boolean.getBoolean("ElasticApm.attached")) {
98105
return;
99106
}
100-
ByteBuddyAgent.attach(AgentJarFileHolder.INSTANCE.agentJarFile, ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE, toAgentArgs(configuration), ATTACHMENT_PROVIDER);
107+
File tempFile = createTempProperties(configuration);
108+
String agentArgs = tempFile == null ? null : TEMP_PROPERTIES_FILE_KEY + "=" + tempFile.getAbsolutePath();
109+
110+
ByteBuddyAgent.attach(AgentJarFileHolder.INSTANCE.agentJarFile, ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE, agentArgs, ATTACHMENT_PROVIDER);
111+
if (tempFile != null) {
112+
if (!tempFile.delete()) {
113+
tempFile.deleteOnExit();
114+
}
115+
}
116+
}
117+
118+
static File createTempProperties(Map<String, String> configuration) {
119+
File tempFile = null;
120+
if (!configuration.isEmpty()) {
121+
Properties properties = new Properties();
122+
properties.putAll(configuration);
123+
try {
124+
tempFile = File.createTempFile("elstcapm", ".tmp");
125+
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
126+
properties.store(outputStream, null);
127+
}
128+
} catch (IOException e) {
129+
e.printStackTrace();
130+
}
131+
}
132+
return tempFile;
101133
}
102134

103135
static String toAgentArgs(Map<String, String> configuration) {

apm-agent-attach/src/test/java/co/elastic/apm/attach/ElasticApmAttacherTest.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -27,6 +27,11 @@
2727
import org.junit.jupiter.api.Test;
2828
import wiremock.org.apache.commons.codec.digest.DigestUtils;
2929

30+
import java.io.File;
31+
import java.io.FileReader;
32+
import java.util.Map;
33+
import java.util.Properties;
34+
3035
import static org.assertj.core.api.Assertions.assertThat;
3136

3237
class ElasticApmAttacherTest {
@@ -36,4 +41,15 @@ void testHash() throws Exception {
3641
assertThat(ElasticApmAttacher.md5Hash(getClass().getResourceAsStream(ElasticApmAttacher.class.getSimpleName() + ".class")))
3742
.isEqualTo(DigestUtils.md5Hex(getClass().getResourceAsStream(ElasticApmAttacher.class.getSimpleName() + ".class")));
3843
}
44+
45+
@Test
46+
void testCreateTempProperties() throws Exception {
47+
File tempProperties = ElasticApmAttacher.createTempProperties(Map.of("foo", "bär"));
48+
assertThat(tempProperties).isNotNull();
49+
tempProperties.deleteOnExit();
50+
Properties properties = new Properties();
51+
properties.load(new FileReader(tempProperties));
52+
assertThat(properties.get("foo")).isEqualTo("bär");
53+
54+
}
3955
}

apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/AgentArgumentsConfigurationSource.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -27,6 +27,7 @@
2727
import org.stagemonitor.configuration.source.AbstractConfigurationSource;
2828
import org.stagemonitor.util.StringUtils;
2929

30+
import javax.annotation.Nullable;
3031
import java.util.HashMap;
3132
import java.util.Map;
3233

@@ -51,6 +52,7 @@ public static AgentArgumentsConfigurationSource parse(String agentAgruments) {
5152
}
5253

5354
@Override
55+
@Nullable
5456
public String getValue(String key) {
5557
return config.get(key);
5658
}

apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/source/PropertyFileConfigurationSource.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -78,7 +78,7 @@ public static Properties getFromClasspath(String classpathLocation, ClassLoader
7878
return null;
7979
}
8080

81-
private static Properties getFromFileSystem(String location) {
81+
public static Properties getFromFileSystem(String location) {
8282
Properties props = new Properties();
8383
try (InputStream input = new FileInputStream(location)) {
8484
props.load(input);

apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilder.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,15 @@
5353
import java.util.HashMap;
5454
import java.util.List;
5555
import java.util.Map;
56+
import java.util.Properties;
5657
import java.util.concurrent.TimeUnit;
5758

5859
public class ElasticApmTracerBuilder {
5960

61+
/**
62+
* See {@link co.elastic.apm.attach.ElasticApmAttacher#TEMP_PROPERTIES_FILE_KEY}
63+
*/
64+
private static final String TEMP_PROPERTIES_FILE_KEY = "c";
6065
private final Logger logger;
6166
@Nullable
6267
private ConfigurationRegistry configurationRegistry;
@@ -153,7 +158,12 @@ private ConfigurationRegistry getDefaultConfigurationRegistry(List<Configuration
153158
private List<ConfigurationSource> getConfigSources(@Nullable String agentArguments) {
154159
List<ConfigurationSource> result = new ArrayList<>();
155160
if (agentArguments != null && !agentArguments.isEmpty()) {
156-
result.add(AgentArgumentsConfigurationSource.parse(agentArguments));
161+
AgentArgumentsConfigurationSource agentArgs = AgentArgumentsConfigurationSource.parse(agentArguments);
162+
result.add(agentArgs);
163+
ConfigurationSource attachmentConfig = getAttachmentArguments(agentArgs.getValue(TEMP_PROPERTIES_FILE_KEY));
164+
if (attachmentConfig != null) {
165+
result.add(attachmentConfig);
166+
}
157167
}
158168
result.add(new PrefixingConfigurationSourceWrapper(new SystemPropertyConfigurationSource(), "elastic.apm."));
159169
result.add(new PrefixingConfigurationSourceWrapper(new EnvironmentVariableConfigurationSource(), "ELASTIC_APM_"));
@@ -180,4 +190,22 @@ public String getName() {
180190
return result;
181191
}
182192

193+
/**
194+
* Loads the configuration from the temporary properties file created by ElasticApmAttacher
195+
*/
196+
@Nullable
197+
private ConfigurationSource getAttachmentArguments(@Nullable String configFileLocation) {
198+
if (configFileLocation != null) {
199+
Properties fromFileSystem = PropertyFileConfigurationSource.getFromFileSystem(configFileLocation);
200+
if (fromFileSystem != null) {
201+
SimpleSource attachmentConfig = new SimpleSource("Attachment configuration");
202+
for (String key : fromFileSystem.stringPropertyNames()) {
203+
attachmentConfig.add(key, fromFileSystem.getProperty(key));
204+
}
205+
return attachmentConfig;
206+
}
207+
}
208+
return null;
209+
}
210+
183211
}

apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilderTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
* the Apache License, Version 2.0 (the "License"); you may
1212
* not use this file except in compliance with the License.
1313
* You may obtain a copy of the License at
14-
*
14+
*
1515
* http://www.apache.org/licenses/LICENSE-2.0
16-
*
16+
*
1717
* Unless required by applicable law or agreed to in writing,
1818
* software distributed under the License is distributed on an
1919
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -39,7 +39,6 @@
3939

4040
class ElasticApmTracerBuilderTest {
4141

42-
4342
@AfterEach
4443
void tearDown() {
4544
System.clearProperty("elastic.apm." + CoreConfiguration.CONFIG_FILE);
@@ -59,4 +58,14 @@ void testConfigFileLocation(@TempDir Path tempDir) throws IOException {
5958
configurationRegistry.getString(CoreConfiguration.CONFIG_FILE);
6059
assertThat(configurationRegistry.getString(CoreConfiguration.CONFIG_FILE)).isEqualTo(file.toString());
6160
}
61+
62+
@Test
63+
void testTempAttacherPropertiesFile(@TempDir Path tempDir) throws Exception {
64+
Path file = Files.createFile(tempDir.resolve("elstcapm.tmp"));
65+
Files.write(file, List.of("instrument=false"));
66+
67+
ConfigurationRegistry configurationRegistry = new ElasticApmTracerBuilder("c=" + file.toAbsolutePath()).build().getConfigurationRegistry();
68+
CoreConfiguration config = configurationRegistry.getConfig(CoreConfiguration.class);
69+
assertThat(config.isInstrument()).isFalse();
70+
}
6271
}

docs/configuration.asciidoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ you should add an additional entry to this list (make sure to also include the d
358358
==== `disable_instrumentations`
359359

360360
A list of instrumentations which should be disabled.
361-
Valid options are `annotations`, `apache-httpclient`, `asynchttpclient`, `concurrent`, `elasticsearch-restclient`, `exception-handler`, `executor`, `hibernate-search`, `http-client`, `incubating`, `jax-rs`, `jax-ws`, `jdbc`, `jedis`, `jms`, `jsf`, `logging`, `okhttp`, `opentracing`, `public-api`, `quartz`, `redis`, `render`, `scheduled`, `servlet-api`, `servlet-api-async`, `servlet-input-stream`, `slf4j`, `spring-mvc`, `spring-resttemplate`, `spring-service-name`, `spring-view-render`, `urlconnection`.
361+
Valid options are `annotations`, `apache-httpclient`, `asynchttpclient`, `concurrent`, `elasticsearch-restclient`, `exception-handler`, `executor`, `hibernate-search`, `http-client`, `incubating`, `jax-rs`, `jax-ws`, `jdbc`, `jedis`, `jms`, `jsf`, `logging`, `mule`, `okhttp`, `opentracing`, `public-api`, `quartz`, `redis`, `render`, `scheduled`, `servlet-api`, `servlet-api-async`, `servlet-input-stream`, `slf4j`, `spring-mvc`, `spring-resttemplate`, `spring-service-name`, `spring-view-render`, `urlconnection`.
362362
If you want to try out incubating features,
363363
set the value to an empty string.
364364

@@ -1551,7 +1551,7 @@ The default unit for this option is `ms`
15511551
# sanitize_field_names=password,passwd,pwd,secret,*key,*token*,*session*,*credit*,*card*,authorization,set-cookie
15521552
15531553
# A list of instrumentations which should be disabled.
1554-
# Valid options are `annotations`, `apache-httpclient`, `asynchttpclient`, `concurrent`, `elasticsearch-restclient`, `exception-handler`, `executor`, `hibernate-search`, `http-client`, `incubating`, `jax-rs`, `jax-ws`, `jdbc`, `jedis`, `jms`, `jsf`, `logging`, `okhttp`, `opentracing`, `public-api`, `quartz`, `redis`, `render`, `scheduled`, `servlet-api`, `servlet-api-async`, `servlet-input-stream`, `slf4j`, `spring-mvc`, `spring-resttemplate`, `spring-service-name`, `spring-view-render`, `urlconnection`.
1554+
# Valid options are `annotations`, `apache-httpclient`, `asynchttpclient`, `concurrent`, `elasticsearch-restclient`, `exception-handler`, `executor`, `hibernate-search`, `http-client`, `incubating`, `jax-rs`, `jax-ws`, `jdbc`, `jedis`, `jms`, `jsf`, `logging`, `mule`, `okhttp`, `opentracing`, `public-api`, `quartz`, `redis`, `render`, `scheduled`, `servlet-api`, `servlet-api-async`, `servlet-input-stream`, `slf4j`, `spring-mvc`, `spring-resttemplate`, `spring-service-name`, `spring-view-render`, `urlconnection`.
15551555
# If you want to try out incubating features,
15561556
# set the value to an empty string.
15571557
#

0 commit comments

Comments
 (0)