Skip to content

Commit

Permalink
Remove legacy agent installer (#6797)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcculls authored Mar 11, 2024
1 parent 4fa5f84 commit 39767bb
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 346 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,8 @@ public static ClassFileTransformer installBytebuddyAgent(
}
}

AbstractTransformerBuilder transformerBuilder;
if (InstrumenterConfig.get().isLegacyInstallerEnabled()) {
transformerBuilder = new LegacyTransformerBuilder(agentBuilder);
} else {
transformerBuilder = new CombiningTransformerBuilder(agentBuilder, maxInstrumentationId);
}
CombiningTransformerBuilder transformerBuilder =
new CombiningTransformerBuilder(agentBuilder, maxInstrumentationId);

int installedCount = 0;
for (Instrumenter instrumenter : instrumenters) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import static datadog.trace.agent.tooling.bytebuddy.DDTransformers.defaultTransformers;
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.ANY_CLASS_LOADER;
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamedOneOf;
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.declaresAnnotation;
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf;
import static net.bytebuddy.matcher.ElementMatchers.not;

Expand All @@ -14,19 +17,38 @@
import datadog.trace.api.InstrumenterConfig;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
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;

/** Builds multiple instrumentations into a single combining-matcher and splitting-transformer. */
public final class CombiningTransformerBuilder extends AbstractTransformerBuilder {
public final class CombiningTransformerBuilder
implements Instrumenter.TypeTransformer, Instrumenter.MethodTransformer {

// Added here instead of byte-buddy's ignores because it's relatively
// expensive. https://github.com/DataDog/dd-trace-java/pull/1045
private static final ElementMatcher.Junction<TypeDescription> NOT_DECORATOR_MATCHER =
not(
declaresAnnotation(
namedOneOf("javax.decorator.Decorator", "jakarta.decorator.Decorator")));

/** Associates context stores with the class-loader matchers to activate them. */
private final Map<Map.Entry<String, String>, ElementMatcher<ClassLoader>> contextStoreInjection =
new HashMap<>();

private final AgentBuilder agentBuilder;

private final List<MatchRecorder> matchers = new ArrayList<>();
Expand All @@ -52,8 +74,21 @@ public CombiningTransformerBuilder(AgentBuilder agentBuilder, int maxInstrumenta
this.nextSupplementaryId = maxInstrumentationId + 1;
}

@Override
protected void buildInstrumentation(InstrumenterModule module, Instrumenter member) {
public void applyInstrumentation(Instrumenter instrumenter) {
if (instrumenter instanceof InstrumenterModule) {
InstrumenterModule module = (InstrumenterModule) instrumenter;
if (module.isEnabled()) {
InstrumenterState.registerInstrumentation(module);
for (Instrumenter member : module.typeInstrumentations()) {
buildInstrumentation(module, member);
}
}
} else {
throw new IllegalArgumentException("Unexpected Instrumenter type");
}
}

private void buildInstrumentation(InstrumenterModule module, Instrumenter member) {

int id = module.instrumentationId();
if (module != member) {
Expand Down Expand Up @@ -161,8 +196,51 @@ public void applyAdvice(ElementMatcher<? super MethodDescription> matcher, Strin
.advice(not(ignoredMethods).and(matcher), className));
}

@Override
protected void applyContextStoreInjection(
/** Counts the number of distinct context store injections registered with this builder. */
private int contextStoreCount() {
return contextStoreInjection.size();
}

/** Applies each context store injection, guarded by the associated class-loader matcher. */
private void applyContextStoreInjection() {
contextStoreInjection.forEach(this::applyContextStoreInjection);
}

/** Tracks which class-loader matchers are associated with each store request. */
private void registerContextStoreInjection(
InstrumenterModule module, Instrumenter member, Map<String, String> contextStore) {
ElementMatcher<ClassLoader> activation;

if (member instanceof Instrumenter.ForBootstrap) {
activation = ANY_CLASS_LOADER;
} else if (member instanceof Instrumenter.ForTypeHierarchy) {
String hierarchyHint = ((Instrumenter.ForTypeHierarchy) member).hierarchyMarkerType();
activation = null != hierarchyHint ? hasClassNamed(hierarchyHint) : ANY_CLASS_LOADER;
} else if (member instanceof Instrumenter.ForSingleType) {
activation = hasClassNamed(((Instrumenter.ForSingleType) member).instrumentedType());
} else if (member instanceof Instrumenter.ForKnownTypes) {
activation = hasClassNamedOneOf(((Instrumenter.ForKnownTypes) member).knownMatchingTypes());
} else {
activation = ANY_CLASS_LOADER;
}

activation = requireBoth(activation, module.classLoaderMatcher());

for (Map.Entry<String, String> storeEntry : contextStore.entrySet()) {
ElementMatcher<ClassLoader> oldActivation = contextStoreInjection.get(storeEntry);
// optimization: treat 'any' as if there wasn't an old matcher
if (null == oldActivation || ANY_CLASS_LOADER == activation) {
contextStoreInjection.put(storeEntry, activation);
} else if (ANY_CLASS_LOADER != oldActivation) {
// store can be activated by either the old OR new matcher
contextStoreInjection.put(
storeEntry, new ElementMatcher.Junction.Disjunction<>(oldActivation, activation));
}
}
}

/** Arranges for a context value field to be injected into types extending the context key. */
private void applyContextStoreInjection(
Map.Entry<String, String> contextStore, ElementMatcher<ClassLoader> activation) {
String keyClassName = contextStore.getKey();
String contextClassName = contextStore.getValue();
Expand All @@ -178,7 +256,6 @@ protected void applyContextStoreInjection(
transformers[id] = new AdviceStack(new VisitingTransformer(contextAdvice));
}

@Override
public ClassFileTransformer installOn(Instrumentation instrumentation) {
if (InstrumenterConfig.get().isRuntimeContextFieldInjection()) {
// expand so we have enough space for a context injecting transformer for each store
Expand All @@ -193,4 +270,39 @@ public ClassFileTransformer installOn(Instrumentation instrumentation) {
.transform(new SplittingTransformer(transformers))
.installOn(instrumentation);
}

static final class VisitingTransformer implements AgentBuilder.Transformer {
private final AsmVisitorWrapper visitor;

VisitingTransformer(AsmVisitorWrapper visitor) {
this.visitor = visitor;
}

@Override
public DynamicType.Builder<?> transform(
DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule module,
ProtectionDomain pd) {
return builder.visit(visitor);
}
}

static final class HelperTransformer extends HelperInjector implements AgentBuilder.Transformer {
HelperTransformer(String requestingName, String... helperClassNames) {
super(requestingName, helperClassNames);
}
}

static ElementMatcher<ClassLoader> requireBoth(
ElementMatcher<ClassLoader> lhs, ElementMatcher<ClassLoader> rhs) {
if (ANY_CLASS_LOADER == lhs) {
return rhs;
} else if (ANY_CLASS_LOADER == rhs) {
return lhs;
} else {
return new ElementMatcher.Junction.Conjunction<>(lhs, rhs);
}
}
}
Loading

0 comments on commit 39767bb

Please sign in to comment.