-
Notifications
You must be signed in to change notification settings - Fork 294
/
Copy pathInstrumenter.java
125 lines (105 loc) · 4.37 KB
/
Instrumenter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package datadog.trace.agent.tooling;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import java.security.ProtectionDomain;
import java.util.Collection;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.utility.JavaModule;
/** Declares bytebuddy-based type instrumentation for the datadog javaagent. */
public interface Instrumenter {
/** Instrumentation that only matches a single named type. */
interface ForSingleType {
String instrumentedType();
}
/** Instrumentation that can match a series of named types. */
interface ForKnownTypes {
String[] knownMatchingTypes();
}
/** Instrumentation that matches based on the type hierarchy. */
interface ForTypeHierarchy {
/** Hint that class-loaders without this type can skip this hierarchy matcher. */
String hierarchyMarkerType();
ElementMatcher<TypeDescription> hierarchyMatcher();
}
/** Instrumentation that transforms types on the bootstrap class-path. */
interface ForBootstrap {}
/**
* Instrumentation that matches a series of types configured at runtime. This is used for last
* minute additions in the field such as testing a new JDBC driver that is not yet in the allowed
* list and to provide a workaround until the next release. The ForKnownTypes interface is more
* appropriate when you know the series of types at build-time.
*/
interface ForConfiguredTypes {
Collection<String> configuredMatchingTypes();
}
/**
* Instrumentation that matches an optional type configured at runtime. This is used for last
* minute additions in the field such as testing a new JDBC driver that is not yet in the allowed
* list and to provide a workaround until the next release. The ForSingleType interface is more
* appropriate when you know the type at build-time.
*/
interface ForConfiguredType extends ForConfiguredTypes {
@Override
default Collection<String> configuredMatchingTypes() {
String type = configuredMatchingType();
if (null != type && !type.isEmpty()) {
return singletonList(type);
} else {
return emptyList();
}
}
String configuredMatchingType();
}
/** Instrumentation that matches based on the caller of an instruction. */
interface ForCallSite {
ElementMatcher<TypeDescription> callerType();
}
/** Instrumentation that can optionally widen matching to consider the type hierarchy. */
interface CanShortcutTypeMatching extends ForKnownTypes, ForTypeHierarchy {
boolean onlyMatchKnownTypes();
}
/** Instrumentation that wants to apply additional structure checks after type matching. */
interface WithTypeStructure {
ElementMatcher<TypeDescription> structureMatcher();
}
/** Instrumentation that provides advice which affects the whole type. */
interface HasTypeAdvice extends Instrumenter {
/**
* Instrumenters should register the full type advice with {@link
* TypeTransformer#applyAdvice(TransformingAdvice)}.
*/
void typeAdvice(TypeTransformer transformer);
}
/** Instrumentation that provides advice specific to one or more methods. */
interface HasMethodAdvice extends Instrumenter {
/**
* Instrumenters should register each method advice with {@link
* MethodTransformer#applyAdvice(ElementMatcher, String)}.
*/
void methodAdvice(MethodTransformer transformer);
}
/** Applies type advice from an instrumentation that {@link HasTypeAdvice}. */
interface TypeTransformer {
void applyAdvice(TransformingAdvice typeAdvice);
default void applyAdvice(AsmVisitorWrapper typeVisitor) {
applyAdvice(new VisitingAdvice(typeVisitor));
}
}
/** Applies method advice from an instrumentation that {@link HasMethodAdvice}. */
interface MethodTransformer {
void applyAdvice(ElementMatcher<? super MethodDescription> matcher, String adviceClass);
}
/** Contributes a transformation step to the dynamic type builder. */
interface TransformingAdvice {
DynamicType.Builder<?> transform(
DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule module,
ProtectionDomain pd);
}
}