Skip to content

Commit 0698839

Browse files
amarzialimcculls
andauthored
Use prefix trie for proxy ignores (#8678)
* Use prefix trie for proxy ignores * Update dd-java-agent/agent-tooling/src/main/resources/datadog/trace/agent/tooling/bytebuddy/matcher/proxy_ignored_class_name.trie Co-authored-by: Stuart McCulloch <[email protected]> * Add suggestion from Bruce * remove annotation processor --------- Co-authored-by: Stuart McCulloch <[email protected]>
1 parent 3682733 commit 0698839

File tree

4 files changed

+146
-10
lines changed

4 files changed

+146
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package datadog.trace.agent.tooling;
2+
3+
import datadog.trace.agent.tooling.bytebuddy.matcher.ProxyIgnoredClassNameTrie;
4+
import java.util.concurrent.TimeUnit;
5+
import org.openjdk.jmh.annotations.Benchmark;
6+
import org.openjdk.jmh.annotations.BenchmarkMode;
7+
import org.openjdk.jmh.annotations.Fork;
8+
import org.openjdk.jmh.annotations.Measurement;
9+
import org.openjdk.jmh.annotations.Mode;
10+
import org.openjdk.jmh.annotations.OutputTimeUnit;
11+
import org.openjdk.jmh.annotations.Param;
12+
import org.openjdk.jmh.annotations.Scope;
13+
import org.openjdk.jmh.annotations.State;
14+
import org.openjdk.jmh.annotations.Warmup;
15+
import org.openjdk.jmh.infra.Blackhole;
16+
17+
/*
18+
Benchmark (className) Mode Cnt Score Error Units
19+
ProxyIgnoreBenchmark.useContains org.springframework.util.ConcurrentReferenceHashMap$4 thrpt 2 0.007 ops/ns
20+
ProxyIgnoreBenchmark.useContains java.lang.invoke.LambdaForm$DMH/0x00007fe9f0388000 thrpt 2 0.008 ops/ns
21+
ProxyIgnoreBenchmark.useContains org.springframework.core.annotation.RepeatableContainers$StandardRepeatableContainers$$Lambda$315/0x00007fe9f03adc70 thrpt 2 0.003 ops/ns
22+
ProxyIgnoreBenchmark.useContains datadog.test.package.redis.RedisTemplateProvider$$TestCGLIB$$FastClass$$0 thrpt 2 0.025 ops/ns
23+
ProxyIgnoreBenchmark.useTrie org.springframework.util.ConcurrentReferenceHashMap$4 thrpt 2 0.026 ops/ns
24+
ProxyIgnoreBenchmark.useTrie java.lang.invoke.LambdaForm$DMH/0x00007fe9f0388000 thrpt 2 0.026 ops/ns
25+
ProxyIgnoreBenchmark.useTrie org.springframework.core.annotation.RepeatableContainers$StandardRepeatableContainers$$Lambda$315/0x00007fe9f03adc70 thrpt 2 0.009 ops/ns
26+
ProxyIgnoreBenchmark.useTrie datadog.test.package.redis.RedisTemplateProvider$$TestCGLIB$$FastClass$$0 thrpt 2 0.029 ops/ns
27+
*/
28+
@State(Scope.Benchmark)
29+
@BenchmarkMode(Mode.Throughput)
30+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
31+
@Measurement(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS)
32+
@Warmup(iterations = 1)
33+
@Fork(value = 1)
34+
public class ProxyIgnoreBenchmark {
35+
@Param({
36+
"org.springframework.util.ConcurrentReferenceHashMap$4",
37+
"java.lang.invoke.LambdaForm$DMH/0x00007fe9f0388000",
38+
"org.springframework.core.annotation.RepeatableContainers$StandardRepeatableContainers$$Lambda$315/0x00007fe9f03adc70",
39+
// worst case for trie based
40+
"datadog.test.package.redis.RedisTemplateProvider$$TestCGLIB$$FastClass$$0"
41+
})
42+
public String className;
43+
44+
@Benchmark
45+
public void useContains(Blackhole bh) {
46+
if (className.indexOf('$') > -1) {
47+
if (className.contains("$JaxbAccessor")
48+
|| className.contains("CGLIB$$")
49+
|| className.contains("$__sisu")
50+
|| className.contains("$$EnhancerByGuice$$")
51+
|| className.contains("$$EnhancerByProxool$$")
52+
|| className.contains("$$$view")
53+
|| className.contains("$$$endpoint") // jboss mdb proxies
54+
|| className.contains("$$_Weld")
55+
|| className.contains("_$$_jvst")) {
56+
bh.consume(true);
57+
}
58+
}
59+
}
60+
61+
@Benchmark
62+
public void useTrie(Blackhole bh) {
63+
int last = -1;
64+
int idx;
65+
while (true) {
66+
idx = className.indexOf('$', last + 1);
67+
if (idx < 0) {
68+
break;
69+
}
70+
if (last < 0 && className.contains("CGLIB$$")) {
71+
break;
72+
}
73+
if (idx == last + 1) {
74+
// skip the trie if consecutive $$ since, to be efficient, we can match prefixes from the
75+
// first dollar
76+
last = idx;
77+
continue;
78+
}
79+
last = idx;
80+
if (ProxyIgnoredClassNameTrie.apply(className, idx) >= 0) {
81+
return;
82+
}
83+
}
84+
bh.consume(true);
85+
}
86+
}

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/matcher/ProxyClassIgnores.java

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ public class ProxyClassIgnores {
55
private ProxyClassIgnores() {}
66

77
public static boolean isIgnored(String name) {
8-
if (name.indexOf('$') > -1) {
9-
if (name.contains("$JaxbAccessor")
10-
|| name.contains("CGLIB$$")
11-
|| name.contains("$__sisu")
12-
|| name.contains("$$EnhancerByGuice$$")
13-
|| name.contains("$$EnhancerByProxool$$")
14-
|| name.contains("$$$view")
15-
|| name.contains("$$$endpoint") // jboss mdb proxies
16-
|| name.contains("$$_Weld")
17-
|| name.contains("_$$_jvst")) {
8+
for (int last = -1, idx; (idx = name.indexOf('$', last + 1)) >= 0; last = idx) {
9+
if (last < 0 && name.contains("CGLIB$$")) {
10+
// check this once
11+
return true;
12+
}
13+
if (idx == last + 1) {
14+
// skip the trie if consecutive $$ since, to be efficient, we can match prefixes from the
15+
// first dollar
16+
continue;
17+
}
18+
if (ProxyIgnoredClassNameTrie.apply(name, idx) == 1) {
1819
return true;
1920
}
2021
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generates 'ProxyIgnoredClassNameTrie.java'
2+
3+
# This file lists classes that are considered as proxy hence ignored.
4+
# The trie will be matched starting from the first '$' char included.
5+
# Use 0 to allow transformation of packages or classes beneath ignored packages
6+
# Use 1 to ignore.
7+
# End lines with '*' to match any trailing char if needed.
8+
9+
# 0 = global allows
10+
# 1 = system-level ignores
11+
12+
# --------- ALLOW SHORTCUTS -----------
13+
14+
# lambda factory generated classes are not proxies
15+
0 $$Lambda$*
16+
17+
# -------- SYSTEM-LEVEL IGNORES --------
18+
19+
1 $$weld*
20+
1 $JaxbAccessor*
21+
1 $__sisu*
22+
1 $$EnhancerByGuice$$*
23+
1 $$EnhancerByProxool$$*
24+
1 $$$view*
25+
# jboss mdb proxies
26+
1 $$$endpoint*
27+
1 $$_Weld*
28+
1 $$_jvst*
29+
1 $$SpringCGLIB$$*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package datadog.trace.agent.tooling.bytebuddy.matcher
2+
3+
import datadog.trace.test.util.DDSpecification
4+
5+
class ProxyClassIgnoresTest extends DDSpecification {
6+
def 'test #clsName exclusion'() {
7+
given:
8+
def result = ProxyClassIgnores.isIgnored(clsName)
9+
expect:
10+
result == excluded
11+
where:
12+
clsName | excluded
13+
'org.springframework.util.ConcurrentReferenceHashMap$4' | false
14+
'io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerAutoConfiguration$CircuitBreakerEndpointAutoConfiguration$$SpringCGLIB$$0' | true
15+
'io.micrometer.core.instrument.config.NamingConvention$$Lambda$1415' | false
16+
'com.package.name.Class$JaxbAccessorF_variablename' | true
17+
'my.package.Resource$Proxy$_$$_Weld$EnterpriseProxy' | true
18+
'com.abc.MyResourceImpl$$EnhancerByGuice$$69175a50' | true
19+
}
20+
}

0 commit comments

Comments
 (0)