-
Notifications
You must be signed in to change notification settings - Fork 987
Add capability for invokedynamic InstrumentationModules to inject proxies #9565
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
Merged
trask
merged 21 commits into
open-telemetry:main
from
JonasKunz:instrumentation-proxies
Oct 19, 2023
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
25a8763
Implemented invokedynamic proxy injection for InstrumentationModules
JonasKunz c3a6a13
Merge remote-tracking branch 'otel/main' into instrumentation-proxies
JonasKunz 7a03962
Comments and spotless
JonasKunz 9209cc6
Remove unnecessary subpackage
JonasKunz a54e730
Added missing javadoc
JonasKunz 57da000
spotless fixes
JonasKunz 1aa563e
Enable AWS SDK instrumentation for indy via proxy mechanism
JonasKunz d48563c
Moved injection to new ExtendedInstrumentationModule
JonasKunz 43fc618
Javadoc review fixes
JonasKunz 80dee2f
Merge remote-tracking branch 'otel/main' into instrumentation-proxies
JonasKunz 5adf59e
Fix AWS tests for indy, enable for testing with indy flag
JonasKunz ac77780
Moved and renamed ExtendedInstrumentationModule
JonasKunz 6b9f958
Added default method for generating proxy with same name
JonasKunz 466ca1b
Revert AWS changes
JonasKunz 1b3352b
Added proxy in log4j 2.17 instrumentation
JonasKunz 85829bb
Spotless fixes
JonasKunz 4e541ca
Merge remote-tracking branch 'otel/main' into instrumentation-proxies
JonasKunz 0a540a2
Merge remote-tracking branch 'otel/main' into instrumentation-proxies
JonasKunz cbe27b3
Remove type pool caching
JonasKunz 0a3b736
typo fix
JonasKunz a788f7c
Merge remote-tracking branch 'otel/HEAD' into instrumentation-proxies
JonasKunz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
...metry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.extension.instrumentation.internal; | ||
|
||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector; | ||
|
||
/** | ||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at | ||
* any time. | ||
*/ | ||
public interface ExperimentalInstrumentationModule { | ||
|
||
/** | ||
* Only functional for Modules where {@link InstrumentationModule#isIndyModule()} returns {@code | ||
* true}. | ||
* | ||
* <p>Normally, helper and advice classes are loaded in a child classloader of the instrumented | ||
* classloader. This method allows to inject classes directly into the instrumented classloader | ||
* instead. | ||
* | ||
* @param injector the builder for injecting classes | ||
*/ | ||
default void injectClasses(ClassInjector injector) {} | ||
} |
39 changes: 39 additions & 0 deletions
39
...o/opentelemetry/javaagent/extension/instrumentation/internal/injection/ClassInjector.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.extension.instrumentation.internal.injection; | ||
|
||
/** | ||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at | ||
* any time. | ||
*/ | ||
public interface ClassInjector { | ||
|
||
/** | ||
* Create a builder for a proxy class which will be injected into the instrumented {@link | ||
* ClassLoader}. The generated proxy will delegate to the original class, which is loaded in a | ||
* separate classloader. | ||
* | ||
* <p>This removes the need for the proxied class and its dependencies to be visible (just like | ||
* Advices) to the instrumented ClassLoader. | ||
* | ||
* @param classToProxy the fully qualified name of the class for which a proxy will be generated | ||
* @param newProxyName the fully qualified name to use for the generated proxy | ||
* @return a builder for further customizing the proxy. {@link | ||
* ProxyInjectionBuilder#inject(InjectionMode)} must be called to actually inject the proxy. | ||
*/ | ||
ProxyInjectionBuilder proxyBuilder(String classToProxy, String newProxyName); | ||
|
||
/** | ||
* Same as invoking {@link #proxyBuilder(String, String)}, but the resulting proxy will have the | ||
* same name as the proxied class. | ||
* | ||
* @param classToProxy the fully qualified name of the class for which a proxy will be generated | ||
* @return a builder for further customizing and injecting the proxy | ||
*/ | ||
default ProxyInjectionBuilder proxyBuilder(String classToProxy) { | ||
return proxyBuilder(classToProxy, classToProxy); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...o/opentelemetry/javaagent/extension/instrumentation/internal/injection/InjectionMode.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.extension.instrumentation.internal.injection; | ||
|
||
/** | ||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at | ||
* any time. | ||
*/ | ||
public enum InjectionMode { | ||
CLASS_ONLY | ||
// TODO: implement the modes RESOURCE_ONLY and CLASS_AND_RESOURCE | ||
// This will require a custom URL implementation for byte arrays, similar to how bytebuddy's | ||
// ByteArrayClassLoader does it | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
...lemetry/javaagent/extension/instrumentation/internal/injection/ProxyInjectionBuilder.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.extension.instrumentation.internal.injection; | ||
|
||
/** | ||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at | ||
* any time. | ||
*/ | ||
public interface ProxyInjectionBuilder { | ||
|
||
void inject(InjectionMode mode); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
.../main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassInjectorImpl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.tooling.instrumentation.indy; | ||
|
||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector; | ||
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode; | ||
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ProxyInjectionBuilder; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.pool.TypePool; | ||
|
||
public class ClassInjectorImpl implements ClassInjector { | ||
|
||
private final InstrumentationModule instrumentationModule; | ||
|
||
private final Map<String, Function<ClassLoader, byte[]>> classesToInject; | ||
|
||
private final IndyProxyFactory proxyFactory; | ||
|
||
public ClassInjectorImpl(InstrumentationModule module) { | ||
instrumentationModule = module; | ||
classesToInject = new HashMap<>(); | ||
proxyFactory = IndyBootstrap.getProxyFactory(module); | ||
} | ||
|
||
public Map<String, Function<ClassLoader, byte[]>> getClassesToInject() { | ||
return classesToInject; | ||
} | ||
|
||
@Override | ||
public ProxyInjectionBuilder proxyBuilder(String classToProxy, String newProxyName) { | ||
return new ProxyBuilder(classToProxy, newProxyName); | ||
} | ||
|
||
private class ProxyBuilder implements ProxyInjectionBuilder { | ||
|
||
private final String classToProxy; | ||
private final String proxyClassName; | ||
|
||
ProxyBuilder(String classToProxy, String proxyClassName) { | ||
this.classToProxy = classToProxy; | ||
this.proxyClassName = proxyClassName; | ||
} | ||
|
||
@Override | ||
public void inject(InjectionMode mode) { | ||
if (mode != InjectionMode.CLASS_ONLY) { | ||
throw new UnsupportedOperationException("Not yet implemented"); | ||
} | ||
classesToInject.put( | ||
proxyClassName, | ||
cl -> { | ||
TypePool typePool = IndyModuleTypePool.get(cl, instrumentationModule); | ||
TypeDescription proxiedType = typePool.describe(classToProxy).resolve(); | ||
return proxyFactory.generateProxy(proxiedType, proxyClassName).getBytes(); | ||
}); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.