Merge pull request #57 from DataDog/tyler/lombok-logging
Use Lombok @Slf4j annotation for declaring loggers
This commit is contained in:
commit
8f04fcaeba
|
@ -8,16 +8,15 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to check the validity of the classpath concerning the java automated
|
* Utility class to check the validity of the classpath concerning the java automated
|
||||||
* instrumentations
|
* instrumentations
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class InstrumentationChecker {
|
public class InstrumentationChecker {
|
||||||
|
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(InstrumentationChecker.class);
|
|
||||||
private static final String CONFIG_FILE = "dd-trace-supported-framework.yaml";
|
private static final String CONFIG_FILE = "dd-trace-supported-framework.yaml";
|
||||||
private final Map<String, List<Map<String, String>>> rules;
|
private final Map<String, List<Map<String, String>>> rules;
|
||||||
private final Map<String, String> frameworks;
|
private final Map<String, String> frameworks;
|
||||||
|
@ -26,7 +25,7 @@ public class InstrumentationChecker {
|
||||||
|
|
||||||
/* For testing purpose */
|
/* For testing purpose */
|
||||||
InstrumentationChecker(
|
InstrumentationChecker(
|
||||||
Map<String, List<Map<String, String>>> rules, Map<String, String> frameworks) {
|
final Map<String, List<Map<String, String>>> rules, final Map<String, String> frameworks) {
|
||||||
this.rules = rules;
|
this.rules = rules;
|
||||||
this.frameworks = frameworks;
|
this.frameworks = frameworks;
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
|
@ -53,18 +52,18 @@ public class InstrumentationChecker {
|
||||||
|
|
||||||
private List<String> doGetUnsupportedRules() {
|
private List<String> doGetUnsupportedRules() {
|
||||||
|
|
||||||
List<String> unsupportedRules = new ArrayList<>();
|
final List<String> unsupportedRules = new ArrayList<>();
|
||||||
for (String rule : rules.keySet()) {
|
for (final String rule : rules.keySet()) {
|
||||||
|
|
||||||
// Check rules
|
// Check rules
|
||||||
boolean supported = false;
|
boolean supported = false;
|
||||||
for (Map<String, String> check : rules.get(rule)) {
|
for (final Map<String, String> check : rules.get(rule)) {
|
||||||
if (frameworks.containsKey(check.get("artifact"))) {
|
if (frameworks.containsKey(check.get("artifact"))) {
|
||||||
boolean matched =
|
final boolean matched =
|
||||||
Pattern.matches(
|
Pattern.matches(
|
||||||
check.get("supported_version"), frameworks.get(check.get("artifact")));
|
check.get("supported_version"), frameworks.get(check.get("artifact")));
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
LOGGER.debug(
|
log.debug(
|
||||||
"Library conflict: supported_version={}, actual_version={}",
|
"Library conflict: supported_version={}, actual_version={}",
|
||||||
check.get("supported_version"),
|
check.get("supported_version"),
|
||||||
frameworks.get(check.get("artifact")));
|
frameworks.get(check.get("artifact")));
|
||||||
|
@ -72,12 +71,12 @@ public class InstrumentationChecker {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
supported = true;
|
supported = true;
|
||||||
LOGGER.trace("Instrumentation rule={} is supported", rule);
|
log.trace("Instrumentation rule={} is supported", rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
LOGGER.info("Instrumentation rule={} is not supported", rule);
|
log.info("Instrumentation rule={} is not supported", rule);
|
||||||
unsupportedRules.add(rule);
|
unsupportedRules.add(rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,19 +86,19 @@ public class InstrumentationChecker {
|
||||||
|
|
||||||
private static Map<String, String> scanLoadedLibraries() {
|
private static Map<String, String> scanLoadedLibraries() {
|
||||||
|
|
||||||
Map<String, String> frameworks = new HashMap<>();
|
final Map<String, String> frameworks = new HashMap<>();
|
||||||
|
|
||||||
// Scan classpath provided jars
|
// Scan classpath provided jars
|
||||||
List<File> jars = getJarFiles(System.getProperty("java.class.path"));
|
final List<File> jars = getJarFiles(System.getProperty("java.class.path"));
|
||||||
for (File file : jars) {
|
for (final File file : jars) {
|
||||||
|
|
||||||
String jarName = file.getName();
|
final String jarName = file.getName();
|
||||||
String version = extractJarVersion(jarName);
|
final String version = extractJarVersion(jarName);
|
||||||
|
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
|
|
||||||
// Extract artifactId
|
// Extract artifactId
|
||||||
String artifactId = file.getName().substring(0, jarName.indexOf(version) - 1);
|
final String artifactId = file.getName().substring(0, jarName.indexOf(version) - 1);
|
||||||
|
|
||||||
// Store it
|
// Store it
|
||||||
frameworks.put(artifactId, version);
|
frameworks.put(artifactId, version);
|
||||||
|
@ -109,8 +108,8 @@ public class InstrumentationChecker {
|
||||||
return frameworks;
|
return frameworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<File> getJarFiles(String paths) {
|
private static List<File> getJarFiles(final String paths) {
|
||||||
List<File> filesList = new ArrayList<File>();
|
final List<File> filesList = new ArrayList<>();
|
||||||
for (final String path : paths.split(File.pathSeparator)) {
|
for (final String path : paths.split(File.pathSeparator)) {
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
|
@ -124,17 +123,17 @@ public class InstrumentationChecker {
|
||||||
return filesList;
|
return filesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void recurse(List<File> filesList, File f) {
|
private static void recurse(final List<File> filesList, final File f) {
|
||||||
File list[] = f.listFiles();
|
final File[] list = f.listFiles();
|
||||||
for (File file : list) {
|
for (final File file : list) {
|
||||||
getJarFiles(file.getPath());
|
getJarFiles(file.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String extractJarVersion(String jarName) {
|
private static String extractJarVersion(final String jarName) {
|
||||||
|
|
||||||
Pattern versionPattern = Pattern.compile("-(\\d+\\..+)\\.jar");
|
final Pattern versionPattern = Pattern.compile("-(\\d+\\..+)\\.jar");
|
||||||
Matcher matcher = versionPattern.matcher(jarName);
|
final Matcher matcher = versionPattern.matcher(jarName);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
return matcher.group(1);
|
return matcher.group(1);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
import javassist.bytecode.Descriptor;
|
import javassist.bytecode.Descriptor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jboss.byteman.agent.Location;
|
import org.jboss.byteman.agent.Location;
|
||||||
import org.jboss.byteman.agent.LocationType;
|
import org.jboss.byteman.agent.LocationType;
|
||||||
import org.jboss.byteman.agent.Retransformer;
|
import org.jboss.byteman.agent.Retransformer;
|
||||||
|
@ -31,8 +32,6 @@ import org.reflections.Reflections;
|
||||||
import org.reflections.scanners.MethodAnnotationsScanner;
|
import org.reflections.scanners.MethodAnnotationsScanner;
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
import org.reflections.util.FilterBuilder;
|
import org.reflections.util.FilterBuilder;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This manager is loaded at pre-main.
|
* This manager is loaded at pre-main.
|
||||||
|
@ -40,10 +39,9 @@ import org.slf4j.LoggerFactory;
|
||||||
* <p>It loads all the scripts contained in all the 'oatrules.btm' resource files then instrument
|
* <p>It loads all the scripts contained in all the 'oatrules.btm' resource files then instrument
|
||||||
* all the methods annoted with the @Trace.
|
* all the methods annoted with the @Trace.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class TraceAnnotationsManager {
|
public class TraceAnnotationsManager {
|
||||||
|
|
||||||
private static Logger LOGGER = LoggerFactory.getLogger(TraceAnnotationsManager.class);
|
|
||||||
|
|
||||||
private static Retransformer transformer;
|
private static Retransformer transformer;
|
||||||
|
|
||||||
private static final String AGENT_RULES = "otarules.btm";
|
private static final String AGENT_RULES = "otarules.btm";
|
||||||
|
@ -53,21 +51,21 @@ public class TraceAnnotationsManager {
|
||||||
*
|
*
|
||||||
* @param trans The ByteMan retransformer
|
* @param trans The ByteMan retransformer
|
||||||
*/
|
*/
|
||||||
public static void initialize(Retransformer trans) throws Exception {
|
public static void initialize(final Retransformer trans) throws Exception {
|
||||||
transformer = trans;
|
transformer = trans;
|
||||||
//Load configuration
|
//Load configuration
|
||||||
AgentTracerConfig agentTracerConfig =
|
final AgentTracerConfig agentTracerConfig =
|
||||||
FactoryUtils.loadConfigFromFilePropertyOrResource(
|
FactoryUtils.loadConfigFromFilePropertyOrResource(
|
||||||
DDTracerFactory.SYSTEM_PROPERTY_CONFIG_PATH,
|
DDTracerFactory.SYSTEM_PROPERTY_CONFIG_PATH,
|
||||||
DDTracerFactory.CONFIG_PATH,
|
DDTracerFactory.CONFIG_PATH,
|
||||||
AgentTracerConfig.class);
|
AgentTracerConfig.class);
|
||||||
|
|
||||||
List<String> loadedScripts = loadRules(ClassLoader.getSystemClassLoader());
|
final List<String> loadedScripts = loadRules(ClassLoader.getSystemClassLoader());
|
||||||
|
|
||||||
//Check if some rules have to be uninstalled
|
//Check if some rules have to be uninstalled
|
||||||
List<String> uninstallScripts = InstrumentationChecker.getUnsupportedRules();
|
final List<String> uninstallScripts = InstrumentationChecker.getUnsupportedRules();
|
||||||
if (agentTracerConfig != null) {
|
if (agentTracerConfig != null) {
|
||||||
List<String> disabledInstrumentations = agentTracerConfig.getDisabledInstrumentations();
|
final List<String> disabledInstrumentations = agentTracerConfig.getDisabledInstrumentations();
|
||||||
if (disabledInstrumentations != null && !disabledInstrumentations.isEmpty()) {
|
if (disabledInstrumentations != null && !disabledInstrumentations.isEmpty()) {
|
||||||
uninstallScripts.addAll(disabledInstrumentations);
|
uninstallScripts.addAll(disabledInstrumentations);
|
||||||
}
|
}
|
||||||
|
@ -88,14 +86,14 @@ public class TraceAnnotationsManager {
|
||||||
*
|
*
|
||||||
* @param patterns not case sensitive (eg. "mongo", "apache http", "elasticsearch", etc...])
|
* @param patterns not case sensitive (eg. "mongo", "apache http", "elasticsearch", etc...])
|
||||||
*/
|
*/
|
||||||
public static void uninstallScripts(List<String> installedScripts, List<String> patterns)
|
public static void uninstallScripts(
|
||||||
throws Exception {
|
final List<String> installedScripts, final List<String> patterns) throws Exception {
|
||||||
Set<String> rulesToRemove = new HashSet<String>();
|
final Set<String> rulesToRemove = new HashSet<>();
|
||||||
|
|
||||||
for (String strPattern : patterns) {
|
for (final String strPattern : patterns) {
|
||||||
Pattern pattern = Pattern.compile("(?i)RULE [^\n]*" + strPattern + "[^\n]*\n");
|
final Pattern pattern = Pattern.compile("(?i)RULE [^\n]*" + strPattern + "[^\n]*\n");
|
||||||
for (String loadedScript : installedScripts) {
|
for (final String loadedScript : installedScripts) {
|
||||||
Matcher matcher = pattern.matcher(loadedScript);
|
final Matcher matcher = pattern.matcher(loadedScript);
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
rulesToRemove.add(matcher.group());
|
rulesToRemove.add(matcher.group());
|
||||||
}
|
}
|
||||||
|
@ -103,11 +101,11 @@ public class TraceAnnotationsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rulesToRemove.isEmpty()) {
|
if (!rulesToRemove.isEmpty()) {
|
||||||
StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
try (PrintWriter pr = new PrintWriter(sw)) {
|
try (PrintWriter pr = new PrintWriter(sw)) {
|
||||||
transformer.removeScripts(new ArrayList<String>(rulesToRemove), pr);
|
transformer.removeScripts(new ArrayList<>(rulesToRemove), pr);
|
||||||
}
|
}
|
||||||
LOGGER.info(sw.toString());
|
log.info(sw.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,47 +115,47 @@ public class TraceAnnotationsManager {
|
||||||
*
|
*
|
||||||
* @param classLoader The classloader
|
* @param classLoader The classloader
|
||||||
*/
|
*/
|
||||||
public static List<String> loadRules(ClassLoader classLoader) {
|
public static List<String> loadRules(final ClassLoader classLoader) {
|
||||||
List<String> scripts = new ArrayList<>();
|
final List<String> scripts = new ArrayList<>();
|
||||||
if (transformer == null) {
|
if (transformer == null) {
|
||||||
LOGGER.warn("Attempt to load OpenTracing agent rules before transformer initialized");
|
log.warn("Attempt to load OpenTracing agent rules before transformer initialized");
|
||||||
return scripts;
|
return scripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> scriptNames = new ArrayList<>();
|
final List<String> scriptNames = new ArrayList<>();
|
||||||
|
|
||||||
// Load default and custom rules
|
// Load default and custom rules
|
||||||
try {
|
try {
|
||||||
Enumeration<URL> iter = classLoader.getResources(AGENT_RULES);
|
final Enumeration<URL> iter = classLoader.getResources(AGENT_RULES);
|
||||||
while (iter.hasMoreElements()) {
|
while (iter.hasMoreElements()) {
|
||||||
loadRules(iter.nextElement().toURI(), scriptNames, scripts);
|
loadRules(iter.nextElement().toURI(), scriptNames, scripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
try (PrintWriter writer = new PrintWriter(sw)) {
|
try (PrintWriter writer = new PrintWriter(sw)) {
|
||||||
try {
|
try {
|
||||||
transformer.installScript(scripts, scriptNames, writer);
|
transformer.installScript(scripts, scriptNames, writer);
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.warn("Failed to install scripts", e);
|
log.warn("Failed to install scripts", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGGER.trace(sw.toString());
|
log.trace(sw.toString());
|
||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
LOGGER.warn("Failed to load OpenTracing agent rules", e);
|
log.warn("Failed to load OpenTracing agent rules", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("OpenTracing Agent rules loaded");
|
log.debug("OpenTracing Agent rules loaded");
|
||||||
return scripts;
|
return scripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find all the methods annoted with @Trace and inject rules */
|
/** Find all the methods annoted with @Trace and inject rules */
|
||||||
public static void loadAnnotationsRules(String... scannedPackages) {
|
public static void loadAnnotationsRules(final String... scannedPackages) {
|
||||||
|
|
||||||
LOGGER.info(
|
log.info(
|
||||||
"Looking for annotations over the following packages: {}", Arrays.asList(scannedPackages));
|
"Looking for annotations over the following packages: {}", Arrays.asList(scannedPackages));
|
||||||
long cur = System.currentTimeMillis();
|
final long cur = System.currentTimeMillis();
|
||||||
|
|
||||||
Reflections reflections =
|
final Reflections reflections =
|
||||||
new Reflections(
|
new Reflections(
|
||||||
new ConfigurationBuilder()
|
new ConfigurationBuilder()
|
||||||
.forPackages(scannedPackages)
|
.forPackages(scannedPackages)
|
||||||
|
@ -165,17 +163,17 @@ public class TraceAnnotationsManager {
|
||||||
new FilterBuilder().includePackage(scannedPackages).include(".*\\.class"))
|
new FilterBuilder().includePackage(scannedPackages).include(".*\\.class"))
|
||||||
.setScanners(new MethodAnnotationsScanner()));
|
.setScanners(new MethodAnnotationsScanner()));
|
||||||
|
|
||||||
Set<Method> methods = reflections.getMethodsAnnotatedWith(Trace.class);
|
final Set<Method> methods = reflections.getMethodsAnnotatedWith(Trace.class);
|
||||||
|
|
||||||
StringBuilder generatedScripts = new StringBuilder();
|
final StringBuilder generatedScripts = new StringBuilder();
|
||||||
for (Method method : methods) {
|
for (final Method method : methods) {
|
||||||
try {
|
try {
|
||||||
ClassPool pool = ClassPool.getDefault();
|
final ClassPool pool = ClassPool.getDefault();
|
||||||
CtClass cc = pool.get(method.getDeclaringClass().getCanonicalName());
|
final CtClass cc = pool.get(method.getDeclaringClass().getCanonicalName());
|
||||||
CtMethod javassistMethod = cc.getDeclaredMethod(method.getName());
|
final CtMethod javassistMethod = cc.getDeclaredMethod(method.getName());
|
||||||
|
|
||||||
//AT ENTRY: child of current case
|
//AT ENTRY: child of current case
|
||||||
String ruleText = CURRENT_SPAN_EXISTS + buildSpan(javassistMethod) + START;
|
final String ruleText = CURRENT_SPAN_EXISTS + buildSpan(javassistMethod) + START;
|
||||||
RuleScript script =
|
RuleScript script =
|
||||||
createRuleScript(
|
createRuleScript(
|
||||||
"Start Active Span ",
|
"Start Active Span ",
|
||||||
|
@ -195,34 +193,38 @@ public class TraceAnnotationsManager {
|
||||||
EXIT_RULE);
|
EXIT_RULE);
|
||||||
generatedScripts.append(script).append("\n");
|
generatedScripts.append(script).append("\n");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.warn(
|
log.warn(
|
||||||
"Could not create rule for method " + method + ". Proceed to next annoted method.", e);
|
"Could not create rule for method " + method + ". Proceed to next annoted method.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
try (PrintWriter pr = new PrintWriter(sw)) {
|
try (PrintWriter pr = new PrintWriter(sw)) {
|
||||||
transformer.installScript(
|
transformer.installScript(
|
||||||
Arrays.asList(generatedScripts.toString()), Arrays.asList("@Trace annotations"), pr);
|
Arrays.asList(generatedScripts.toString()), Arrays.asList("@Trace annotations"), pr);
|
||||||
}
|
}
|
||||||
LOGGER.debug(sw.toString());
|
log.debug(sw.toString());
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.warn("Could not install annotation scripts.", e);
|
log.warn("Could not install annotation scripts.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.info(
|
log.info(
|
||||||
"Finished annotation scanning in "
|
"Finished annotation scanning in "
|
||||||
+ (System.currentTimeMillis() - cur)
|
+ (System.currentTimeMillis() - cur)
|
||||||
+ " ms. You can accelerate this process by refining the packages you want to scan with `scannedPackages` in the dd-trace.yaml configuration file.");
|
+ " ms. You can accelerate this process by refining the packages you want to scan with `scannedPackages` in the dd-trace.yaml configuration file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RuleScript createRuleScript(
|
private static RuleScript createRuleScript(
|
||||||
String ruleNamePrefix, CtClass cc, CtMethod javassistMethod, Location loc, String ruleText) {
|
final String ruleNamePrefix,
|
||||||
int lineNumber = javassistMethod.getMethodInfo().getLineNumber(0);
|
final CtClass cc,
|
||||||
String[] imports = new String[0];
|
final CtMethod javassistMethod,
|
||||||
|
final Location loc,
|
||||||
|
final String ruleText) {
|
||||||
|
final int lineNumber = javassistMethod.getMethodInfo().getLineNumber(0);
|
||||||
|
final String[] imports = new String[0];
|
||||||
|
|
||||||
RuleScript ruleScript =
|
final RuleScript ruleScript =
|
||||||
new RuleScript(
|
new RuleScript(
|
||||||
ruleNamePrefix + loc + " " + javassistMethod.getLongName(),
|
ruleNamePrefix + loc + " " + javassistMethod.getLongName(),
|
||||||
cc.getName(),
|
cc.getName(),
|
||||||
|
@ -239,14 +241,15 @@ public class TraceAnnotationsManager {
|
||||||
return ruleScript;
|
return ruleScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadRules(URI uri, final List<String> scriptNames, final List<String> scripts)
|
private static void loadRules(
|
||||||
|
final URI uri, final List<String> scriptNames, final List<String> scripts)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
LOGGER.debug("Load rules from URI uri={} ", uri);
|
log.debug("Load rules from URI uri={} ", uri);
|
||||||
|
|
||||||
StringBuilder str = new StringBuilder();
|
final StringBuilder str = new StringBuilder();
|
||||||
try (InputStream is = uri.toURL().openStream()) {
|
try (InputStream is = uri.toURL().openStream()) {
|
||||||
|
|
||||||
byte[] b = new byte[10240];
|
final byte[] b = new byte[10240];
|
||||||
int len;
|
int len;
|
||||||
while ((len = is.read(b)) != -1) {
|
while ((len = is.read(b)) != -1) {
|
||||||
str.append(new String(b, 0, len));
|
str.append(new String(b, 0, len));
|
||||||
|
@ -256,24 +259,24 @@ public class TraceAnnotationsManager {
|
||||||
scriptNames.add(uri.toString());
|
scriptNames.add(uri.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String CURRENT_SPAN_EXISTS = "IF TRUE\n";
|
private static final String CURRENT_SPAN_EXISTS = "IF TRUE\n";
|
||||||
|
|
||||||
private static String BUILD_SPAN = "DO\n" + "getTracer().buildSpan(\"";
|
private static final String BUILD_SPAN = "DO\n" + "getTracer().buildSpan(\"";
|
||||||
private static String CLOSE_PARENTHESIS = "\")";
|
private static final String CLOSE_PARENTHESIS = "\")";
|
||||||
|
|
||||||
private static String START = ".startActive();";
|
private static final String START = ".startActive();";
|
||||||
|
|
||||||
private static String EXIT_RULE =
|
private static final String EXIT_RULE =
|
||||||
"IF getTracer().activeSpan() != null\n" + "DO\n" + "getTracer().activeSpan().deactivate();\n";
|
"IF getTracer().activeSpan() != null\n" + "DO\n" + "getTracer().activeSpan().deactivate();\n";
|
||||||
|
|
||||||
private static String buildSpan(CtMethod javassistMethod) {
|
private static String buildSpan(final CtMethod javassistMethod) {
|
||||||
try {
|
try {
|
||||||
Trace trace = (Trace) javassistMethod.getAnnotation(Trace.class);
|
final Trace trace = (Trace) javassistMethod.getAnnotation(Trace.class);
|
||||||
if (trace.operationName() != null & !trace.operationName().isEmpty()) {
|
if (trace.operationName() != null & !trace.operationName().isEmpty()) {
|
||||||
return BUILD_SPAN + trace.operationName() + CLOSE_PARENTHESIS;
|
return BUILD_SPAN + trace.operationName() + CLOSE_PARENTHESIS;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.warn(
|
log.warn(
|
||||||
"Error when building injection rule on method "
|
"Error when building injection rule on method "
|
||||||
+ javassistMethod
|
+ javassistMethod
|
||||||
+ ". Fallback on default value.",
|
+ ". Fallback on default value.",
|
||||||
|
|
|
@ -3,35 +3,33 @@ package com.datadoghq.trace.agent.integration;
|
||||||
import io.opentracing.NoopTracerFactory;
|
import io.opentracing.NoopTracerFactory;
|
||||||
import io.opentracing.Tracer;
|
import io.opentracing.Tracer;
|
||||||
import io.opentracing.contrib.agent.OpenTracingHelper;
|
import io.opentracing.contrib.agent.OpenTracingHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jboss.byteman.rule.Rule;
|
import org.jboss.byteman.rule.Rule;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides helpful stuff in order to easy patch object using Byteman rules
|
* This class provides helpful stuff in order to easy patch object using Byteman rules
|
||||||
*
|
*
|
||||||
* @param <T> The type of the object to patch
|
* @param <T> The type of the object to patch
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public abstract class DDAgentTracingHelper<T> extends OpenTracingHelper {
|
public abstract class DDAgentTracingHelper<T> extends OpenTracingHelper {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DDAgentTracingHelper.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current instance of the tracer. If something goes wrong during the resolution, we provides
|
* The current instance of the tracer. If something goes wrong during the resolution, we provides
|
||||||
* a NoopTracer.
|
* a NoopTracer.
|
||||||
*/
|
*/
|
||||||
protected final Tracer tracer;
|
protected final Tracer tracer;
|
||||||
|
|
||||||
DDAgentTracingHelper(Rule rule) {
|
DDAgentTracingHelper(final Rule rule) {
|
||||||
super(rule);
|
super(rule);
|
||||||
Tracer tracerResolved;
|
Tracer tracerResolved;
|
||||||
try {
|
try {
|
||||||
tracerResolved = getTracer();
|
tracerResolved = getTracer();
|
||||||
tracerResolved = tracerResolved == null ? NoopTracerFactory.create() : tracerResolved;
|
tracerResolved = tracerResolved == null ? NoopTracerFactory.create() : tracerResolved;
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
tracerResolved = NoopTracerFactory.create();
|
tracerResolved = NoopTracerFactory.create();
|
||||||
LOGGER.warn("Failed to retrieve the tracer, using a NoopTracer instead: {}", e.getMessage());
|
log.warn("Failed to retrieve the tracer, using a NoopTracer instead: {}", e.getMessage());
|
||||||
LOGGER.warn(e.getMessage(), e);
|
log.warn(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
tracer = tracerResolved;
|
tracer = tracerResolved;
|
||||||
}
|
}
|
||||||
|
@ -46,23 +44,23 @@ public abstract class DDAgentTracingHelper<T> extends OpenTracingHelper {
|
||||||
* @param args The object to patch, the type is defined by the subclass instantiation
|
* @param args The object to patch, the type is defined by the subclass instantiation
|
||||||
* @return The object patched
|
* @return The object patched
|
||||||
*/
|
*/
|
||||||
public T patch(T args) {
|
public T patch(final T args) {
|
||||||
|
|
||||||
if (args == null) {
|
if (args == null) {
|
||||||
LOGGER.debug("Skipping rule={} because the input arg is null", rule.getName());
|
log.debug("Skipping rule={} because the input arg is null", rule.getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String className = args.getClass().getName();
|
final String className = args.getClass().getName();
|
||||||
LOGGER.debug("Try to patch class={}", className);
|
log.debug("Try to patch class={}", className);
|
||||||
|
|
||||||
T patched;
|
T patched;
|
||||||
try {
|
try {
|
||||||
patched = doPatch(args);
|
patched = doPatch(args);
|
||||||
LOGGER.debug("class={} patched", className);
|
log.debug("class={} patched", className);
|
||||||
} catch (Throwable e) {
|
} catch (final Throwable e) {
|
||||||
LOGGER.warn("Failed to patch class={}, reason: {}", className, e.getMessage());
|
log.warn("Failed to patch class={}, reason: {}", className, e.getMessage());
|
||||||
LOGGER.warn(e.getMessage(), e);
|
log.warn(e.getMessage(), e);
|
||||||
patched = args;
|
patched = args;
|
||||||
}
|
}
|
||||||
return patched;
|
return patched;
|
||||||
|
|
|
@ -3,6 +3,7 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
classpath "io.franzbecker:gradle-lombok:1.8"
|
||||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.18"
|
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
|
|
||||||
/** StartTime stores the creation time of the span in milliseconds */
|
/** StartTime stores the creation time of the span in milliseconds */
|
||||||
|
@ -22,8 +22,6 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
/** The context attached to the span */
|
/** The context attached to the span */
|
||||||
protected final DDSpanContext context;
|
protected final DDSpanContext context;
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDBaseSpan.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple constructor. Currently, users have
|
* A simple constructor. Currently, users have
|
||||||
*
|
*
|
||||||
|
@ -61,7 +59,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
* not, warned it
|
* not, warned it
|
||||||
*/
|
*/
|
||||||
protected final void afterFinish() {
|
protected final void afterFinish() {
|
||||||
logger.debug("{} - Closing the span.", this);
|
log.debug("{} - Closing the span.", this);
|
||||||
|
|
||||||
// warn if one of the parent's children is not finished
|
// warn if one of the parent's children is not finished
|
||||||
if (this.isRootSpan()) {
|
if (this.isRootSpan()) {
|
||||||
|
@ -69,13 +67,13 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
|
|
||||||
for (final DDBaseSpan<?> span : spans) {
|
for (final DDBaseSpan<?> span : spans) {
|
||||||
if (span.getDurationNano() == 0L) {
|
if (span.getDurationNano() == 0L) {
|
||||||
logger.warn(
|
log.warn(
|
||||||
"{} - The parent span is marked as finished but this span isn't. You have to close each children.",
|
"{} - The parent span is marked as finished but this span isn't. You have to close each children.",
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.context.getTracer().write(this.context.getTrace());
|
this.context.getTracer().write(this.context.getTrace());
|
||||||
logger.debug("{} - Write the trace", this);
|
log.debug("{} - Write the trace", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +159,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final Map<String, ?> map) {
|
public final S log(final Map<String, ?> map) {
|
||||||
logger.debug("`log` method is not implemented. Doing nothing");
|
log.debug("`log` method is not implemented. Doing nothing");
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final long l, final Map<String, ?> map) {
|
public final S log(final long l, final Map<String, ?> map) {
|
||||||
logger.debug("`log` method is not implemented. Doing nothing");
|
log.debug("`log` method is not implemented. Doing nothing");
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final String s) {
|
public final S log(final String s) {
|
||||||
logger.debug("`log` method is not implemented. Provided log: {}", s);
|
log.debug("`log` method is not implemented. Provided log: {}", s);
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +186,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final long l, final String s) {
|
public final S log(final long l, final String s) {
|
||||||
logger.debug("`log` method is not implemented. Provided log: {}", s);
|
log.debug("`log` method is not implemented. Provided log: {}", s);
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +195,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final String s, final Object o) {
|
public final S log(final String s, final Object o) {
|
||||||
logger.debug("`log` method is not implemented. Provided log: {}", s);
|
log.debug("`log` method is not implemented. Provided log: {}", s);
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +204,7 @@ public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final S log(final long l, final String s, final Object o) {
|
public final S log(final long l, final String s, final Object o) {
|
||||||
logger.debug("`log` method is not implemented. Provided log: {}", s);
|
log.debug("`log` method is not implemented. Provided log: {}", s);
|
||||||
return thisInstance();
|
return thisInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,10 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/** DDTracer makes it easy to send traces and span to DD using the OpenTracing integration. */
|
/** DDTracer makes it easy to send traces and span to DD using the OpenTracing integration. */
|
||||||
|
@Slf4j
|
||||||
public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentracing.Tracer {
|
public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentracing.Tracer {
|
||||||
|
|
||||||
public static final String JAVA_VERSION = System.getProperty("java.version", "unknown");
|
public static final String JAVA_VERSION = System.getProperty("java.version", "unknown");
|
||||||
|
@ -37,8 +37,6 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
public static final Writer UNASSIGNED_WRITER = new LoggingWriter();
|
public static final Writer UNASSIGNED_WRITER = new LoggingWriter();
|
||||||
public static final Sampler UNASSIGNED_SAMPLER = new AllSampler();
|
public static final Sampler UNASSIGNED_SAMPLER = new AllSampler();
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDTracer.class);
|
|
||||||
|
|
||||||
/** Writer is an charge of reporting traces and spans to the desired endpoint */
|
/** Writer is an charge of reporting traces and spans to the desired endpoint */
|
||||||
private final Writer writer;
|
private final Writer writer;
|
||||||
/** Sampler defines the sampling policy in order to reduce the number of traces for instance */
|
/** Sampler defines the sampling policy in order to reduce the number of traces for instance */
|
||||||
|
@ -109,7 +107,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
|
|
||||||
final Codec<T> codec = registry.get(format);
|
final Codec<T> codec = registry.get(format);
|
||||||
if (codec == null) {
|
if (codec == null) {
|
||||||
logger.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
log.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
||||||
} else {
|
} else {
|
||||||
codec.inject((DDSpanContext) spanContext, carrier);
|
codec.inject((DDSpanContext) spanContext, carrier);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +118,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
|
|
||||||
final Codec<T> codec = registry.get(format);
|
final Codec<T> codec = registry.get(format);
|
||||||
if (codec == null) {
|
if (codec == null) {
|
||||||
logger.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
log.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
||||||
} else {
|
} else {
|
||||||
return codec.extract(carrier);
|
return codec.extract(carrier);
|
||||||
}
|
}
|
||||||
|
@ -176,14 +174,14 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
@Override
|
@Override
|
||||||
public ActiveSpan startActive() {
|
public ActiveSpan startActive() {
|
||||||
final ActiveSpan activeSpan = spanSource.makeActive(startSpan());
|
final ActiveSpan activeSpan = spanSource.makeActive(startSpan());
|
||||||
logger.debug("{} - Starting a new active span.", activeSpan);
|
log.debug("{} - Starting a new active span.", activeSpan);
|
||||||
return activeSpan;
|
return activeSpan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DDSpan startManual() {
|
public DDSpan startManual() {
|
||||||
final DDSpan span = startSpan();
|
final DDSpan span = startSpan();
|
||||||
logger.debug("{} - Starting a new manuel span.", span);
|
log.debug("{} - Starting a new manuel span.", span);
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +265,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DDSpanBuilder addReference(final String referenceType, final SpanContext spanContext) {
|
public DDSpanBuilder addReference(final String referenceType, final SpanContext spanContext) {
|
||||||
logger.debug("`addReference` method is not implemented. Doing nothing");
|
log.debug("`addReference` method is not implemented. Doing nothing");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import java.net.URLEncoder;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/** A codec designed for HTTP transport via headers */
|
/** A codec designed for HTTP transport via headers */
|
||||||
|
@Slf4j
|
||||||
public class HTTPCodec implements Codec<TextMap> {
|
public class HTTPCodec implements Codec<TextMap> {
|
||||||
|
|
||||||
private static final String OT_PREFIX = "ot-tracer-";
|
private static final String OT_PREFIX = "ot-tracer-";
|
||||||
|
@ -19,8 +19,6 @@ public class HTTPCodec implements Codec<TextMap> {
|
||||||
private static final String TRACE_ID_KEY = OT_PREFIX + "traceid";
|
private static final String TRACE_ID_KEY = OT_PREFIX + "traceid";
|
||||||
private static final String SPAN_ID_KEY = OT_PREFIX + "spanid";
|
private static final String SPAN_ID_KEY = OT_PREFIX + "spanid";
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(HTTPCodec.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inject(final DDSpanContext context, final TextMap carrier) {
|
public void inject(final DDSpanContext context, final TextMap carrier) {
|
||||||
|
|
||||||
|
@ -59,7 +57,7 @@ public class HTTPCodec implements Codec<TextMap> {
|
||||||
new DDSpanContext(
|
new DDSpanContext(
|
||||||
traceId, spanId, 0L, null, null, null, baggage, false, null, null, null, null);
|
traceId, spanId, 0L, null, null, null, baggage, false, null, null, null, null);
|
||||||
|
|
||||||
logger.debug("{} - Parent context extracted", context);
|
log.debug("{} - Parent context extracted", context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
@ -70,7 +68,7 @@ public class HTTPCodec implements Codec<TextMap> {
|
||||||
try {
|
try {
|
||||||
encoded = URLEncoder.encode(value, "UTF-8");
|
encoded = URLEncoder.encode(value, "UTF-8");
|
||||||
} catch (final UnsupportedEncodingException e) {
|
} catch (final UnsupportedEncodingException e) {
|
||||||
logger.info("Failed to encode value - {}", value);
|
log.info("Failed to encode value - {}", value);
|
||||||
}
|
}
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +78,7 @@ public class HTTPCodec implements Codec<TextMap> {
|
||||||
try {
|
try {
|
||||||
decoded = URLDecoder.decode(value, "UTF-8");
|
decoded = URLDecoder.decode(value, "UTF-8");
|
||||||
} catch (final UnsupportedEncodingException e) {
|
} catch (final UnsupportedEncodingException e) {
|
||||||
logger.info("Failed to decode value - {}", value);
|
log.info("Failed to decode value - {}", value);
|
||||||
}
|
}
|
||||||
return decoded;
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,12 @@ package com.datadoghq.trace.resolver;
|
||||||
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/** Create DDSpaDecorators from a valid configuration */
|
/** Create DDSpaDecorators from a valid configuration */
|
||||||
|
@Slf4j
|
||||||
public class DDDecoratorsFactory {
|
public class DDDecoratorsFactory {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDDecoratorsFactory.class);
|
|
||||||
|
|
||||||
public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration.";
|
public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration.";
|
||||||
|
|
||||||
public static final String CONFIG_PATH = "dd-trace-decorators.yaml";
|
public static final String CONFIG_PATH = "dd-trace-decorators.yaml";
|
||||||
|
@ -26,7 +24,7 @@ public class DDDecoratorsFactory {
|
||||||
final List<DDSpanContextDecorator> decorators = new ArrayList<>();
|
final List<DDSpanContextDecorator> decorators = new ArrayList<>();
|
||||||
for (final DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) {
|
for (final DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) {
|
||||||
if (decoratorConfig.getType() == null) {
|
if (decoratorConfig.getType() == null) {
|
||||||
logger.warn("Cannot create decorator without type from configuration {}", decoratorConfig);
|
log.warn("Cannot create decorator without type from configuration {}", decoratorConfig);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +33,7 @@ public class DDDecoratorsFactory {
|
||||||
try {
|
try {
|
||||||
decoratorClass = Class.forName(DECORATORS_PACKAGE + decoratorConfig.getType());
|
decoratorClass = Class.forName(DECORATORS_PACKAGE + decoratorConfig.getType());
|
||||||
} catch (final ClassNotFoundException e) {
|
} catch (final ClassNotFoundException e) {
|
||||||
logger.warn(
|
log.warn(
|
||||||
"Cannot create decorator as the class {} is not defined. Provided configuration {}",
|
"Cannot create decorator as the class {} is not defined. Provided configuration {}",
|
||||||
decoratorConfig);
|
decoratorConfig);
|
||||||
continue;
|
continue;
|
||||||
|
@ -45,7 +43,7 @@ public class DDDecoratorsFactory {
|
||||||
try {
|
try {
|
||||||
decorator = (DDSpanContextDecorator) decoratorClass.getConstructor().newInstance();
|
decorator = (DDSpanContextDecorator) decoratorClass.getConstructor().newInstance();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.warn(
|
log.warn(
|
||||||
"Cannot create decorator as we could not invoke the default constructor. Provided configuration {}",
|
"Cannot create decorator as we could not invoke the default constructor. Provided configuration {}",
|
||||||
decoratorConfig);
|
decoratorConfig);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -11,14 +11,12 @@ import com.datadoghq.trace.writer.LoggingWriter;
|
||||||
import com.datadoghq.trace.writer.Writer;
|
import com.datadoghq.trace.writer.Writer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/** Create a tracer from a configuration file */
|
/** Create a tracer from a configuration file */
|
||||||
|
@Slf4j
|
||||||
public class DDTracerFactory {
|
public class DDTracerFactory {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDTracerFactory.class);
|
|
||||||
|
|
||||||
public static final String SYSTEM_PROPERTY_CONFIG_PATH = "dd.trace.configurationFile";
|
public static final String SYSTEM_PROPERTY_CONFIG_PATH = "dd.trace.configurationFile";
|
||||||
public static final String CONFIG_PATH = "dd-trace.yaml";
|
public static final String CONFIG_PATH = "dd-trace.yaml";
|
||||||
|
|
||||||
|
@ -95,7 +93,7 @@ public class DDTracerFactory {
|
||||||
|
|
||||||
DDTracer tracer = null;
|
DDTracer tracer = null;
|
||||||
if (tracerConfig == null) {
|
if (tracerConfig == null) {
|
||||||
logger.info("No valid configuration file {} found. Loading default tracer.", CONFIG_PATH);
|
log.info("No valid configuration file {} found. Loading default tracer.", CONFIG_PATH);
|
||||||
tracer = new DDTracer();
|
tracer = new DDTracer();
|
||||||
} else {
|
} else {
|
||||||
tracer = DDTracerFactory.create(tracerConfig);
|
tracer = DDTracerFactory.create(tracerConfig);
|
||||||
|
|
|
@ -8,17 +8,15 @@ import io.opentracing.Tracer;
|
||||||
import io.opentracing.contrib.tracerresolver.TracerResolver;
|
import io.opentracing.contrib.tracerresolver.TracerResolver;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@AutoService(TracerResolver.class)
|
@AutoService(TracerResolver.class)
|
||||||
public class DDTracerResolver extends TracerResolver {
|
public class DDTracerResolver extends TracerResolver {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDTracerResolver.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Tracer resolve() {
|
protected Tracer resolve() {
|
||||||
logger.info("Creating the Datadog tracer");
|
log.info("Creating the Datadog tracer");
|
||||||
|
|
||||||
//Find a resource file named dd-trace.yml
|
//Find a resource file named dd-trace.yml
|
||||||
DDTracer tracer = null;
|
DDTracer tracer = null;
|
||||||
|
|
|
@ -6,11 +6,10 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class FactoryUtils {
|
public class FactoryUtils {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FactoryUtils.class);
|
|
||||||
|
|
||||||
private static final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
private static final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
||||||
|
|
||||||
|
@ -19,10 +18,10 @@ public class FactoryUtils {
|
||||||
final String filePath = System.getProperty(systemProperty);
|
final String filePath = System.getProperty(systemProperty);
|
||||||
if (filePath != null) {
|
if (filePath != null) {
|
||||||
try {
|
try {
|
||||||
logger.info("Loading config from file " + filePath);
|
log.info("Loading config from file " + filePath);
|
||||||
return objectMapper.readValue(new File(filePath), targetClass);
|
return objectMapper.readValue(new File(filePath), targetClass);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.error(
|
log.error(
|
||||||
"Cannot read provided configuration file " + filePath + ". Using the default one.", e);
|
"Cannot read provided configuration file " + filePath + ". Using the default one.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,12 +37,12 @@ public class FactoryUtils {
|
||||||
final Enumeration<URL> iter = classLoader.getResources(resourceName);
|
final Enumeration<URL> iter = classLoader.getResources(resourceName);
|
||||||
if (iter.hasMoreElements()) {
|
if (iter.hasMoreElements()) {
|
||||||
final URL url = iter.nextElement();
|
final URL url = iter.nextElement();
|
||||||
logger.info("Loading config from resource " + url);
|
log.info("Loading config from resource " + url);
|
||||||
config = objectMapper.readValue(url.openStream(), targetClass);
|
config = objectMapper.readValue(url.openStream(), targetClass);
|
||||||
}
|
}
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
logger.warn("Could not load configuration file {}.", resourceName);
|
log.warn("Could not load configuration file {}.", resourceName);
|
||||||
logger.error("Error when loading config file", e);
|
log.error("Error when loading config file", e);
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@ package com.datadoghq.trace.sampling;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This sampler sample the traces at a predefined rate.
|
* This sampler sample the traces at a predefined rate.
|
||||||
|
@ -11,10 +10,10 @@ import org.slf4j.LoggerFactory;
|
||||||
* <p>Keep (100 * `sample_rate`)% of the traces. It samples randomly, its main purpose is to reduce
|
* <p>Keep (100 * `sample_rate`)% of the traces. It samples randomly, its main purpose is to reduce
|
||||||
* the integration footprint.
|
* the integration footprint.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@AutoService(Sampler.class)
|
@AutoService(Sampler.class)
|
||||||
public class RateSampler extends AbstractSampler {
|
public class RateSampler extends AbstractSampler {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RateSampler.class);
|
|
||||||
/** The sample rate used */
|
/** The sample rate used */
|
||||||
private final double sampleRate;
|
private final double sampleRate;
|
||||||
|
|
||||||
|
@ -27,19 +26,19 @@ public class RateSampler extends AbstractSampler {
|
||||||
|
|
||||||
if (sampleRate <= 0) {
|
if (sampleRate <= 0) {
|
||||||
sampleRate = 1;
|
sampleRate = 1;
|
||||||
logger.error("SampleRate is negative or null, disabling the sampler");
|
log.error("SampleRate is negative or null, disabling the sampler");
|
||||||
} else if (sampleRate > 1) {
|
} else if (sampleRate > 1) {
|
||||||
sampleRate = 1;
|
sampleRate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sampleRate = sampleRate;
|
this.sampleRate = sampleRate;
|
||||||
logger.debug("Initializing the RateSampler, sampleRate: {} %", this.sampleRate * 100);
|
log.debug("Initializing the RateSampler, sampleRate: {} %", this.sampleRate * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doSample(DDBaseSpan<?> span) {
|
public boolean doSample(final DDBaseSpan<?> span) {
|
||||||
boolean sample = Math.random() <= this.sampleRate;
|
final boolean sample = Math.random() <= this.sampleRate;
|
||||||
logger.debug("{} - Span is sampled: {}", span, sample);
|
log.debug("{} - Span is sampled: {}", span, sample);
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,7 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This writer write provided traces to the a DD agent which is most of time located on the same
|
* This writer write provided traces to the a DD agent which is most of time located on the same
|
||||||
|
@ -21,11 +20,10 @@ import org.slf4j.LoggerFactory;
|
||||||
* if too much spans are collected the writers can reach a state where it is forced to drop incoming
|
* if too much spans are collected the writers can reach a state where it is forced to drop incoming
|
||||||
* spans.
|
* spans.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@AutoService(Writer.class)
|
@AutoService(Writer.class)
|
||||||
public class DDAgentWriter implements Writer {
|
public class DDAgentWriter implements Writer {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDAgentWriter.class.getName());
|
|
||||||
|
|
||||||
/** Default location of the DD agent */
|
/** Default location of the DD agent */
|
||||||
public static final String DEFAULT_HOSTNAME = "localhost";
|
public static final String DEFAULT_HOSTNAME = "localhost";
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ public class DDAgentWriter implements Writer {
|
||||||
if (proceed) {
|
if (proceed) {
|
||||||
traces.add(trace);
|
traces.add(trace);
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
log.warn(
|
||||||
"Cannot add a trace of {} as the async queue is full. Queue max size: {}",
|
"Cannot add a trace of {} as the async queue is full. Queue max size: {}",
|
||||||
trace.size(),
|
trace.size(),
|
||||||
DEFAULT_MAX_SPANS);
|
DEFAULT_MAX_SPANS);
|
||||||
|
@ -98,7 +96,7 @@ public class DDAgentWriter implements Writer {
|
||||||
try {
|
try {
|
||||||
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
|
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
logger.info("Writer properly closed and async writer interrupted.");
|
log.info("Writer properly closed and async writer interrupted.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +117,7 @@ public class DDAgentWriter implements Writer {
|
||||||
traces.drainTo(payload, DEFAULT_BATCH_SIZE);
|
traces.drainTo(payload, DEFAULT_BATCH_SIZE);
|
||||||
|
|
||||||
//SEND the payload to the agent
|
//SEND the payload to the agent
|
||||||
logger.debug("Async writer about to write {} traces.", payload.size());
|
log.debug("Async writer about to write {} traces.", payload.size());
|
||||||
api.sendTraces(payload);
|
api.sendTraces(payload);
|
||||||
|
|
||||||
//Compute the number of spans sent
|
//Compute the number of spans sent
|
||||||
|
@ -127,18 +125,18 @@ public class DDAgentWriter implements Writer {
|
||||||
for (final List<DDBaseSpan<?>> trace : payload) {
|
for (final List<DDBaseSpan<?>> trace : payload) {
|
||||||
spansCount += trace.size();
|
spansCount += trace.size();
|
||||||
}
|
}
|
||||||
logger.debug(
|
log.debug(
|
||||||
"Async writer just sent {} spans through {} traces", spansCount, payload.size());
|
"Async writer just sent {} spans through {} traces", spansCount, payload.size());
|
||||||
|
|
||||||
//Release the tokens
|
//Release the tokens
|
||||||
tokens.release(spansCount);
|
tokens.release(spansCount);
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
logger.info("Async writer interrupted.");
|
log.info("Async writer interrupted.");
|
||||||
|
|
||||||
//The thread was interrupted, we break the LOOP
|
//The thread was interrupted, we break the LOOP
|
||||||
break;
|
break;
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
logger.error("Unexpected error! Some traces may have been dropped.", e);
|
log.error("Unexpected error! Some traces may have been dropped.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,12 @@ import java.io.OutputStreamWriter;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/** The API pointing to a DD agent */
|
/** The API pointing to a DD agent */
|
||||||
|
@Slf4j
|
||||||
public class DDApi {
|
public class DDApi {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DDApi.class.getName());
|
|
||||||
|
|
||||||
private static final String TRACES_ENDPOINT = "/v0.3/traces";
|
private static final String TRACES_ENDPOINT = "/v0.3/traces";
|
||||||
|
|
||||||
private final String tracesEndpoint;
|
private final String tracesEndpoint;
|
||||||
|
@ -38,11 +36,10 @@ public class DDApi {
|
||||||
public boolean sendTraces(final List<List<DDBaseSpan<?>>> traces) {
|
public boolean sendTraces(final List<List<DDBaseSpan<?>>> traces) {
|
||||||
final int status = callPUT(traces);
|
final int status = callPUT(traces);
|
||||||
if (status == 200) {
|
if (status == 200) {
|
||||||
logger.debug("Succesfully sent {} traces to the DD agent.", traces.size());
|
log.debug("Succesfully sent {} traces to the DD agent.", traces.size());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
log.warn("Error while sending {} traces to the DD agent. Status: {}", traces.size(), status);
|
||||||
"Error while sending {} traces to the DD agent. Status: {}", traces.size(), status);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +56,7 @@ public class DDApi {
|
||||||
try {
|
try {
|
||||||
httpCon = getHttpURLConnection();
|
httpCon = getHttpURLConnection();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.warn("Error thrown before PUT call to the DD agent.", e);
|
log.warn("Error thrown before PUT call to the DD agent.", e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,16 +68,16 @@ public class DDApi {
|
||||||
jsonGen.close();
|
jsonGen.close();
|
||||||
final int responseCode = httpCon.getResponseCode();
|
final int responseCode = httpCon.getResponseCode();
|
||||||
if (responseCode == 200) {
|
if (responseCode == 200) {
|
||||||
logger.debug("Sent the payload to the DD agent.");
|
log.debug("Sent the payload to the DD agent.");
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
log.warn(
|
||||||
"Could not send the payload to the DD agent. Status: {} ResponseMessage: {}",
|
"Could not send the payload to the DD agent. Status: {} ResponseMessage: {}",
|
||||||
httpCon.getResponseCode(),
|
httpCon.getResponseCode(),
|
||||||
httpCon.getResponseMessage());
|
httpCon.getResponseMessage());
|
||||||
}
|
}
|
||||||
return responseCode;
|
return responseCode;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.warn("Could not send the payload to the DD agent.", e);
|
log.warn("Could not send the payload to the DD agent.", e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,26 +3,24 @@ package com.datadoghq.trace.writer;
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@AutoService(Writer.class)
|
@AutoService(Writer.class)
|
||||||
public class LoggingWriter implements Writer {
|
public class LoggingWriter implements Writer {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LoggingWriter.class.getName());
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final List<DDBaseSpan<?>> trace) {
|
public void write(final List<DDBaseSpan<?>> trace) {
|
||||||
logger.info("write(trace): {}", trace);
|
log.info("write(trace): {}", trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
logger.info("close()");
|
log.info("close()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
logger.info("start()");
|
log.info("start()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
|
||||||
sourceCompatibility = 1.7
|
sourceCompatibility = 1.7
|
||||||
targetCompatibility = 1.7
|
targetCompatibility = 1.7
|
||||||
|
|
||||||
|
apply plugin: "io.franzbecker.gradle-lombok"
|
||||||
|
|
||||||
|
lombok { // optional: values below are the defaults
|
||||||
|
version = "1.16.18"
|
||||||
|
sha256 = "9d957f572386b9e257093a45b148f9b411cff80d9efd55eaf6fca27002d2e4d9"
|
||||||
|
}
|
||||||
|
|
||||||
task packageSources(type: Jar) {
|
task packageSources(type: Jar) {
|
||||||
classifier = 'sources'
|
classifier = 'sources'
|
||||||
from sourceSets.main.allSource
|
from sourceSets.main.allSource
|
||||||
|
|
Loading…
Reference in New Issue