-
Couldn't load subscription status.
- Fork 4
fix: AWS SdkV2 support with auto-trace #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
010911c
c0204a4
f6d3894
922499c
7f5faa4
42d1171
a8e9503
1c77096
44db921
15f901c
0333983
c967c86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,19 +37,19 @@ public static void agentmain(String agentArgs, Instrumentation inst) { | |
| if ("lib".equalsIgnoreCase(agentArgs)) { | ||
| urls = getUrls(); | ||
| } else { | ||
| urls = | ||
| new URL[] { | ||
| new File("/var/task/").toURI().toURL(), | ||
| new File(LUMIGO_JAVA_TRACER_PATH).toURI().toURL() | ||
| }; | ||
| List<URL> jars = new LinkedList<>(); | ||
| jars.add(new File("/var/task/").toURI().toURL()); | ||
| if (isAutoTrace()) { | ||
| jars.add(new File(LUMIGO_JAVA_TRACER_PATH).toURI().toURL()); | ||
| installTracerJar(inst); | ||
| } | ||
| urls = jars.toArray(new URL[jars.size()]); | ||
| } | ||
| installTracerJar(inst); | ||
| URLClassLoader newClassLoader = new URLClassLoader(urls, null); | ||
| Thread.currentThread().setContextClassLoader(newClassLoader); | ||
| final Class<?> loader = | ||
| newClassLoader.loadClass("io.lumigo.core.instrumentation.agent.Loader"); | ||
| final Method instrument = loader.getMethod("instrument", Instrumentation.class); | ||
| instrument.invoke(null, inst); | ||
| URLClassLoader agentClassLoader = new AgentClassLoader(urls, ClassLoader.getSystemClassLoader()); | ||
| final Class<?> instrumentationLoader = | ||
| agentClassLoader.loadClass("io.lumigo.core.instrumentation.agent.Loader"); | ||
| final Method instrument = instrumentationLoader.getMethod("instrument", Instrumentation.class, ClassLoader.class); | ||
| instrument.invoke(null, inst, agentClassLoader); | ||
| } catch (Exception e) { | ||
| e.printStackTrace(); | ||
| } | ||
|
|
@@ -89,4 +89,9 @@ public static boolean isKillSwitchOn() { | |
| String value = System.getenv("LUMIGO_SWITCH_OFF"); | ||
| return "true".equalsIgnoreCase(value); | ||
| } | ||
|
|
||
| public static boolean isAutoTrace() { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to inject the jar only when we use autoTrace |
||
| String value = System.getenv("JAVA_TOOL_OPTIONS"); | ||
| return !value.contains("allowAttachSelf=true"); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| package io.lumigo.agent; | ||
|
|
||
| import java.net.URL; | ||
| import java.net.URLClassLoader; | ||
|
|
||
| /** | ||
| * This class is refered from : | ||
| * https://github.com/gaoxingliang/tracing-research/blob/main/bootstrap/src/main/java/com/zoomphant/agent/trace/boost/StandaloneAgentClassloader.java | ||
| */ | ||
| public class AgentClassLoader extends URLClassLoader { | ||
|
|
||
| private final ClassLoader additionalClassloader; | ||
|
|
||
| public AgentClassLoader(URL[] urls, ClassLoader additionalClassloader) { | ||
| super(urls, ClassLoader.getSystemClassLoader().getParent()); | ||
| this.additionalClassloader = additionalClassloader; | ||
| } | ||
|
|
||
| @Override | ||
| protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { | ||
| Class<?> loadedClass = findLoadedClass(name); | ||
| if (loadedClass != null) { | ||
| return loadedClass; | ||
| } | ||
|
|
||
| if (name != null && (name.startsWith("sun.") || name.startsWith("java."))) { | ||
| return super.loadClass(name, resolve); | ||
| } | ||
|
|
||
| ClassLoader platformClassLoader = safeGetPlatformClassLoader(); | ||
| if (platformClassLoader != null) { | ||
| // try load from platform class loader | ||
| try { | ||
| loadedClass = platformClassLoader.loadClass(name); | ||
| return loadedClass; | ||
| } catch (Exception ignore) { | ||
| } | ||
| } | ||
| if (additionalClassloader != null) { | ||
| // try load from additional classloader | ||
| try { | ||
| loadedClass = additionalClassloader.loadClass(name); | ||
| return loadedClass; | ||
| } catch (Exception ignore) { | ||
| } | ||
| } | ||
| try { | ||
| loadedClass = this.getParent().loadClass(name); | ||
| return loadedClass; | ||
| } catch (Exception e) { | ||
| } | ||
| try { | ||
| Class<?> aClass = findClass(name); | ||
| if (resolve) { | ||
| resolveClass(aClass); | ||
| } | ||
| return aClass; | ||
| } catch (Exception e) { | ||
| // ignore | ||
| } | ||
| return super.loadClass(name, resolve); | ||
| } | ||
|
|
||
| private ClassLoader safeGetPlatformClassLoader() { | ||
| // get platform class loader with reflection | ||
| try { | ||
| return (ClassLoader) ClassLoader.class.getDeclaredMethod("getPlatformClassLoader").invoke(null); | ||
| } catch (Exception e) { | ||
| return null; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,10 +12,10 @@ | |
| import net.bytebuddy.description.type.TypeDescription; | ||
| import net.bytebuddy.matcher.ElementMatcher; | ||
| import org.pmw.tinylog.Logger; | ||
| import software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder; | ||
| import software.amazon.awssdk.core.interceptor.Context; | ||
| import software.amazon.awssdk.core.interceptor.ExecutionAttributes; | ||
| import software.amazon.awssdk.core.interceptor.ExecutionInterceptor; | ||
| import software.amazon.awssdk.http.SdkHttpRequest; | ||
|
|
||
| public class AmazonHttpClientV2Instrumentation implements LumigoInstrumentationApi { | ||
|
|
||
|
|
@@ -28,12 +28,13 @@ public ElementMatcher<TypeDescription> getTypeMatcher() { | |
| } | ||
|
|
||
| @Override | ||
| public AgentBuilder.Transformer.ForAdvice getTransformer() { | ||
| public AgentBuilder.Transformer.ForAdvice getTransformer(ClassLoader classLoader) { | ||
| return new AgentBuilder.Transformer.ForAdvice() | ||
| .include(Loader.class.getClassLoader()) | ||
| .include(classLoader) | ||
| .advice( | ||
| isMethod().and(named("resolveExecutionInterceptors")), | ||
| AmazonHttpClientV2Advice.class.getName()); | ||
| AmazonHttpClientV2Instrumentation.class.getName() | ||
| + "$AmazonHttpClientV2Advice"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unused") | ||
|
|
@@ -61,20 +62,11 @@ public static class TracingExecutionInterceptor implements ExecutionInterceptor | |
| public void beforeExecution( | ||
| final Context.BeforeExecution context, | ||
| final ExecutionAttributes executionAttributes) { | ||
| startTimeMap.put(context.request().hashCode(), System.currentTimeMillis()); | ||
| } | ||
|
|
||
| @Override | ||
| public SdkHttpRequest modifyHttpRequest( | ||
| Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) { | ||
| try { | ||
| SdkHttpRequest.Builder requestBuilder = context.httpRequest().toBuilder(); | ||
| requestBuilder.appendHeader("X-Amzn-Trace-Id", spansContainer.getPatchedRoot()); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We dont need to inject traceId because its auto injected by aws |
||
| return requestBuilder.build(); | ||
| startTimeMap.put(context.request().hashCode(), System.currentTimeMillis()); | ||
| } catch (Throwable e) { | ||
| Logger.debug("Unable to inject trace header", e); | ||
| Logger.error(e, "Failed save trace context"); | ||
| } | ||
| return context.httpRequest(); | ||
| } | ||
|
|
||
| @Override | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we somehow know it and print it as warn?
I mean, if the sdk1 exist, and we were imported with a layer