-
Notifications
You must be signed in to change notification settings - Fork 1k
Library instrumentation for Java Servlet 3.0 Filters. #15188
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: main
Are you sure you want to change the base?
Library instrumentation for Java Servlet 3.0 Filters. #15188
Conversation
Includes handling for attaching all the async stuff, but can't support everything the java agent does. I could use help figuring out the right way to shadow all the necessary dependencies. I'm a bit rusty with our shadow usage. Depending on how aggressive we want to be, the dependency could be reversed so that `:servlet-3.0:javaagent` depends on this new module, but that's more aggressive. Perhaps shadow could prune unused classes (with `minimize()`) instead. Once we get the modules figured out, I can work on adding some unit tests. If we like this approach, it could probably be copied and modified pretty easily to support servlet 5, but I'm not familiar with that instrumentation.
You shouldn't shadow anything. If you need to share code you can extract common code between the javaagent and library instrumentation into separate module or make javaagent module depend on the library module if that make sense. In your place I would focus on building a functioning instrumentation along with tests and explore options for sharing code later. It is quite possible that the agent code does things that don't make sense for the library instrumentation which could limit the amount of code that can be shared between them. |
...rary/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/OtelHttpServletRequest.java
Outdated
Show resolved
Hide resolved
Copied over from :servlet3.0:javaagent. Had to disable/remove some test cases/scenarios that didn't make sense or just weren't working. Still not using proper gradle project structure though.
| @Override | ||
| public void run() { | ||
| try { | ||
| try (Scope scope = context.makeCurrent()) { |
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.
It seems like an oversight that this isn't already here.
|
|
||
| public static final VirtualField<Filter, MappingResolver.Factory> | ||
| FILTER_MAPPING_RESOLVER_FACTORY = | ||
| VirtualField.find(Filter.class, MappingResolver.Factory.class); |
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.
This change isn't necessary, but it seems odd that these are duplicated. I combined them, but if it's intentional I can revert this change.
| Throwable throwable = null; | ||
| Servlet3RequestAdviceScope adviceScope = | ||
| new Servlet3RequestAdviceScope( | ||
| CallDepth.forClass(OpenTelemetryServletFilter.class), httpRequest, httpResponse, this); |
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.
I tried to keep the instrumentation as similar as possible to the javaagent instrumentation.
4efcd9e to
2e0d691
Compare
Incubating keys are internalized to avoid a dependency on a moving target.
|
🔧 The result from spotlessApply was committed to the PR branch. |
c822c44 to
6ce59fa
Compare
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.instrumentation.servlet.v3_0.copied; |
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.
i'm wondering about the value / confusion tradeoff with having "copied" in the package name. I understand the motivation, but wondering if it will be obvious to someone stumbling across it. I don't have any better ideas at this time though
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.
This is why I originally suggested using shadow/shade to generate the jar and avoid copying all this over. I personally like the distinction between what is copied over vs specific to this library. Open to better ideas.
....0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/OtelAsyncContext.java
Outdated
Show resolved
Hide resolved
...rary/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/OtelHttpServletRequest.java
Show resolved
Hide resolved
...ary/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/OtelHttpServletResponse.java
Show resolved
Hide resolved
|
|
||
| @Override | ||
| public void init(FilterConfig filterConfig) { | ||
| FILTER_MAPPING_RESOLVER.set(this, new Servlet3FilterMappingResolverFactory(filterConfig)); |
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.
I think we could just add a field to this class instead of using a virtual field? or maybe this falls under "I tried to keep the instrumentation as similar as possible to the javaagent instrumentation."
just thinking we could add
private MappingResolver.Factory mappingResolverFactory;
@Override
public void init(FilterConfig filterConfig) {
this.mappingResolverFactory = new Servlet3FilterMappingResolverFactory(filterConfig);
}and then pass it to the advice scope:
Servlet3RequestAdviceScope adviceScope =
new Servlet3RequestAdviceScope(
CallDepth.forClass(OpenTelemetryServletFilter.class),
httpRequest,
httpResponse,
this,
mappingResolverFactory);and in Servlet3RequestAdviceScope something like:
MappingResolver mappingResolver =
mappingResolverFactory != null ? mappingResolverFactory.get() : null;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.
yeah, there a lot of things about this that I would do very differently if I were writing it from scratch. Trying to keep it as similar as possible to make it easier to maintain long term.
.../src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/OpenTelemetryServletFilter.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Jay DeLuca <jaydeluca4@gmail.com>
Co-authored-by: Jay DeLuca <jaydeluca4@gmail.com>
Includes handling for attaching all the async stuff, but can't support everything the java agent does.
I could use help figuring out the right way to shadow all the necessary dependencies. I'm a bit rusty with our shadow usage. Depending on how aggressive we want to be, the dependency could be reversed so that
:servlet-3.0:javaagentdepends on this new module, but that's more aggressive. Perhaps shadow could prune unused classes (withminimize()) instead.Once we get the modules figured out, I can work on adding some unit tests.
If we like this approach, it could probably be copied and modified pretty easily to support servlet 5, but I'm not familiar with that instrumentation.