Skip to content

Commit 1c5934d

Browse files
authored
Use emulated attach as fallback (elastic#2385)
* use emulated attach as fallback on attach itself * update changelog
1 parent c61a301 commit 1c5934d

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ endif::[]
2525
2626
[float]
2727
===== Bug fixes
28+
* Fix runtime attach with some docker images - {pull}2385[#2385]
2829
2930
[[release-notes-1.x]]
3031
=== Java Agent version 1.x

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,34 @@ public static void attach(String pid, Map<String, String> configuration, File ag
151151
File tempFile = createTempProperties(configuration, null);
152152
String agentArgs = tempFile == null ? null : TEMP_PROPERTIES_FILE_KEY + "=" + tempFile.getAbsolutePath();
153153

154-
ByteBuddyAgent.attach(agentJarFile, pid, agentArgs, ElasticAttachmentProvider.get());
154+
attachWithFallback(agentJarFile, pid, agentArgs);
155155
if (tempFile != null) {
156156
if (!tempFile.delete()) {
157157
tempFile.deleteOnExit();
158158
}
159159
}
160160
}
161161

162+
private static void attachWithFallback(File agentJarFile, String pid, String agentArgs) {
163+
try {
164+
// while the native providers may report to be supported and appear to work properly, in practice there are
165+
// cases (Docker without '--init' option on some JDK images like 'openjdk:8-jdk-alpine') where the accessor
166+
// returned by the provider will not work as expected at attachment time.
167+
ByteBuddyAgent.attach(agentJarFile, pid, agentArgs, ElasticAttachmentProvider.get());
168+
} catch (RuntimeException e1) {
169+
try {
170+
ByteBuddyAgent.attach(agentJarFile, pid, agentArgs, ElasticAttachmentProvider.getFallback());
171+
} catch (RuntimeException e2) {
172+
// output the two exceptions for debugging
173+
System.err.println("Unable to attach with fallback provider:");
174+
e2.printStackTrace();
175+
176+
System.err.println("Unable to attach with regular provider:");
177+
e1.printStackTrace();
178+
}
179+
}
180+
}
181+
162182
/**
163183
* Attaches the agent to a remote JVM
164184
*
@@ -168,7 +188,7 @@ public static void attach(String pid, Map<String, String> configuration, File ag
168188
*/
169189
@Deprecated
170190
public static void attach(String pid, String agentArgs) {
171-
ByteBuddyAgent.attach(AgentJarFileHolder.INSTANCE.agentJarFile, pid, agentArgs, ElasticAttachmentProvider.get());
191+
attachWithFallback(AgentJarFileHolder.INSTANCE.agentJarFile, pid, agentArgs);
172192
}
173193

174194
public static File getBundledAgentJarFile() {

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ public class ElasticAttachmentProvider {
2727

2828
private static ByteBuddyAgent.AttachmentProvider provider;
2929

30+
private static ByteBuddyAgent.AttachmentProvider fallback;
31+
3032
/**
3133
* Initializes attachment provider, this method can only be called once as it loads native code.
32-
*
3334
*/
3435
private synchronized static void init() {
3536
if (provider != null) {
@@ -44,14 +45,21 @@ private synchronized static void init() {
4445
new CachedAttachmentProvider(ByteBuddyAgent.AttachmentProvider.ForStandardToolsJarVm.MACINTOSH),
4546
new CachedAttachmentProvider(ByteBuddyAgent.AttachmentProvider.ForUserDefinedToolsJar.INSTANCE),
4647
// only use emulated attach last, as native attachment providers should be preferred
47-
ByteBuddyAgent.AttachmentProvider.ForEmulatedAttachment.INSTANCE);
48+
getFallback());
4849

4950

5051
provider = new ByteBuddyAgent.AttachmentProvider.Compound(providers);
5152
}
5253

54+
private synchronized static void initFallback(){
55+
if (fallback != null) {
56+
throw new IllegalStateException("ElasticAttachmentProvider.initFallback() should only be called once");
57+
}
58+
fallback = ByteBuddyAgent.AttachmentProvider.ForEmulatedAttachment.INSTANCE;
59+
}
60+
5361
/**
54-
* Get (and optionally initialize) attachment provider, will internally call {@link #init()} if not already called
62+
* Get (and optionally initialize) attachment provider
5563
*
5664
* @return attachment provider
5765
*/
@@ -62,4 +70,16 @@ public synchronized static ByteBuddyAgent.AttachmentProvider get() {
6270
return provider;
6371
}
6472

73+
/**
74+
* Get (and optionally initialize) fallback (emulated) attachment provider
75+
*
76+
* @return fallback (emulated) attachment provider
77+
*/
78+
public synchronized static ByteBuddyAgent.AttachmentProvider getFallback() {
79+
if (fallback == null) {
80+
initFallback();
81+
}
82+
return fallback;
83+
}
84+
6585
}

0 commit comments

Comments
 (0)