Remove dead code
This commit is contained in:
parent
e9b6f5278d
commit
f5ecd47379
|
@ -1,46 +0,0 @@
|
|||
package com.datadoghq.agent;
|
||||
|
||||
import com.datadoghq.trace.DDTraceAnnotationsInfo;
|
||||
import com.datadoghq.trace.DDTraceInfo;
|
||||
import com.datadoghq.trace.resolver.DDTracerFactory;
|
||||
import com.datadoghq.trace.resolver.FactoryUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class AgentRulesManager {
|
||||
|
||||
// Initialize the info classes so they print out their version info:
|
||||
private static final String ddJavaAgentVersion = DDJavaAgentInfo.VERSION;
|
||||
private static final String ddTraceVersion = DDTraceInfo.VERSION;
|
||||
private static final String ddTraceAnnotationsVersion = DDTraceAnnotationsInfo.VERSION;
|
||||
|
||||
private static final String INITIALIZER_RULES = "initializer-rules.btm";
|
||||
|
||||
protected static volatile AgentRulesManager INSTANCE;
|
||||
|
||||
protected final TracingAgentConfig agentTracerConfig;
|
||||
protected final InstrumentationRulesManager instrumentationRulesManager;
|
||||
|
||||
public AgentRulesManager(final TracingAgentConfig config) {
|
||||
agentTracerConfig = config;
|
||||
instrumentationRulesManager = new InstrumentationRulesManager(config, this);
|
||||
instrumentationRulesManager.initTracer();
|
||||
}
|
||||
|
||||
/** This method initializes the manager. */
|
||||
public static void initialize() {
|
||||
log.debug("Initializing {}", AgentRulesManager.class.getSimpleName());
|
||||
|
||||
final TracingAgentConfig config =
|
||||
FactoryUtils.loadConfigFromFilePropertyOrResource(
|
||||
DDTracerFactory.SYSTEM_PROPERTY_CONFIG_PATH,
|
||||
DDTracerFactory.CONFIG_PATH,
|
||||
TracingAgentConfig.class);
|
||||
|
||||
log.debug("Configuration: {}", config.toString());
|
||||
|
||||
final AgentRulesManager manager = new AgentRulesManager(config);
|
||||
|
||||
INSTANCE = manager;
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package com.datadoghq.agent;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
// TODO: consider augmenting with com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector
|
||||
public class ClassLoaderIntegrationInjector {
|
||||
private final Map<ZipEntry, byte[]> entries;
|
||||
private final Map<ClassLoader, Method> invocationPoints = Maps.newConcurrentMap();
|
||||
|
||||
public ClassLoaderIntegrationInjector(final Map<ZipEntry, byte[]> allEntries) {
|
||||
this.entries = Maps.newHashMap(allEntries);
|
||||
for (final Iterator<Map.Entry<ZipEntry, byte[]>> it = entries.entrySet().iterator();
|
||||
it.hasNext();
|
||||
) {
|
||||
final Map.Entry<ZipEntry, byte[]> entry = it.next();
|
||||
if (!entry.getKey().getName().endsWith(".class")) {
|
||||
// remove all non-class files
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inject(final ClassLoader cl) {
|
||||
try {
|
||||
final Method inovcationPoint = getInovcationPoint(cl);
|
||||
final Map<ZipEntry, byte[]> toInject = Maps.newHashMap(entries);
|
||||
final Map<ZipEntry, byte[]> injectedEntries = Maps.newHashMap();
|
||||
final List<Throwable> lastErrors = new LinkedList<>();
|
||||
boolean successfulyAdded = true;
|
||||
while (!toInject.isEmpty() && successfulyAdded) {
|
||||
log.debug("Attempting to inject {} entries into {}", toInject.size(), cl);
|
||||
successfulyAdded = false;
|
||||
lastErrors.clear();
|
||||
for (final Map.Entry<ZipEntry, byte[]> entry : toInject.entrySet()) {
|
||||
final byte[] bytes = entry.getValue();
|
||||
try {
|
||||
inovcationPoint.invoke(cl, bytes, 0, bytes.length);
|
||||
injectedEntries.put(entry.getKey(), entry.getValue());
|
||||
successfulyAdded = true;
|
||||
} catch (final InvocationTargetException e) {
|
||||
lastErrors.add(e);
|
||||
}
|
||||
}
|
||||
toInject.keySet().removeAll(injectedEntries.keySet());
|
||||
}
|
||||
log.info("Successfully injected {} classes into {}", injectedEntries.size(), cl);
|
||||
log.info("Failed injecting {} classes into {}", toInject.size(), cl);
|
||||
log.debug("\nSuccesses: {}", injectedEntries);
|
||||
log.debug("\nFailures: {}", toInject);
|
||||
for (final Throwable error : lastErrors) {
|
||||
log.debug("Injection error", error.getCause());
|
||||
}
|
||||
|
||||
} catch (final NoSuchMethodException e) {
|
||||
log.error("Error getting 'defineClass' method from {}", cl);
|
||||
} catch (final IllegalAccessException e) {
|
||||
log.error("Error accessing 'defineClass' method on {}", cl);
|
||||
}
|
||||
}
|
||||
|
||||
private Method getInovcationPoint(final ClassLoader cl) throws NoSuchMethodException {
|
||||
if (invocationPoints.containsKey(invocationPoints)) {
|
||||
return invocationPoints.get(invocationPoints);
|
||||
}
|
||||
Class<?> clazz = cl.getClass();
|
||||
NoSuchMethodException firstException = null;
|
||||
while (clazz != null) {
|
||||
try {
|
||||
// defineClass is protected so we may need to check up the class hierarchy.
|
||||
final Method invocationPoint =
|
||||
clazz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||
invocationPoint.setAccessible(true);
|
||||
invocationPoints.put(cl, invocationPoint);
|
||||
return invocationPoint;
|
||||
} catch (final NoSuchMethodException e) {
|
||||
if (firstException == null) {
|
||||
firstException = e;
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
throw firstException;
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
package com.datadoghq.agent;
|
||||
|
||||
import com.datadoghq.trace.resolver.FactoryUtils;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Utility class to check the validity of the classpath concerning the java automated
|
||||
* instrumentations
|
||||
*/
|
||||
@Slf4j
|
||||
public class InstrumentationChecker {
|
||||
|
||||
private static final String CONFIG_FILE = "dd-trace-supported-framework";
|
||||
|
||||
private final Map<String, List<ArtifactSupport>> rules;
|
||||
|
||||
/* For testing purpose */
|
||||
InstrumentationChecker(
|
||||
final Map<String, List<ArtifactSupport>> rules, final Map<String, String> frameworks) {
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
public InstrumentationChecker() {
|
||||
rules =
|
||||
FactoryUtils.loadConfigFromResource(
|
||||
CONFIG_FILE, new TypeReference<Map<String, List<ArtifactSupport>>>() {});
|
||||
}
|
||||
|
||||
public List<String> getUnsupportedRules(final ClassLoader classLoader) {
|
||||
log.debug("Checking rule compatibility on classloader {}", classLoader);
|
||||
|
||||
final List<String> unsupportedRules = new ArrayList<>();
|
||||
for (final String rule : rules.keySet()) {
|
||||
|
||||
// Check rules
|
||||
boolean supported = false;
|
||||
for (final ArtifactSupport check : rules.get(rule)) {
|
||||
log.debug("Checking rule {}", check);
|
||||
|
||||
boolean matched =
|
||||
(check.identifyingPresentClasses != null
|
||||
&& !check.identifyingPresentClasses.entrySet().isEmpty())
|
||||
|| (check.identifyingMissingClasses != null
|
||||
&& !check.identifyingMissingClasses.isEmpty());
|
||||
if (check.identifyingPresentClasses != null) {
|
||||
for (final Map.Entry<String, String> identifier :
|
||||
check.identifyingPresentClasses.entrySet()) {
|
||||
final boolean classPresent = isClassPresent(identifier.getKey(), classLoader);
|
||||
if (!classPresent) {
|
||||
log.debug(
|
||||
"Instrumentation {} not applied due to missing class {}.", rule, identifier);
|
||||
} else {
|
||||
final String identifyingMethod = identifier.getValue();
|
||||
if (identifyingMethod != null && !identifyingMethod.isEmpty()) {
|
||||
final Class clazz = getClassIfPresent(identifier.getKey(), classLoader);
|
||||
// already confirmed above the class is there.
|
||||
final Method[] declaredMethods = clazz.getDeclaredMethods();
|
||||
boolean methodFound = false;
|
||||
for (final Method m : declaredMethods) {
|
||||
if (m.getName().equals(identifyingMethod)) {
|
||||
methodFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!methodFound) {
|
||||
log.debug(
|
||||
"Instrumentation {} not applied due to missing method {}.{}",
|
||||
rule,
|
||||
identifier.getKey(),
|
||||
identifyingMethod);
|
||||
matched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
matched &= classPresent;
|
||||
}
|
||||
}
|
||||
if (check.identifyingMissingClasses != null) {
|
||||
for (final String identifyingClass : check.identifyingMissingClasses) {
|
||||
final boolean classMissing = !isClassPresent(identifyingClass, classLoader);
|
||||
if (!classMissing) {
|
||||
log.debug(
|
||||
"Instrumentation {} not applied due to present class {}.",
|
||||
rule,
|
||||
identifyingClass);
|
||||
}
|
||||
matched &= classMissing;
|
||||
}
|
||||
}
|
||||
|
||||
supported |= matched;
|
||||
if (supported) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!supported) {
|
||||
log.info("Instrumentation rule={} is not supported", rule);
|
||||
unsupportedRules.add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
return unsupportedRules;
|
||||
}
|
||||
|
||||
static boolean isClassPresent(
|
||||
final String identifyingPresentClass, final ClassLoader classLoader) {
|
||||
return getClassIfPresent(identifyingPresentClass, classLoader) != null;
|
||||
}
|
||||
|
||||
static Class getClassIfPresent(
|
||||
final String identifyingPresentClass, final ClassLoader classLoader) {
|
||||
try {
|
||||
return Class.forName(identifyingPresentClass, false, classLoader);
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
static class ArtifactSupport {
|
||||
private String artifact;
|
||||
|
||||
@JsonProperty("supported_version")
|
||||
private String supportedVersion;
|
||||
|
||||
@JsonProperty("identifying_present_classes")
|
||||
private Map<String, String> identifyingPresentClasses = Collections.emptyMap();
|
||||
|
||||
@JsonProperty("identifying_missing_classes")
|
||||
private List<String> identifyingMissingClasses = Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package com.datadoghq.agent;
|
||||
|
||||
import io.opentracing.Tracer;
|
||||
import io.opentracing.contrib.tracerresolver.TracerResolver;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* This manager is loaded at pre-main. It loads all the scripts contained in all the 'oatrules.btm'
|
||||
* resource files.
|
||||
*/
|
||||
@Slf4j
|
||||
public class InstrumentationRulesManager {
|
||||
private static final Object SYNC = new Object();
|
||||
|
||||
public InstrumentationRulesManager(
|
||||
final TracingAgentConfig config, final AgentRulesManager agentRulesManager) {}
|
||||
|
||||
void initTracer() {
|
||||
synchronized (SYNC) {
|
||||
if (!GlobalTracer.isRegistered()) {
|
||||
// Try to obtain a tracer using the TracerResolver
|
||||
final Tracer resolved = TracerResolver.resolveTracer();
|
||||
if (resolved != null) {
|
||||
try {
|
||||
GlobalTracer.register(resolved);
|
||||
} catch (final RuntimeException re) {
|
||||
log.warn("Failed to register tracer '" + resolved + "'", re);
|
||||
}
|
||||
} else {
|
||||
log.warn("Failed to resolve dd tracer");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.datadoghq.agent;
|
||||
|
||||
import com.datadoghq.trace.resolver.TracerConfig;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Configuration POJO for the agent */
|
||||
public class TracingAgentConfig extends TracerConfig {
|
||||
|
||||
private List<String> disabledInstrumentations = new ArrayList<>();
|
||||
|
||||
private String[] enableCustomAnnotationTracingOver = {};
|
||||
|
||||
public String[] getEnableCustomAnnotationTracingOver() {
|
||||
return enableCustomAnnotationTracingOver;
|
||||
}
|
||||
|
||||
public void setEnableCustomAnnotationTracingOver(
|
||||
final String[] enableCustomAnnotationTracingOver) {
|
||||
this.enableCustomAnnotationTracingOver = enableCustomAnnotationTracingOver;
|
||||
}
|
||||
|
||||
public List<String> getDisabledInstrumentations() {
|
||||
return disabledInstrumentations;
|
||||
}
|
||||
|
||||
public void setDisabledInstrumentations(final List<String> uninstallContributions) {
|
||||
this.disabledInstrumentations = uninstallContributions;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.datadoghq.agent
|
||||
|
||||
import com.datadoghq.trace.resolver.FactoryUtils
|
||||
import com.fasterxml.jackson.core.type.TypeReference
|
||||
import spock.lang.Specification
|
||||
|
||||
class InstrumentationCheckerTest extends Specification {
|
||||
Map<String, List<Map<String, String>>> rules =
|
||||
FactoryUtils.loadConfigFromResource("supported-version-test", new TypeReference<Map<String, List<InstrumentationChecker.ArtifactSupport>>>() {
|
||||
})
|
||||
Map<String, String> frameworks = [
|
||||
"artifact-1": "1.2.3.1232",
|
||||
"artifact-2": "4.y.z",
|
||||
"artifact-3": "5.123-1"
|
||||
]
|
||||
|
||||
def checker = new InstrumentationChecker(rules, frameworks)
|
||||
|
||||
def "test rules"() {
|
||||
setup:
|
||||
def rules = checker.getUnsupportedRules(getClass().getClassLoader())
|
||||
|
||||
expect:
|
||||
rules.sort() == ["unsupportedRuleOne", "unsupportedRuleThree", "unsupportedRuleTwo"]
|
||||
}
|
||||
|
||||
static class DemoClass1 {
|
||||
void testMethod(String arg) {}
|
||||
}
|
||||
|
||||
static class DemoClass2 {}
|
||||
|
||||
static class DemoClass3 {}
|
||||
}
|
Loading…
Reference in New Issue