Introduce IgnoredTypesConfigurer SPI to enable defining per-module ignores - #3219
Conversation
| @Deprecated | ||
| public interface IgnoreMatcherProvider { |
There was a problem hiding this comment.
always nice to remove something when adding something 😄👍
| * <p>This is a service provider interface that requires implementations to be registered in a | ||
| * provider-configuration file stored in the {@code META-INF/services} resource directory. | ||
| */ | ||
| public interface IgnoredTypesConfigurer extends Ordered { |
There was a problem hiding this comment.
Is there a reason for a separate interface instead of knob on InstrumentationModule?
There was a problem hiding this comment.
I thought that it'd be useful to be able ignore some classes (e.g. task classes to prevent context leaking) even if you turn the instrumentation off.
There was a problem hiding this comment.
Hmm - well we could choose to respet them even if it's disabled? Not sure if it's a great idea - IIRC, dd-trace-java has the knob on InstrumentationModule so it could keep us more consistent with them, though maybe that's a difficult goal at this point
There was a problem hiding this comment.
As far as I understand, they have something similar just for concurrent/task classes: https://github.com/DataDog/dd-trace-java/blob/master/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ExcludeFilterProvider.java
And they're doing a separate pass over Instrumenters and check with instanceof if this interface is implemented.
it could keep us more consistent with them, though maybe that's a difficult goal at this point
With all our changes to muzzle, the split to InstrumentationModule/TypeInstrumentation, and DD's custom things (like profiling) it's probably impossible 😅
Hmm - well we could choose to respet them even if it's disabled?
That's what seemed a bit confusing to me - you have the enabled flag but it only works for some InstrumentationModule methods.
|
|
||
| import org.checkerframework.checker.nullness.qual.Nullable; | ||
|
|
||
| /** A prefix tree that maps from the longest matching prefix to a value {@code V}. */ |
There was a problem hiding this comment.
Did you copy this class from anywhere?
There was a problem hiding this comment.
No, I wrote it from scratch.
|
|
||
| @Nullable | ||
| Node<V> getNext(char c) { | ||
| int index = Arrays.binarySearch(chars, c); |
There was a problem hiding this comment.
If you feel like comparing some optimizations, some ideas are
- Don't binary search, these arrays seem small enough that it would be slower than a normal loop
- A single array with every other element
CharacterandNode- single array means better cache performance - Copy in from Armeria (while simplifying it's funcionality for parameters) :P
The main difference is the nodes are subpaths rather than characters - it's quite unfortunate a boring path like org.springframework.blah has a node per character
There was a problem hiding this comment.
Nice, thanks!
I'll note all your suggestions down and try them out later.
When I was writing the spring-integration javaagent instrumentation I had to add yet another entry (a few of them, in fact) into the
AdditionalLibraryIgnoresMatcher- an I thought that maybe it's a good idea to finally make the first step towards splitting that class and keeping the lib-specific ignores in the lib instrumentation itself.This PR introduces a new
IgnoredTypesConfigurerSPI that allows adding ignored/allowed classes to the agent builder in any instrumentation module (or extension jar). All those ignores are still kept in one place, but now it's possible to split that one giant class and move some of those overrides to related instrumentation modules. I still don't have a good idea what to do about our tests that verify that classes matched byAdditionalLibraryIgnoresMatcherwere not instrumented, but maybe it'll become clear with the first instrumentation.The same SPI could be used to exclude task classes (
ExecutorInstrumentationUtils) from context propagation, although it's not implemented yet.The new SPI stores all those overrides in a prefix tree, which has a bit better performance than repeated
.startsWithcalls:The old version (
.startsWith(...)):The new version (trie):
I didn't really trust my algo skills, fortunately this benchmark proved that I didn't make matters worse with this change 😂