Ver código fonte

Remove Byteman now that instrumentation is migrated

At some point, we should refactor the managers since this leaves them in an awkward state.
Tyler Benson 7 anos atrás
pai
commit
6f985c15bf

+ 0 - 1
LICENSE-3rdparty.csv

@@ -9,4 +9,3 @@ logback.xml,net.logstash.logback,Apache-2.0,
 import (test),org.junit,EPL-1.0,Copyright © 2002-2017 JUnit. All Rights Reserved.
 import (test),org.assertj,Apache-2.0,Copyright 2012-2017 the original author or authors.
 import (test),org.mockito,MIT,Copyright (c) 2007 Mockito contributors
-Byteman (JVM code injector),JBoss,LGPL-2.1,"Copyright 2008-12, Red Hat and individual contributors"

+ 0 - 4
dd-java-agent-ittests/dd-java-agent-ittests.gradle

@@ -43,8 +43,6 @@ test {
   jvmArgs "-Ddd.trace.configurationFile=${project.buildDir}/resources/test/dd-trace.yaml"
   jvmArgs "-Ddd.slf4j.simpleLogger.defaultLogLevel=debug"
   jvmArgs "-Dorg.slf4j.simpleLogger.defaultLogLevel=debug"
-  jvmArgs "-Ddd.deps.org.jboss.byteman.verbose=true"
-  jvmArgs "-Dorg.jboss.byteman.verbose=true"
 
   doFirst {
     // Defining here to allow jacoco to be first on the command line.
@@ -68,8 +66,6 @@ task expensiveTest(type: Test) {
   jvmArgs "-Ddd.trace.configurationFile=${project.buildDir}/resources/test/dd-trace.yaml"
   jvmArgs "-Ddd.slf4j.simpleLogger.defaultLogLevel=debug"
   jvmArgs "-Dorg.slf4j.simpleLogger.defaultLogLevel=debug"
-  jvmArgs "-Ddd.deps.org.jboss.byteman.verbose=true"
-  jvmArgs "-Dorg.jboss.byteman.verbose=true"
 
   doFirst {
     // Defining here to allow jacoco to be first on the command line.

+ 0 - 6
dd-java-agent/dd-java-agent.gradle

@@ -56,7 +56,6 @@ dependencies {
   }
 
   compile deps.bytebuddy
-  compile group: 'org.jboss.byteman', name: 'byteman', version: '3.0.10'
 
   compile deps.autoservice
   compile deps.slf4j
@@ -120,11 +119,6 @@ shadowJar {
     relocate 'com.fasterxml', 'dd.deps.com.fasterxml'
 
     relocate 'net.bytebuddy', 'dd.deps.net.bytebuddy'
-    relocate('org.jboss.byteman', 'dd.deps.org.jboss.byteman') {
-      // Renaming these causes a verify error in the tests.
-      exclude 'org.jboss.byteman.rule.*'
-      exclude 'org.jboss.byteman.rule.helper.*'
-    }
     relocate('com.google', 'dd.deps.com.google') {
       // This is used in the Cassandra Cluster.connectAsync signature so we can't relocate it. :fingers_crossed:
       exclude 'com.google.common.util.concurrent.ListenableFuture'

+ 0 - 2
dd-java-agent/integrations/helpers/helpers.gradle

@@ -11,8 +11,6 @@ dependencies {
   compileOnly project(':dd-trace-annotations')
   compileOnly deps.slf4j
 
-  compileOnly group: 'org.jboss.byteman', name: 'byteman', version: '4.0.0-BETA5'
-
   compile group: 'io.opentracing.contrib', name: 'opentracing-web-servlet-filter', version: '0.0.9'
   compile group: 'io.opentracing.contrib', name: 'opentracing-okhttp3', version: '0.0.5'
   compile group: 'io.opentracing.contrib', name: 'opentracing-aws-sdk', version: '0.0.2'

+ 0 - 78
dd-java-agent/integrations/helpers/src/main/java/com/datadoghq/agent/integration/DDAgentTracingHelper.java

@@ -1,78 +0,0 @@
-package com.datadoghq.agent.integration;
-
-import io.opentracing.NoopTracerFactory;
-import io.opentracing.Tracer;
-import lombok.extern.slf4j.Slf4j;
-import org.jboss.byteman.rule.Rule;
-
-/**
- * This class provides helpful stuff in order to easy patch object using Byteman rules
- *
- * @param <T> The type of the object to patch
- */
-@Slf4j
-public abstract class DDAgentTracingHelper<T> extends OpenTracingHelper {
-
-  /**
-   * The current instance of the tracer. If something goes wrong during the resolution, we provides
-   * a NoopTracer.
-   */
-  protected final Tracer tracer;
-
-  // This is intentionally protected scope to avoid IllegalAccessError if on separate classloaders:
-  // https://stackoverflow.com/a/10538366
-  protected DDAgentTracingHelper(final Rule rule) {
-    super(rule);
-    Tracer tracerResolved;
-    try {
-      tracerResolved = getTracer();
-      tracerResolved = tracerResolved == null ? NoopTracerFactory.create() : tracerResolved;
-    } catch (final Exception e) {
-      tracerResolved = NoopTracerFactory.create();
-      log.warn("Failed to retrieve the tracer, using a NoopTracer instead: {}", e.getMessage());
-      log.warn(e.getMessage(), e);
-    }
-    tracer = tracerResolved;
-  }
-
-  /**
-   * This method takes an object and applies some mutation in order to add tracing capabilities.
-   * This method should never return any Exception in order to not stop the app traced.
-   *
-   * <p>This method should be defined as final, but something Byteman need to define this one with
-   * the explicit type (i.e. without using generic), so this is why we don't use final here.
-   *
-   * @param args The object to patch, the type is defined by the subclass instantiation
-   * @return The object patched
-   */
-  public T patch(final T args) {
-
-    if (args == null) {
-      log.debug("Skipping rule={} because the input arg is null", rule.getName());
-      return null;
-    }
-
-    final String className = args.getClass().getName();
-    log.debug("Try to patch class={}", className);
-
-    T patched;
-    try {
-      patched = doPatch(args);
-      log.debug("class={} patched", className);
-    } catch (final Throwable e) {
-      log.warn("Failed to patch class={}, reason: {}", className, e.getMessage());
-      log.warn(e.getMessage(), e);
-      patched = args;
-    }
-    return patched;
-  }
-
-  /**
-   * The current implementation of the patch
-   *
-   * @param obj the object to patch
-   * @return the object patched
-   * @throws Exception The exceptions are managed directly to the patch method
-   */
-  protected abstract T doPatch(T obj) throws Exception;
-}

+ 0 - 296
dd-java-agent/integrations/helpers/src/main/java/com/datadoghq/agent/integration/OpenTracingHelper.java

@@ -1,296 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.datadoghq.agent.integration;
-
-import io.opentracing.ActiveSpan;
-import io.opentracing.BaseSpan;
-import io.opentracing.Span;
-import io.opentracing.SpanContext;
-import io.opentracing.Tracer;
-import io.opentracing.Tracer.SpanBuilder;
-import io.opentracing.contrib.tracerresolver.TracerResolver;
-import io.opentracing.propagation.Format;
-import io.opentracing.util.GlobalTracer;
-import java.net.HttpURLConnection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.jboss.byteman.rule.Rule;
-import org.jboss.byteman.rule.helper.Helper;
-
-/** This class provides helper capabilities to the byteman rules. */
-public class OpenTracingHelper extends Helper {
-
-  private static final Logger log = Logger.getLogger(OpenTracingHelper.class.getName());
-
-  private static Tracer tracer;
-
-  private static final Map<Object, Span> spanAssociations =
-      Collections.synchronizedMap(new WeakHashMap<Object, Span>());
-  private static final Map<Object, Span> finished =
-      Collections.synchronizedMap(new WeakHashMap<Object, Span>());
-
-  private static final Map<Object, Integer> state =
-      Collections.synchronizedMap(new WeakHashMap<Object, Integer>());
-
-  private static final Object SYNC = new Object();
-
-  public OpenTracingHelper(final Rule rule) {
-    super(rule);
-  }
-
-  /**
-   * This method returns the OpenTracing tracer.
-   *
-   * @return The tracer
-   */
-  public Tracer getTracer() {
-    if (tracer == null) {
-      // Initialize on first use
-      initTracer();
-    }
-    return tracer;
-  }
-
-  protected void initTracer() {
-    synchronized (SYNC) {
-      if (tracer == null) {
-        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.log(Level.WARNING, "Failed to register tracer '" + resolved + "'", re);
-            }
-          }
-        }
-        // Initialize the tracer even if one has not been registered
-        // (i.e. it will use a NoopTracer under the covers)
-        tracer = new AgentTracer(GlobalTracer.get());
-      }
-    }
-  }
-
-  /**
-   * This method establishes an association between an application object (i.e. the subject of the
-   * instrumentation) and a span. Once the application object is no longer being used, the
-   * association with the span will automatically be discarded.
-   *
-   * @param obj The application object to be associated with the span
-   * @param span The span
-   */
-  public void associateSpan(final Object obj, final Span span) {
-    spanAssociations.put(obj, span);
-  }
-
-  /**
-   * This method retrieves the span associated with the supplied application object.
-   *
-   * @param obj The application object
-   * @return The span, or null if no associated span exists
-   */
-  public Span retrieveSpan(final Object obj) {
-    return spanAssociations.get(obj);
-  }
-
-  /** ******************************************* */
-  /** Needs to be replaced by span.isFinished() */
-  public void finishedSpan(final Object key, final Span span) {
-    finished.put(key, span);
-  }
-
-  public boolean isFinished(final Object key) {
-    return finished.containsKey(key);
-  }
-  /** ******************************************* */
-
-  /**
-   * This method enables an instrumentation rule to record a 'state' number against an application
-   * object. This can be used in situations where rules are only applicable in certain states. For
-   * example, the simple case for rules responsible for installing filters would be states
-   * representing NOT_INSTALLED and INSTALLED. This means that the filter would only be installed if
-   * the application object (target of the instrumentation rule) was in the NOT_INSTALLED state.
-   * However other more complex scenarios may be encountered where more than two states are
-   * required.
-   *
-   * @param obj The application object
-   * @param value The state value
-   */
-  public void setState(final Object obj, final int value) {
-    state.put(obj, new Integer(value));
-  }
-
-  /**
-   * This method retrieves the current 'state' number associated with the supplied application
-   * object.
-   *
-   * @param obj The application object
-   * @return The state, or 0 if no state currently exists
-   */
-  public int getState(final Object obj) {
-    final Integer value = state.get(obj);
-    return value == null ? 0 : value.intValue();
-  }
-
-  /**
-   * This method determines whether the instrumentation point, associated with the supplied object,
-   * should be ignored.
-   *
-   * @param obj The instrumentation target
-   * @return Whether the instrumentation point should be ignored
-   */
-  public boolean ignore(final Object obj) {
-    boolean ignore = false;
-
-    if (obj instanceof HttpURLConnection) {
-      final String value = ((HttpURLConnection) obj).getRequestProperty("opentracing.ignore");
-      ignore = value != null && value.equalsIgnoreCase("true");
-    }
-
-    // TODO: If other technologies need to use this feature,
-    // then create an Adapter to wrap the specifics of each
-    // technology and provide access to their properties
-
-    if (ignore && log.isLoggable(Level.FINEST)) {
-      log.finest("Ignoring request because the property [opentracing.ignore] is present.");
-    }
-
-    return ignore;
-  }
-
-  /**
-   * Proxy tracer used for one purpose - to enable the rules to define a ChildOf relationship
-   * without being concerned whether the supplied Span is null. If the spec (and Tracer
-   * implementations) are updated to indicate a null should be ignored, then this proxy can be
-   * removed.
-   */
-  public static class AgentTracer implements Tracer {
-
-    private final Tracer tracer;
-
-    public AgentTracer(final Tracer tracer) {
-      this.tracer = tracer;
-    }
-
-    @Override
-    public SpanBuilder buildSpan(final String operation) {
-      return new AgentSpanBuilder(tracer.buildSpan(operation));
-    }
-
-    @Override
-    public <C> SpanContext extract(final Format<C> format, final C carrier) {
-      return tracer.extract(format, carrier);
-    }
-
-    @Override
-    public <C> void inject(final SpanContext ctx, final Format<C> format, final C carrier) {
-      tracer.inject(ctx, format, carrier);
-    }
-
-    @Override
-    public ActiveSpan activeSpan() {
-      return tracer.activeSpan();
-    }
-
-    @Override
-    public ActiveSpan makeActive(final Span span) {
-      return tracer.makeActive(span);
-    }
-  }
-
-  public static class AgentSpanBuilder implements SpanBuilder {
-
-    private final SpanBuilder spanBuilder;
-
-    public AgentSpanBuilder(final SpanBuilder spanBuilder) {
-      this.spanBuilder = spanBuilder;
-    }
-
-    @Override
-    public SpanBuilder addReference(final String type, final SpanContext ctx) {
-      if (ctx != null) {
-        spanBuilder.addReference(type, ctx);
-      }
-      return this;
-    }
-
-    @Override
-    public SpanBuilder asChildOf(final SpanContext ctx) {
-      if (ctx != null) {
-        spanBuilder.asChildOf(ctx);
-      }
-      return this;
-    }
-
-    @Override
-    public SpanBuilder asChildOf(final BaseSpan<?> span) {
-      if (span != null) {
-        spanBuilder.asChildOf(span);
-      }
-      return this;
-    }
-
-    @Override
-    public Span start() {
-      return spanBuilder.start();
-    }
-
-    @Override
-    public SpanBuilder withStartTimestamp(final long ts) {
-      spanBuilder.withStartTimestamp(ts);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final String value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final boolean value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final Number value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder ignoreActiveSpan() {
-      spanBuilder.ignoreActiveSpan();
-      return this;
-    }
-
-    @Override
-    public ActiveSpan startActive() {
-      return spanBuilder.startActive();
-    }
-
-    @Override
-    public Span startManual() {
-      return spanBuilder.startManual();
-    }
-  }
-}

+ 5 - 91
dd-java-agent/src/main/java/com/datadoghq/agent/AgentRulesManager.java

@@ -4,18 +4,7 @@ import com.datadoghq.trace.DDTraceAnnotationsInfo;
 import com.datadoghq.trace.DDTraceInfo;
 import com.datadoghq.trace.resolver.DDTracerFactory;
 import com.datadoghq.trace.resolver.FactoryUtils;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
 import lombok.extern.slf4j.Slf4j;
-import org.jboss.byteman.agent.Retransformer;
 
 @Slf4j
 public class AgentRulesManager {
@@ -29,22 +18,16 @@ public class AgentRulesManager {
 
   protected static volatile AgentRulesManager INSTANCE;
 
-  protected final Retransformer transformer;
   protected final TracingAgentConfig agentTracerConfig;
   protected final InstrumentationRulesManager instrumentationRulesManager;
 
-  public AgentRulesManager(final Retransformer trans, final TracingAgentConfig config) {
-    transformer = trans;
+  public AgentRulesManager(final TracingAgentConfig config) {
     agentTracerConfig = config;
-    instrumentationRulesManager = new InstrumentationRulesManager(trans, config, this);
+    instrumentationRulesManager = new InstrumentationRulesManager(config, this);
   }
 
-  /**
-   * This method initializes the manager.
-   *
-   * @param trans The ByteMan retransformer
-   */
-  public static void initialize(final Retransformer trans) {
+  /** This method initializes the manager. */
+  public static void initialize() {
     log.debug("Initializing {}", AgentRulesManager.class.getSimpleName());
 
     final TracingAgentConfig config =
@@ -55,77 +38,8 @@ public class AgentRulesManager {
 
     log.debug("Configuration: {}", config.toString());
 
-    final AgentRulesManager manager = new AgentRulesManager(trans, config);
+    final AgentRulesManager manager = new AgentRulesManager(config);
 
     INSTANCE = manager;
-
-    manager.loadRules(INITIALIZER_RULES, ClassLoader.getSystemClassLoader());
-  }
-
-  /**
-   * This method loads any OpenTracing Agent rules (integration-rules.btm) found as resources within
-   * the supplied classloader.
-   *
-   * @param classLoader The classloader
-   */
-  protected List<String> loadRules(final String rulesFileName, final ClassLoader classLoader) {
-    final List<String> scripts = new ArrayList<>();
-    if (transformer == null) {
-      log.warn(
-          "Attempt to load rules file {} on classloader {} before transformer initialized",
-          rulesFileName,
-          classLoader == null ? "bootstrap" : classLoader);
-      return scripts;
-    }
-
-    log.debug("Loading rules with classloader {}", classLoader == null ? "bootstrap" : classLoader);
-
-    final List<String> scriptNames = new ArrayList<>();
-
-    // Load default and custom rules
-    try {
-      final Enumeration<URL> iter = classLoader.getResources(rulesFileName);
-      while (iter.hasMoreElements()) {
-        loadRules(iter.nextElement().toURI(), scriptNames, scripts);
-      }
-
-      final StringWriter sw = new StringWriter();
-      try (PrintWriter writer = new PrintWriter(sw)) {
-        try {
-          transformer.installScript(scripts, scriptNames, writer);
-        } catch (final Exception e) {
-          log.warn("Failed to install scripts", e);
-        }
-      }
-      log.debug(sw.toString());
-    } catch (IOException | URISyntaxException e) {
-      log.warn("Failed to load rules", e);
-    }
-
-    log.debug("Rules loaded from {} on classloader {}", rulesFileName, classLoader);
-    if (log.isTraceEnabled()) {
-      for (final String rule : scripts) {
-        log.trace("Loading rule: {}", rule);
-      }
-    }
-    return scripts;
-  }
-
-  private static void loadRules(
-      final URI uri, final List<String> scriptNames, final List<String> scripts)
-      throws IOException {
-    log.debug("Load rules from URI uri={} ", uri);
-
-    final StringBuilder str = new StringBuilder();
-    try (InputStream is = uri.toURL().openStream()) {
-
-      final 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());
   }
 }

+ 1 - 59
dd-java-agent/src/main/java/com/datadoghq/agent/InstrumentationRulesManager.java

@@ -7,21 +7,13 @@ import io.opentracing.util.GlobalTracer;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 import lombok.extern.slf4j.Slf4j;
-import org.jboss.byteman.agent.Retransformer;
 
 /**
  * This manager is loaded at pre-main. It loads all the scripts contained in all the 'oatrules.btm'
@@ -35,7 +27,6 @@ public class InstrumentationRulesManager {
 
   private static final Object SYNC = new Object();
 
-  private final Retransformer transformer;
   private final TracingAgentConfig config;
   private final AgentRulesManager agentRulesManager;
   private final ClassLoaderIntegrationInjector injector;
@@ -45,10 +36,7 @@ public class InstrumentationRulesManager {
       Collections.newSetFromMap(new WeakHashMap<ClassLoader, Boolean>());
 
   public InstrumentationRulesManager(
-      final Retransformer trans,
-      final TracingAgentConfig config,
-      final AgentRulesManager agentRulesManager) {
-    this.transformer = trans;
+      final TracingAgentConfig config, final AgentRulesManager agentRulesManager) {
     this.config = config;
     this.agentRulesManager = agentRulesManager;
     final InputStream helpersStream = this.getClass().getResourceAsStream(HELPERS_NAME);
@@ -116,55 +104,9 @@ public class InstrumentationRulesManager {
 
     injector.inject(classLoader);
 
-    final List<String> loadedScripts = agentRulesManager.loadRules(INTEGRATION_RULES, classLoader);
-
-    // Check if some rules have to be uninstalled
-    final List<String> uninstallScripts = checker.getUnsupportedRules(classLoader);
-    if (config != null) {
-      final List<String> disabledInstrumentations = config.getDisabledInstrumentations();
-      if (disabledInstrumentations != null && !disabledInstrumentations.isEmpty()) {
-        uninstallScripts.addAll(disabledInstrumentations);
-      }
-    }
-
-    try {
-      uninstallScripts(loadedScripts, uninstallScripts);
-    } catch (final Exception e) {
-      log.warn("Error uninstalling scripts", e);
-    }
-
     initTracer();
   }
 
-  /**
-   * Uninstall some scripts from a list of patterns. All the rules that contain the pattern will be
-   * uninstalled
-   *
-   * @param patterns not case sensitive (eg. "mongo", "apache http", "elasticsearch", etc...])
-   */
-  private void uninstallScripts(final List<String> installedScripts, final List<String> patterns)
-      throws Exception {
-    final Set<String> rulesToRemove = new HashSet<>();
-
-    for (final String strPattern : patterns) {
-      final Pattern pattern = Pattern.compile("(?i)RULE [^\n]*" + strPattern + "[^\n]*\n");
-      for (final String loadedScript : installedScripts) {
-        final Matcher matcher = pattern.matcher(loadedScript);
-        while (matcher.find()) {
-          rulesToRemove.add(matcher.group());
-        }
-      }
-    }
-
-    if (!rulesToRemove.isEmpty()) {
-      final StringWriter sw = new StringWriter();
-      try (PrintWriter pr = new PrintWriter(sw)) {
-        transformer.removeScripts(new ArrayList<>(rulesToRemove), pr);
-      }
-      log.info("Uninstall rule scripts: {}", rulesToRemove.toString());
-    }
-  }
-
   private void initTracer() {
     synchronized (SYNC) {
       if (!GlobalTracer.isRegistered()) {

+ 0 - 296
dd-java-agent/src/main/java/com/datadoghq/agent/OpenTracingHelper.java

@@ -1,296 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.datadoghq.agent;
-
-import io.opentracing.ActiveSpan;
-import io.opentracing.BaseSpan;
-import io.opentracing.Span;
-import io.opentracing.SpanContext;
-import io.opentracing.Tracer;
-import io.opentracing.Tracer.SpanBuilder;
-import io.opentracing.contrib.tracerresolver.TracerResolver;
-import io.opentracing.propagation.Format;
-import io.opentracing.util.GlobalTracer;
-import java.net.HttpURLConnection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.jboss.byteman.rule.Rule;
-import org.jboss.byteman.rule.helper.Helper;
-
-/** This class provides helper capabilities to the byteman rules. */
-public class OpenTracingHelper extends Helper {
-
-  private static final Logger log = Logger.getLogger(OpenTracingHelper.class.getName());
-
-  private static Tracer tracer;
-
-  private static final Map<Object, Span> spanAssociations =
-      Collections.synchronizedMap(new WeakHashMap<Object, Span>());
-  private static final Map<Object, Span> finished =
-      Collections.synchronizedMap(new WeakHashMap<Object, Span>());
-
-  private static final Map<Object, Integer> state =
-      Collections.synchronizedMap(new WeakHashMap<Object, Integer>());
-
-  private static final Object SYNC = new Object();
-
-  public OpenTracingHelper(final Rule rule) {
-    super(rule);
-  }
-
-  /**
-   * This method returns the OpenTracing tracer.
-   *
-   * @return The tracer
-   */
-  public Tracer getTracer() {
-    if (tracer == null) {
-      // Initialize on first use
-      initTracer();
-    }
-    return tracer;
-  }
-
-  protected void initTracer() {
-    synchronized (SYNC) {
-      if (tracer == null) {
-        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.log(Level.WARNING, "Failed to register tracer '" + resolved + "'", re);
-            }
-          }
-        }
-        // Initialize the tracer even if one has not been registered
-        // (i.e. it will use a NoopTracer under the covers)
-        tracer = new AgentTracer(GlobalTracer.get());
-      }
-    }
-  }
-
-  /**
-   * This method establishes an association between an application object (i.e. the subject of the
-   * instrumentation) and a span. Once the application object is no longer being used, the
-   * association with the span will automatically be discarded.
-   *
-   * @param obj The application object to be associated with the span
-   * @param span The span
-   */
-  public void associateSpan(final Object obj, final Span span) {
-    spanAssociations.put(obj, span);
-  }
-
-  /**
-   * This method retrieves the span associated with the supplied application object.
-   *
-   * @param obj The application object
-   * @return The span, or null if no associated span exists
-   */
-  public Span retrieveSpan(final Object obj) {
-    return spanAssociations.get(obj);
-  }
-
-  /** ******************************************* */
-  /** Needs to be replaced by span.isFinished() */
-  public void finishedSpan(final Object key, final Span span) {
-    finished.put(key, span);
-  }
-
-  public boolean isFinished(final Object key) {
-    return finished.containsKey(key);
-  }
-  /** ******************************************* */
-
-  /**
-   * This method enables an instrumentation rule to record a 'state' number against an application
-   * object. This can be used in situations where rules are only applicable in certain states. For
-   * example, the simple case for rules responsible for installing filters would be states
-   * representing NOT_INSTALLED and INSTALLED. This means that the filter would only be installed if
-   * the application object (target of the instrumentation rule) was in the NOT_INSTALLED state.
-   * However other more complex scenarios may be encountered where more than two states are
-   * required.
-   *
-   * @param obj The application object
-   * @param value The state value
-   */
-  public void setState(final Object obj, final int value) {
-    state.put(obj, new Integer(value));
-  }
-
-  /**
-   * This method retrieves the current 'state' number associated with the supplied application
-   * object.
-   *
-   * @param obj The application object
-   * @return The state, or 0 if no state currently exists
-   */
-  public int getState(final Object obj) {
-    final Integer value = state.get(obj);
-    return value == null ? 0 : value.intValue();
-  }
-
-  /**
-   * This method determines whether the instrumentation point, associated with the supplied object,
-   * should be ignored.
-   *
-   * @param obj The instrumentation target
-   * @return Whether the instrumentation point should be ignored
-   */
-  public boolean ignore(final Object obj) {
-    boolean ignore = false;
-
-    if (obj instanceof HttpURLConnection) {
-      final String value = ((HttpURLConnection) obj).getRequestProperty("opentracing.ignore");
-      ignore = value != null && value.equalsIgnoreCase("true");
-    }
-
-    // TODO: If other technologies need to use this feature,
-    // then create an Adapter to wrap the specifics of each
-    // technology and provide access to their properties
-
-    if (ignore && log.isLoggable(Level.FINEST)) {
-      log.finest("Ignoring request because the property [opentracing.ignore] is present.");
-    }
-
-    return ignore;
-  }
-
-  /**
-   * Proxy tracer used for one purpose - to enable the rules to define a ChildOf relationship
-   * without being concerned whether the supplied Span is null. If the spec (and Tracer
-   * implementations) are updated to indicate a null should be ignored, then this proxy can be
-   * removed.
-   */
-  public static class AgentTracer implements Tracer {
-
-    private final Tracer tracer;
-
-    public AgentTracer(final Tracer tracer) {
-      this.tracer = tracer;
-    }
-
-    @Override
-    public SpanBuilder buildSpan(final String operation) {
-      return new AgentSpanBuilder(tracer.buildSpan(operation));
-    }
-
-    @Override
-    public <C> SpanContext extract(final Format<C> format, final C carrier) {
-      return tracer.extract(format, carrier);
-    }
-
-    @Override
-    public <C> void inject(final SpanContext ctx, final Format<C> format, final C carrier) {
-      tracer.inject(ctx, format, carrier);
-    }
-
-    @Override
-    public ActiveSpan activeSpan() {
-      return tracer.activeSpan();
-    }
-
-    @Override
-    public ActiveSpan makeActive(final Span span) {
-      return tracer.makeActive(span);
-    }
-  }
-
-  public static class AgentSpanBuilder implements SpanBuilder {
-
-    private final SpanBuilder spanBuilder;
-
-    public AgentSpanBuilder(final SpanBuilder spanBuilder) {
-      this.spanBuilder = spanBuilder;
-    }
-
-    @Override
-    public SpanBuilder addReference(final String type, final SpanContext ctx) {
-      if (ctx != null) {
-        spanBuilder.addReference(type, ctx);
-      }
-      return this;
-    }
-
-    @Override
-    public SpanBuilder asChildOf(final SpanContext ctx) {
-      if (ctx != null) {
-        spanBuilder.asChildOf(ctx);
-      }
-      return this;
-    }
-
-    @Override
-    public SpanBuilder asChildOf(final BaseSpan<?> span) {
-      if (span != null) {
-        spanBuilder.asChildOf(span);
-      }
-      return this;
-    }
-
-    @Override
-    public Span start() {
-      return spanBuilder.start();
-    }
-
-    @Override
-    public SpanBuilder withStartTimestamp(final long ts) {
-      spanBuilder.withStartTimestamp(ts);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final String value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final boolean value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder withTag(final String name, final Number value) {
-      spanBuilder.withTag(name, value);
-      return this;
-    }
-
-    @Override
-    public SpanBuilder ignoreActiveSpan() {
-      spanBuilder.ignoreActiveSpan();
-      return this;
-    }
-
-    @Override
-    public ActiveSpan startActive() {
-      return spanBuilder.startActive();
-    }
-
-    @Override
-    public Span startManual() {
-      return spanBuilder.startManual();
-    }
-  }
-}

+ 7 - 23
dd-java-agent/src/main/java/com/datadoghq/agent/TracingAgent.java

@@ -36,36 +36,21 @@ import net.bytebuddy.description.type.TypeDescription;
 import net.bytebuddy.dynamic.DynamicType;
 import net.bytebuddy.utility.JavaModule;
 
-/**
- * This class provides a wrapper around the ByteMan agent, to establish required system properties
- * and the manager class.
- */
+/** Entry point for initializing the agent. */
 @Slf4j
 public class TracingAgent {
 
-  public static void premain(String agentArgs, final Instrumentation inst) throws Exception {
-    agentArgs = addManager(agentArgs);
+  public static void premain(final String agentArgs, final Instrumentation inst) throws Exception {
     log.debug("Using premain for loading {}", TracingAgent.class.getSimpleName());
-    org.jboss.byteman.agent.Main.premain(agentArgs, inst);
     addByteBuddy(inst);
+    AgentRulesManager.initialize();
   }
 
-  public static void agentmain(String agentArgs, final Instrumentation inst) throws Exception {
-    agentArgs = addManager(agentArgs);
+  public static void agentmain(final String agentArgs, final Instrumentation inst)
+      throws Exception {
     log.debug("Using agentmain for loading {}", TracingAgent.class.getSimpleName());
-    org.jboss.byteman.agent.Main.agentmain(agentArgs, inst);
     addByteBuddy(inst);
-  }
-
-  protected static String addManager(String agentArgs) {
-    if (agentArgs == null || agentArgs.trim().isEmpty()) {
-      agentArgs = "";
-    } else {
-      agentArgs += ",";
-    }
-    agentArgs += "manager:" + AgentRulesManager.class.getName();
-    log.debug("Agent args=: {}", agentArgs);
-    return agentArgs;
+    AgentRulesManager.initialize();
   }
 
   public static void addByteBuddy(final Instrumentation inst) {
@@ -94,8 +79,7 @@ public class TracingAgent {
                     .or(isReflectionClassLoader())
                     .or(
                         classLoaderWithName(
-                            "org.codehaus.groovy.runtime.callsite.CallSiteClassLoader"))
-                    .or(classLoaderWithName("org.jboss.byteman.modules.ClassbyteClassLoader")));
+                            "org.codehaus.groovy.runtime.callsite.CallSiteClassLoader")));
 
     for (final Instrumenter instrumenter : ServiceLoader.load(Instrumenter.class)) {
       agentBuilder = instrumenter.instrument(agentBuilder);

+ 0 - 4
dd-trace-examples/async-tracing/README.md

@@ -5,9 +5,6 @@ The OpenTracing Java Agent contribution is designed to inject code directly to t
 It provides to developers a way to instrument their code, without modifying it.
 The Java Agent is a compiled Jar and it is added to the JVM using the `-javaagent` option.
 
-This contribution uses the [Byteman project](http://byteman.jboss.org/). The contribution provides 
-a set of rules for instrumenting the code through a collection of `otarules.btm` files
-
 The contrib is basically able to serve 2 goals:
 - Instrumenting custom or legacy code without modifying it (extremely verbose and painful)
 - Inject the others OpenTracing contribution in your app (Spring Boot, JDBC wrapper, Jax-Rs, etc. )
@@ -76,7 +73,6 @@ If you want to instrument custom code, without using a contribution, you need 2
 
 In this project, we show you an instrumentation. We inject some code via A rule file. 
 The BTM rule files describes when/where/how modify the legacy code.
-If you want to dig deeper, you have to refer to the [official documentation](http://byteman.jboss.org/docs.html)
 
 For instance, here is how to create a new span when the `method1` is called somewhere.
 Check the full class [code](src/main/java/org/javaagent/App.java).