New feature: disabling instrumentations
This commit is contained in:
parent
0265abd9a7
commit
96e98e3567
|
@ -72,9 +72,17 @@ sampler:
|
||||||
# RateSample: only a portion of spans are reported to the writer
|
# RateSample: only a portion of spans are reported to the writer
|
||||||
# - Param 'rate': the portion of spans to keep
|
# - Param 'rate': the portion of spans to keep
|
||||||
type: AllSampler
|
type: AllSampler
|
||||||
|
# Skip some traces if the root span tag values matches some regexp patterns
|
||||||
|
# skipTagsPatterns: {"http.url": ".*/demo/add.*"}
|
||||||
|
|
||||||
|
# Enable custom tracing (Custom annotations for now)
|
||||||
|
enableCustomTracing: true
|
||||||
|
|
||||||
|
# Disable some instrumentations
|
||||||
|
# disabledInstrumentations: ["apache http", "mongo", "jetty", "tomcat", ...]
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to change it, you should then create it in your project and change it as suited.
|
If you want to change it, you must create it in your project.
|
||||||
|
|
||||||
## Instrumented frameworks
|
## Instrumented frameworks
|
||||||
|
|
||||||
|
@ -114,6 +122,21 @@ But unfortunately this can not be done entirely automatically today. To enable t
|
||||||
|
|
||||||
We also provide an [example project with Spring Boot & MySQL](web application frameworks).
|
We also provide an [example project with Spring Boot & MySQL](web application frameworks).
|
||||||
|
|
||||||
|
### Disabling instrumentations
|
||||||
|
|
||||||
|
If for some reasons you need to disable an instrumentation you should uncomment the `disabledInstrumentations: ` attribute in the configuration and provide a list as illustrated below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
...
|
||||||
|
|
||||||
|
# Disable a few instrumentations
|
||||||
|
disabledInstrumentations: ["apache http", "mongo", "tomcat"]
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
## Custom instrumentations
|
## Custom instrumentations
|
||||||
|
|
||||||
### The `@trace` annotation
|
### The `@trace` annotation
|
||||||
|
|
|
@ -1,11 +1,24 @@
|
||||||
package com.datadoghq.trace.resolver;
|
package com.datadoghq.trace.resolver;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration POJO for the agent
|
* Configuration POJO for the agent
|
||||||
*/
|
*/
|
||||||
public class AgentTracerConfig extends TracerConfig {
|
public class AgentTracerConfig extends TracerConfig {
|
||||||
|
|
||||||
private boolean enableCustomTracing = false;
|
private boolean enableCustomTracing = false;
|
||||||
|
|
||||||
|
private List<String> disabledInstrumentations = new ArrayList<String>();
|
||||||
|
|
||||||
|
public List<String> getDisabledInstrumentations() {
|
||||||
|
return disabledInstrumentations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisabledInstrumentations(List<String> uninstallContributions) {
|
||||||
|
this.disabledInstrumentations = uninstallContributions;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnableCustomTracing() {
|
public boolean isEnableCustomTracing() {
|
||||||
return enableCustomTracing;
|
return enableCustomTracing;
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
package io.opentracing.contrib.agent;
|
package io.opentracing.contrib.agent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.jboss.byteman.agent.Location;
|
import org.jboss.byteman.agent.Location;
|
||||||
import org.jboss.byteman.agent.LocationType;
|
import org.jboss.byteman.agent.LocationType;
|
||||||
|
@ -31,11 +42,13 @@ import javassist.bytecode.Descriptor;
|
||||||
*
|
*
|
||||||
* It loads all the scripts contained in all the 'oatrules.btm' resource files then instrument all the methods annoted with the @Trace.
|
* It loads all the scripts contained in all the 'oatrules.btm' resource files then instrument all the methods annoted with the @Trace.
|
||||||
*/
|
*/
|
||||||
public class TraceAnnotationsManager extends OpenTracingManager{
|
public class TraceAnnotationsManager {
|
||||||
private static Logger log = Logger.getLogger(TraceAnnotationsManager.class.getName());
|
private static Logger log = Logger.getLogger(TraceAnnotationsManager.class.getName());
|
||||||
|
|
||||||
private static Retransformer transformer;
|
private static Retransformer transformer;
|
||||||
|
|
||||||
|
private static final String AGENT_RULES = "otarules.btm";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method initializes the manager.
|
* This method initializes the manager.
|
||||||
*
|
*
|
||||||
|
@ -44,24 +57,57 @@ public class TraceAnnotationsManager extends OpenTracingManager{
|
||||||
*/
|
*/
|
||||||
public static void initialize(Retransformer trans) throws Exception {
|
public static void initialize(Retransformer trans) throws Exception {
|
||||||
transformer = trans;
|
transformer = trans;
|
||||||
OpenTracingManager.initialize(trans);
|
|
||||||
OpenTracingManager.loadRules(ClassLoader.getSystemClassLoader());
|
|
||||||
|
|
||||||
//Load configuration
|
//Load configuration
|
||||||
AgentTracerConfig agentTracerConfig = FactoryUtils.loadConfigFromResource(DDTracerFactory.CONFIG_PATH, AgentTracerConfig.class);
|
AgentTracerConfig agentTracerConfig = FactoryUtils.loadConfigFromResource(DDTracerFactory.CONFIG_PATH, AgentTracerConfig.class);
|
||||||
|
|
||||||
|
List<String> loadedScripts = loadRules(ClassLoader.getSystemClassLoader());
|
||||||
|
|
||||||
|
//Check if some rules have to be uninstalled
|
||||||
|
if(agentTracerConfig != null){
|
||||||
|
List<String> uninstallContributions = agentTracerConfig.getDisabledInstrumentations();
|
||||||
|
if(uninstallContributions!=null && !uninstallContributions.isEmpty()){
|
||||||
|
uninstallScripts(loadedScripts,uninstallContributions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Check if annotations are enabled
|
//Check if annotations are enabled
|
||||||
if(agentTracerConfig.isEnableCustomTracing()){
|
if(agentTracerConfig != null && agentTracerConfig.isEnableCustomTracing()){
|
||||||
loadRules(ClassLoader.getSystemClassLoader());
|
loadAnnotationsRules(ClassLoader.getSystemClassLoader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall some scripts from a list of patterns.
|
||||||
|
* All the rules that contain the pattern will be uninstalled
|
||||||
|
*
|
||||||
|
* @param installedScripts
|
||||||
|
* @param patterns not case sensitive (eg. "mongo", "apache http", "elasticsearch", etc...])
|
||||||
|
*/
|
||||||
|
public static void uninstallScripts(List<String> installedScripts, List<String> patterns) throws Exception{
|
||||||
|
Set<String> rulesToRemove = new HashSet<String>();
|
||||||
|
|
||||||
|
for(String strPattern : patterns){
|
||||||
|
Pattern pattern = Pattern.compile("(?i)RULE [^\n]*"+strPattern+"[^\n]*\n");
|
||||||
|
for(String loadedScript : installedScripts){
|
||||||
|
Matcher matcher = pattern.matcher(loadedScript);
|
||||||
|
while(matcher.find()){
|
||||||
|
rulesToRemove.add(matcher.group());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
try(PrintWriter pr = new PrintWriter(sw)){
|
||||||
|
transformer.removeScripts(new ArrayList<String>(rulesToRemove), pr);
|
||||||
|
}
|
||||||
|
log.log(Level.INFO, sw.toString());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all the methods annoted with @Trace and inject rules
|
* Find all the methods annoted with @Trace and inject rules
|
||||||
*
|
*
|
||||||
* @param classLoader
|
* @param classLoader
|
||||||
*/
|
*/
|
||||||
public static void loadRules(ClassLoader classLoader) {
|
public static void loadAnnotationsRules(ClassLoader classLoader) {
|
||||||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||||||
.forPackages("/")
|
.forPackages("/")
|
||||||
.filterInputsBy(new FilterBuilder().include(".*\\.class"))
|
.filterInputsBy(new FilterBuilder().include(".*\\.class"))
|
||||||
|
@ -140,6 +186,67 @@ public class TraceAnnotationsManager extends OpenTracingManager{
|
||||||
return ruleScript;
|
return ruleScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads any OpenTracing Agent rules (otarules.btm) found as resources
|
||||||
|
* within the supplied classloader.
|
||||||
|
*
|
||||||
|
* @param classLoader The classloader
|
||||||
|
*/
|
||||||
|
public static List<String> loadRules(ClassLoader classLoader) {
|
||||||
|
List<String> scripts = new ArrayList<>();
|
||||||
|
if (transformer == null) {
|
||||||
|
log.severe("Attempt to load OpenTracing agent rules before transformer initialized");
|
||||||
|
return scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> scriptNames = new ArrayList<>();
|
||||||
|
|
||||||
|
// Load default and custom rules
|
||||||
|
try {
|
||||||
|
Enumeration<URL> iter = classLoader.getResources(AGENT_RULES);
|
||||||
|
while (iter.hasMoreElements()) {
|
||||||
|
loadRules(iter.nextElement().toURI(), scriptNames, scripts);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter sw=new StringWriter();
|
||||||
|
try (PrintWriter writer = new PrintWriter(sw)) {
|
||||||
|
try {
|
||||||
|
transformer.installScript(scripts, scriptNames, writer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "Failed to install scripts", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (log.isLoggable(Level.FINEST)) {
|
||||||
|
log.finest(sw.toString());
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
log.log(Level.SEVERE, "Failed to load OpenTracing agent rules", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.isLoggable(Level.FINE)) {
|
||||||
|
log.fine("OpenTracing Agent rules loaded");
|
||||||
|
}
|
||||||
|
return scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadRules(URI uri, final List<String> scriptNames,
|
||||||
|
final List<String> scripts) throws IOException {
|
||||||
|
if (log.isLoggable(Level.FINE)) {
|
||||||
|
log.fine("Load rules from URI = " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder str=new StringBuilder();
|
||||||
|
try (InputStream is = uri.toURL().openStream()) {
|
||||||
|
byte[] b = new byte[10240];
|
||||||
|
int len;
|
||||||
|
while ((len = is.read(b)) != -1) {
|
||||||
|
str.append(new String(b, 0, len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scripts.add(str.toString());
|
||||||
|
scriptNames.add(uri.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private static String CURRENT_SPAN_EXISTS = "IF currentSpan() != null\n";
|
private static String CURRENT_SPAN_EXISTS = "IF currentSpan() != null\n";
|
||||||
private static String CURRENT_SPAN_NOT_EXISTS = "IF currentSpan() == null\n";
|
private static String CURRENT_SPAN_NOT_EXISTS = "IF currentSpan() == null\n";
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,11 @@ sampler:
|
||||||
# RateSample: only a portion of spans are reported to the writer
|
# RateSample: only a portion of spans are reported to the writer
|
||||||
# - Param 'rate': the portion of spans to keep
|
# - Param 'rate': the portion of spans to keep
|
||||||
type: AllSampler
|
type: AllSampler
|
||||||
|
# Skip some traces if the root span tag values matches some regexp patterns
|
||||||
|
# skipTagsPatterns: {"http.url": ".*/demo/add.*"}
|
||||||
|
|
||||||
# Enable custom tracing (annotations)
|
# Enable custom tracing (Custom annotations for now)
|
||||||
# enableCustomTracing: true
|
# enableCustomTracing: true
|
||||||
|
|
||||||
|
# Disable some instrumentations
|
||||||
|
# disabledInstrumentations: ["apache http", "mongo", "jetty", "tomcat", ...]
|
|
@ -15,11 +15,11 @@ public class TraceAnnotationsManagerTest {
|
||||||
@Before
|
@Before
|
||||||
public void beforeTest() throws Exception {
|
public void beforeTest() throws Exception {
|
||||||
GlobalTracer.register(tracer);
|
GlobalTracer.register(tracer);
|
||||||
TraceAnnotationsManager.loadRules(ClassLoader.getSystemClassLoader());
|
TraceAnnotationsManager.loadAnnotationsRules(ClassLoader.getSystemClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void testAnnotations() {
|
||||||
//Test single span in new trace
|
//Test single span in new trace
|
||||||
SayTracedHello.sayHello();
|
SayTracedHello.sayHello();
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,8 @@ sampler:
|
||||||
# Skip some traces if the root span tag values matches some regexp patterns
|
# Skip some traces if the root span tag values matches some regexp patterns
|
||||||
# skipTagsPatterns: {"http.url": ".*/demo/add.*"}
|
# skipTagsPatterns: {"http.url": ".*/demo/add.*"}
|
||||||
|
|
||||||
# Enable custom tracing (annotations)
|
# Enable custom tracing (Custom annotations for now)
|
||||||
enableCustomTracing: true
|
enableCustomTracing: true
|
||||||
|
|
||||||
|
# Disable some instrumentations
|
||||||
|
# disabledInstrumentations: ["apache http", "mongo", "jetty", "tomcat", ...]
|
Loading…
Reference in New Issue