Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions dd-java-agent/agent-otel/otel-bootstrap/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ plugins {
id "com.github.johnrengelman.shadow"
}

def otelApiVersion = '1.38.0'
def otelInstrumentationApiVersion = '2.4.0'

apply from: "$rootDir/gradle/java.gradle"
apply plugin: 'instrument'

Expand All @@ -25,6 +28,7 @@ minimumInstructionCoverage = 0.0
minimumBranchCoverage = 0.0

forbiddenApis {
failOnMissingClasses = false
ignoreFailures = true
}
spotbugs {
Expand All @@ -33,8 +37,14 @@ spotbugs {

dependencies {
// latest OpenTelemetry API for drop-in support; instrumented at build-time with our shim
embeddedClasspath group: 'io.opentelemetry', name: 'opentelemetry-api', version: '1.38.0'
embeddedClasspath group: 'io.opentelemetry', name: 'opentelemetry-api', version: otelApiVersion
embeddedClasspath group: 'io.opentelemetry.instrumentation', name: 'opentelemetry-instrumentation-api', version: otelInstrumentationApiVersion
embeddedClasspath group: 'io.opentelemetry.javaagent', name: 'opentelemetry-javaagent-extension-api', version: "$otelInstrumentationApiVersion-alpha"

// selected bootstrap types shared across multiple OpenTelemetry instrumentations
embeddedClasspath group: 'io.opentelemetry.javaagent.instrumentation', name: 'opentelemetry-javaagent-servlet-common-bootstrap', version: "$otelInstrumentationApiVersion-alpha"

compileOnly project(':dd-java-agent:agent-bootstrap')
implementation project(':dd-java-agent:agent-otel:otel-shim')

instrumentPluginClasspath project(path: ':dd-java-agent:agent-otel:otel-tooling', configuration: 'instrumentPluginClasspath')
Expand All @@ -44,6 +54,8 @@ dependencies {
tasks.register('unpackJars', Copy) {
dependsOn configurations.embeddedClasspath
exclude 'META-INF/'
exclude '**/module-info.class'
exclude '**/package-info.class'
from {
configurations.embeddedClasspath.collect { zipTree(it) }
}
Expand All @@ -56,9 +68,33 @@ tasks.named('compileJava') {
shadowJar {
dependencies deps.excludeShared

include '*.jar'
include 'io/opentelemetry/api/**'
exclude 'io/opentelemetry/api/incubator/**'
include 'io/opentelemetry/context/**'
exclude 'io/opentelemetry/context/internal/shaded/**'
include 'io/opentelemetry/semconv/**'
include 'io/opentelemetry/instrumentation/api/**'
exclude 'io/opentelemetry/instrumentation/api/incubator/**'
exclude 'io/opentelemetry/instrumentation/api/internal/cache/**'
exclude 'io/opentelemetry/instrumentation/api/internal/RuntimeVirtualFieldSupplier*'
exclude 'io/opentelemetry/instrumentation/api/util/VirtualField*'
include 'io/opentelemetry/javaagent/bootstrap/**'
exclude 'io/opentelemetry/javaagent/bootstrap/CallDepth*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/ClassLoaderMatcherCacheHolder*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/ConfiguredResourceAttributesHolder*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/DeprecatedConfigProperties*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/InClassLoaderMatcher*'
exclude 'io/opentelemetry/javaagent/bootstrap/internal/InstrumentationConfig*'
include 'datadog/opentelemetry/shim/**'
include 'datadog/trace/bootstrap/otel/**'

relocate 'io.opentelemetry', 'datadog.trace.bootstrap.otel'
relocate 'io.opentelemetry.api', 'datadog.trace.bootstrap.otel.api'
relocate 'io.opentelemetry.context', 'datadog.trace.bootstrap.otel.context'
relocate 'io.opentelemetry.semconv', 'datadog.trace.bootstrap.otel.semconv'
relocate 'io.opentelemetry.instrumentation.api', 'datadog.trace.bootstrap.otel.instrumentation.api'
relocate 'io.opentelemetry.javaagent.bootstrap', 'datadog.trace.bootstrap.otel.instrumentation'
relocate 'datadog.opentelemetry.shim', 'datadog.trace.bootstrap.otel.shim'
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package datadog.trace.bootstrap.otel.instrumentation;

import datadog.trace.bootstrap.CallDepthThreadLocalMap;

/** Redirects requests to our own {@link CallDepthThreadLocalMap}. */
public final class CallDepth {
private final Class<?> clazz;

private CallDepth(final Class<?> clazz) {
this.clazz = clazz;
}

public static CallDepth forClass(Class<?> clazz) {
return new CallDepth(clazz);
}

public int getAndIncrement() {
return CallDepthThreadLocalMap.incrementCallDepth(clazz);
}

public int decrementAndGet() {
return CallDepthThreadLocalMap.decrementCallDepth(clazz);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package datadog.trace.bootstrap.otel.instrumentation.internal;

import datadog.trace.bootstrap.config.provider.ConfigProvider;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** Redirects requests to our own {@link ConfigProvider}. */
public final class InstrumentationConfig {
private static final InstrumentationConfig INSTANCE = new InstrumentationConfig();

private static final Pattern DURATION_PATTERN = Pattern.compile("(\\d+)(ms|[DdHhMmSs]?)");

private static final ConfigProvider delegate = ConfigProvider.getInstance();

public static InstrumentationConfig get() {
return INSTANCE;
}

public String getString(String name) {
return delegate.getString(name);
}

public String getString(String name, String defaultValue) {
return delegate.getString(name, defaultValue);
}

public boolean getBoolean(String name, boolean defaultValue) {
return delegate.getBoolean(name, defaultValue);
}

public int getInt(String name, int defaultValue) {
return delegate.getInteger(name, defaultValue);
}

public long getLong(String name, long defaultValue) {
return delegate.getLong(name, defaultValue);
}

public double getDouble(String name, double defaultValue) {
return delegate.getDouble(name, defaultValue);
}

public Duration getDuration(String name, Duration defaultValue) {
String durationString = delegate.getString(name);
if (null == durationString) {
return defaultValue;
}
Matcher matcher = DURATION_PATTERN.matcher(durationString);
if (matcher.matches()) {
long value = Integer.parseInt(matcher.group(1));
String unit = matcher.group(2);
if ("D".equalsIgnoreCase(unit)) {
return Duration.ofDays(value);
} else if ("H".equalsIgnoreCase(unit)) {
return Duration.ofHours(value);
} else if ("M".equalsIgnoreCase(unit)) {
return Duration.ofMinutes(value);
} else if ("S".equalsIgnoreCase(unit)) {
return Duration.ofSeconds(value);
} else {
return Duration.ofMillis(value); // already in ms
}
} else {
throw new IllegalArgumentException(
"Invalid duration property " + name + "=" + durationString);
}
}

public List<String> getList(String name) {
return getList(name, Collections.emptyList());
}

public List<String> getList(String name, List<String> defaultValue) {
return delegate.getList(name, defaultValue);
}

public Set<String> getSet(String name, Set<String> defaultValue) {
return delegate.getSet(name, defaultValue);
}

public Map<String, String> getMap(String name, Map<String, String> defaultValue) {
Map<String, String> map = delegate.getMergedMap(name);
if (map.isEmpty()) {
map = defaultValue;
}
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ private String[] removeUnsupportedTypes(String[] interfaces) {
static final class Renamer extends Remapper {
static final Renamer INSTANCE = new Renamer();

private static final String OTEL_JAVAAGENT_SHADED_PREFIX =
"io/opentelemetry/javaagent/shaded/io/opentelemetry/";

private static final String ASM_PREFIX = "org/objectweb/asm/";

/** Datadog equivalent of OpenTelemetry instrumentation classes. */
private static final Map<String, String> RENAMED_TYPES = new HashMap<>();

Expand Down Expand Up @@ -111,9 +106,25 @@ static final class Renamer extends Remapper {
RENAMED_TYPES.put(
"io/opentelemetry/javaagent/tooling/muzzle/references/Source",
Type.getInternalName(OtelMuzzleRefBuilder.Source.class));
RENAMED_TYPES.put(
"io/opentelemetry/javaagent/bootstrap/Java8BytecodeBridge",
"datadog/trace/bootstrap/otel/Java8BytecodeBridge");
}

/** OpenTelemetry and related packages shaded inside the tracer. */
private static final Map<String, String> RENAMED_PACKAGES = new HashMap<>();

static {
RENAMED_PACKAGES.put(
"io/opentelemetry/javaagent/shaded/io/opentelemetry/", "datadog/trace/bootstrap/otel/");

RENAMED_PACKAGES.put("io/opentelemetry/api/", "datadog/trace/bootstrap/otel/api/");
RENAMED_PACKAGES.put("io/opentelemetry/context/", "datadog/trace/bootstrap/otel/context/");
RENAMED_PACKAGES.put("io/opentelemetry/semconv/", "datadog/trace/bootstrap/otel/semconv/");

RENAMED_PACKAGES.put(
"io/opentelemetry/instrumentation/", "datadog/trace/bootstrap/otel/instrumentation/");
RENAMED_PACKAGES.put(
"io/opentelemetry/javaagent/bootstrap/", "datadog/trace/bootstrap/otel/instrumentation/");

RENAMED_PACKAGES.put("org/objectweb/asm/", "net/bytebuddy/jar/asm/");
}

@Override
Expand All @@ -122,14 +133,10 @@ public String map(String internalName) {
if (null != rename) {
return rename;
}
// map OpenTelemetry's shaded API to our embedded copy
if (internalName.startsWith(OTEL_JAVAAGENT_SHADED_PREFIX)) {
return "datadog/trace/bootstrap/otel/"
+ internalName.substring(OTEL_JAVAAGENT_SHADED_PREFIX.length());
}
// map unshaded ASM types to the shaded copy in byte-buddy
if (internalName.startsWith(ASM_PREFIX)) {
return "net/bytebuddy/jar/asm/" + internalName.substring(ASM_PREFIX.length());
for (Map.Entry<String, String> mapping : RENAMED_PACKAGES.entrySet()) {
if (internalName.startsWith(mapping.getKey())) {
return mapping.getValue() + internalName.substring(mapping.getKey().length());
}
}
return MAP_LOGGING.apply(internalName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
final class OtelEnvironmentConfigSource extends ConfigProvider.Source {
private static final Logger log = LoggerFactory.getLogger(OtelEnvironmentConfigSource.class);

private final boolean enabled;

private final Map<String, String> otelEnvironment = new HashMap<>();

private final Properties otelConfigFile = loadOtelConfigFile();
Expand All @@ -44,7 +46,15 @@ final class OtelEnvironmentConfigSource extends ConfigProvider.Source {

@Override
protected String get(String key) {
return otelEnvironment.get(key);
if (!enabled) {
return null;
}

String value = otelEnvironment.get(key);
if (null == value && key.startsWith("otel.")) {
value = getOtelProperty(key);
}
return value;
}

@Override
Expand All @@ -57,9 +67,10 @@ public ConfigOrigin origin() {
}

OtelEnvironmentConfigSource(Properties datadogConfigFile) {
this.enabled = traceOtelEnabled();
this.datadogConfigFile = datadogConfigFile;

if (traceOtelEnabled()) {
if (enabled) {
setupOteEnvironment();
}
}
Expand Down