Merge tag 'v0.46.0' into dd-merge

This commit is contained in:
Trask Stalnaker 2020-03-13 17:28:58 -07:00
commit 2298885678
358 changed files with 2645 additions and 2328 deletions

View File

@ -14,4 +14,6 @@ dependencies {
compile deps.slf4j
compile group: 'org.slf4j', name: 'slf4j-simple', version: versions.slf4j
// ^ Generally a bad idea for libraries, but we're shadowing.
testCompile project(':testing')
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.auto.instrumentation.api.Tags;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.trace.Span;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.config.Config;
import io.opentelemetry.auto.instrumentation.api.MoreTags;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.config.Config;
import io.opentelemetry.auto.instrumentation.api.MoreTags;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.config.Config;
import io.opentelemetry.auto.instrumentation.api.MoreTags;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.trace.Span;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.opentelemetry.trace.Span;

View File

@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.java.concurrent;
package io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent.State;
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;

View File

@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.java.concurrent;
package io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent;
import static io.opentelemetry.auto.instrumentation.java.concurrent.AdviceUtils.TRACER;
import static io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent.AdviceUtils.TRACER;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.WeakMap;
import io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent.CallableWrapper;
import io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent.RunnableWrapper;
import io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent.State;
import io.opentelemetry.trace.Span;
import java.util.concurrent.Executor;
import lombok.extern.slf4j.Slf4j;

View File

@ -13,17 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.playws1;
package io.opentelemetry.auto.bootstrap.instrumentation.java.concurrent;
import io.opentelemetry.context.propagation.HttpTextFormat;
import play.shaded.ahc.org.asynchttpclient.Request;
public class HeadersInjectAdapter implements HttpTextFormat.Setter<Request> {
public static final HeadersInjectAdapter SETTER = new HeadersInjectAdapter();
/** Used by ThreadPoolExecutorInstrumentation to check executor support */
public class GenericRunnable implements Runnable {
@Override
public void put(final Request carrier, final String key, final String value) {
carrier.getHeaders().add(key, value);
}
public void run() {}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.jdbc;
package io.opentelemetry.auto.bootstrap.instrumentation.jdbc;
import lombok.Builder;
import lombok.Data;

View File

@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.jdbc;
package io.opentelemetry.auto.bootstrap.instrumentation.jdbc;
import static io.opentelemetry.auto.instrumentation.jdbc.DBInfo.DEFAULT;
import static io.opentelemetry.auto.bootstrap.instrumentation.jdbc.DBInfo.DEFAULT;
import io.opentelemetry.auto.bootstrap.ExceptionLogger;
import java.io.UnsupportedEncodingException;

View File

@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import lombok.Getter;
import lombok.ToString;
@ -68,6 +69,8 @@ public class Config {
public static final String HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN = "trace.http.client.split-by-domain";
public static final String DB_CLIENT_HOST_SPLIT_BY_INSTANCE = "trace.db.client.split-by-instance";
public static final String SCOPE_DEPTH_LIMIT = "trace.scope.depth.limit";
public static final String SPAN_DURATION_ABOVE_AVERAGE_STACKTRACE_MILLIS =
"trace.span.duration-above-average.stacktrace.millis";
public static final String RUNTIME_CONTEXT_FIELD_INJECTION =
"trace.runtime.context.field.injection";
@ -89,6 +92,8 @@ public class Config {
private static final boolean DEFAULT_HTTP_CLIENT_SPLIT_BY_DOMAIN = false;
private static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE = false;
private static final int DEFAULT_SCOPE_DEPTH_LIMIT = 100;
private static final int DEFAULT_SPAN_DURATION_ABOVE_AVERAGE_STACKTRACE_MILLIS =
(int) TimeUnit.SECONDS.toMillis(1);
public static final boolean DEFAULT_LOG_INJECTION_ENABLED = false;
public static final String DEFAULT_EXPERIMENTAL_LOG_CAPTURE_THRESHOLD = null;
@ -112,6 +117,7 @@ public class Config {
@Getter private final boolean httpClientSplitByDomain;
@Getter private final boolean dbClientSplitByInstance;
@Getter private final Integer scopeDepthLimit;
@Getter private final long spanDurationAboveAverageStacktraceNanos;
@Getter private final boolean runtimeContextFieldInjection;
@Getter private final boolean logInjectionEnabled;
@ -182,6 +188,13 @@ public class Config {
scopeDepthLimit =
getIntegerSettingFromEnvironment(SCOPE_DEPTH_LIMIT, DEFAULT_SCOPE_DEPTH_LIMIT);
spanDurationAboveAverageStacktraceNanos =
TimeUnit.MILLISECONDS.toNanos(
getIntegerSettingFromEnvironment(
SPAN_DURATION_ABOVE_AVERAGE_STACKTRACE_MILLIS,
DEFAULT_SPAN_DURATION_ABOVE_AVERAGE_STACKTRACE_MILLIS)
.longValue());
runtimeContextFieldInjection =
getBooleanSettingFromEnvironment(
RUNTIME_CONTEXT_FIELD_INJECTION, DEFAULT_RUNTIME_CONTEXT_FIELD_INJECTION);
@ -244,6 +257,15 @@ public class Config {
scopeDepthLimit =
getPropertyIntegerValue(properties, SCOPE_DEPTH_LIMIT, parent.scopeDepthLimit);
// do we care about the integer downcast here?
spanDurationAboveAverageStacktraceNanos =
TimeUnit.MILLISECONDS.toNanos(
getPropertyIntegerValue(
properties,
SPAN_DURATION_ABOVE_AVERAGE_STACKTRACE_MILLIS,
(int)
TimeUnit.NANOSECONDS.toMillis(parent.spanDurationAboveAverageStacktraceNanos)));
runtimeContextFieldInjection =
getPropertyBooleanValue(
properties, RUNTIME_CONTEXT_FIELD_INJECTION, parent.runtimeContextFieldInjection);

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -13,11 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.config.Config
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.Tags
/*
* Copyright 2020, OpenTelemetry Authors
*
* 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.
*/
import io.opentelemetry.trace.Span
import static io.opentelemetry.auto.test.utils.ConfigUtils.withConfigOverride

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.config.Config
import io.opentelemetry.auto.instrumentation.api.MoreTags

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.config.Config
import io.opentelemetry.auto.instrumentation.api.MoreTags

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.trace.Span

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator;
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
/**
* Used by {@link BaseDecoratorTest}. Groovy with Java 10+ doesn't seem to treat it properly as an

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.decorator
package io.opentelemetry.auto.bootstrap.instrumentation.decorator
import io.opentelemetry.auto.instrumentation.api.MoreTags

View File

@ -15,10 +15,10 @@
*/
package io.opentelemetry.auto.config
import io.opentelemetry.auto.util.test.AgentSpecification
import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables
import org.junit.contrib.java.lang.system.RestoreSystemProperties
import spock.lang.Specification
import static io.opentelemetry.auto.config.Config.CONFIGURATION_FILE
import static io.opentelemetry.auto.config.Config.DB_CLIENT_HOST_SPLIT_BY_INSTANCE
@ -30,7 +30,7 @@ import static io.opentelemetry.auto.config.Config.RUNTIME_CONTEXT_FIELD_INJECTIO
import static io.opentelemetry.auto.config.Config.TRACE_ENABLED
import static io.opentelemetry.auto.config.Config.TRACE_METHODS
class ConfigTest extends Specification {
class ConfigTest extends AgentSpecification {
@Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
@Rule

View File

@ -16,13 +16,11 @@
package io.opentelemetry.auto.tooling;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.skipClassLoader;
import static io.opentelemetry.auto.tooling.matcher.AdditionalLibraryIgnoresMatcher.additionalLibraryIgnoresMatcher;
import static io.opentelemetry.auto.tooling.matcher.GlobalIgnoresMatcher.globalIgnoresMatcher;
import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.none;
import static net.bytebuddy.matcher.ElementMatchers.not;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.config.Config;
@ -106,18 +104,10 @@ public class AgentInstaller {
// https://github.com/raphw/byte-buddy/issues/558
// .with(AgentBuilder.LambdaInstrumentationStrategy.ENABLED)
.ignore(any(), skipClassLoader());
if (skipAdditionalLibraryMatcher) {
// Ignore classes matched by globalIgnoresMatcher but not matched by
// additionalLibraryIgnoresMatcher.
// Note: globalIgnoresMatcher includes additionalLibraryIgnoresMatcher internally for
// efficiency purposes.
// Note2: this is expected to be used by tests only.
ignoredAgentBuilder =
ignoredAgentBuilder.or(
globalIgnoresMatcher().and(not(additionalLibraryIgnoresMatcher())));
} else {
ignoredAgentBuilder = ignoredAgentBuilder.or(globalIgnoresMatcher());
}
ignoredAgentBuilder =
ignoredAgentBuilder.or(globalIgnoresMatcher(skipAdditionalLibraryMatcher));
ignoredAgentBuilder = ignoredAgentBuilder.or(matchesConfiguredExcludes());
AgentBuilder agentBuilder = ignoredAgentBuilder;

View File

@ -17,12 +17,14 @@ package io.opentelemetry.auto.tooling;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.opentelemetry.auto.bootstrap.PatchLogger;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.matcher.ElementMatcher;
@Slf4j
public final class ClassLoaderMatcher {
public static final ClassLoader BOOTSTRAP_CLASSLOADER = null;
public static final int CACHE_MAX_SIZE = 25; // limit number of cached responses for each matcher.
public static final int CACHE_CONCURRENCY =
Math.max(8, Runtime.getRuntime().availableProcessors());
@ -35,14 +37,24 @@ public final class ClassLoaderMatcher {
return SkipClassLoaderMatcher.INSTANCE;
}
public static ElementMatcher.Junction.AbstractBase<ClassLoader> classLoaderHasNoResources(
final String... resources) {
return new ClassLoaderHasNoResourceMatcher(resources);
/**
* NOTICE: Does not match the bootstrap classpath. Don't use with classes expected to be on the
* bootstrap.
*
* @param classNames list of names to match. returns true if empty.
* @return true if class is available as a resource and not the bootstrap classloader.
*/
public static ElementMatcher.Junction.AbstractBase<ClassLoader> hasClassesNamed(
final String... classNames) {
return new ClassLoaderHasClassesNamedMatcher(classNames);
}
private static class SkipClassLoaderMatcher
extends ElementMatcher.Junction.AbstractBase<ClassLoader> {
public static final SkipClassLoaderMatcher INSTANCE = new SkipClassLoaderMatcher();
/* Cache of classloader-instance -> (true|false). True = skip instrumentation. False = safe to instrument. */
private static final Cache<ClassLoader, Boolean> skipCache =
CacheBuilder.newBuilder().weakKeys().concurrencyLevel(CACHE_CONCURRENCY).build();
private static final String AGENT_CLASSLOADER_NAME =
"io.opentelemetry.auto.bootstrap.AgentClassLoader";
@ -54,7 +66,21 @@ public final class ClassLoaderMatcher {
// Don't skip bootstrap loader
return false;
}
return shouldSkipClass(cl);
Boolean v = skipCache.getIfPresent(cl);
if (v != null) {
return v;
}
// when ClassloadingInstrumentation is active, checking delegatesToBootstrap() below is not
// required, because ClassloadingInstrumentation forces all class loaders to load all of the
// classes in Constants.BOOTSTRAP_PACKAGE_PREFIXES directly from the bootstrap class loader
//
// however, at this time we don't want to introduce the concept of a required instrumentation,
// and we don't want to introduce the concept of the tooling code depending on whether or not
// a particular instrumentation is active (mainly because this particular use case doesn't
// seem to justify introducing either of these new concepts)
v = shouldSkipClass(cl) || !delegatesToBootstrap(cl);
skipCache.put(cl, v);
return v;
}
private static boolean shouldSkipClass(final ClassLoader loader) {
@ -70,40 +96,73 @@ public final class ClassLoaderMatcher {
}
return false;
}
/**
* TODO: this turns out to be useless with OSGi: {@code
* org.eclipse.osgi.internal.loader.BundleLoader#isRequestFromVM} returns {@code true} when
* class loading is issued from this check and {@code false} for 'real' class loads. We should
* come up with some sort of hack to avoid this problem.
*/
private static boolean delegatesToBootstrap(final ClassLoader loader) {
boolean delegates = true;
if (!loadsExpectedClass(loader, PatchLogger.class)) {
log.debug("loader {} failed to delegate bootstrap agent class", loader);
delegates = false;
}
return delegates;
}
private static boolean loadsExpectedClass(
final ClassLoader loader, final Class<?> expectedClass) {
try {
return loader.loadClass(expectedClass.getName()) == expectedClass;
} catch (final ClassNotFoundException e) {
return false;
}
}
}
private static class ClassLoaderHasNoResourceMatcher
private static class ClassLoaderHasClassesNamedMatcher
extends ElementMatcher.Junction.AbstractBase<ClassLoader> {
private final Cache<ClassLoader, Boolean> cache =
CacheBuilder.newBuilder().weakKeys().concurrencyLevel(CACHE_CONCURRENCY).build();
CacheBuilder.newBuilder()
.weakKeys()
.maximumSize(CACHE_MAX_SIZE)
.concurrencyLevel(CACHE_CONCURRENCY)
.build();
private final String[] resources;
private ClassLoaderHasNoResourceMatcher(final String... resources) {
this.resources = resources;
private ClassLoaderHasClassesNamedMatcher(final String... classNames) {
resources = classNames;
for (int i = 0; i < resources.length; i++) {
resources[i] = resources[i].replace(".", "/") + ".class";
}
}
private boolean hasNoResources(final ClassLoader cl) {
private boolean hasResources(final ClassLoader cl) {
for (final String resource : resources) {
if (cl.getResource(resource) == null) {
return true;
return false;
}
}
return false;
return true;
}
@Override
public boolean matches(final ClassLoader cl) {
if (cl == null) {
if (cl == BOOTSTRAP_CLASSLOADER) {
// Can't match the bootstrap classloader.
return false;
}
Boolean v = cache.getIfPresent(cl);
if (v != null) {
return v;
final Boolean cached;
if ((cached = cache.getIfPresent(cl)) != null) {
return cached;
}
v = hasNoResources(cl);
cache.put(cl, v);
return v;
final boolean value = hasResources(cl);
cache.put(cl, value);
return value;
}
}
}

View File

@ -22,6 +22,7 @@ import io.opentelemetry.auto.bootstrap.WeakMap;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.file.Files;
import java.security.SecureClassLoader;
import java.util.Arrays;
import java.util.Collection;
@ -46,7 +47,14 @@ import net.bytebuddy.utility.JavaModule;
public class HelperInjector implements Transformer {
// Need this because we can't put null into the injectedClassLoaders map.
private static final ClassLoader BOOTSTRAP_CLASSLOADER_PLACEHOLDER =
new SecureClassLoader(null) {};
new SecureClassLoader(null) {
@Override
public String toString() {
return "<bootstrap>";
}
};
private final String requestingName;
private final Set<String> helperClassNames;
private final Map<String, byte[]> dynamicTypeMap = new LinkedHashMap<>();
@ -63,21 +71,26 @@ public class HelperInjector implements Transformer {
* order provided. This is important if there is interdependency between helper classes that
* requires them to be injected in a specific order.
*/
public HelperInjector(final String... helperClassNames) {
public HelperInjector(final String requestingName, final String... helperClassNames) {
this.requestingName = requestingName;
this.helperClassNames = new LinkedHashSet<>(Arrays.asList(helperClassNames));
}
public HelperInjector(final Map<String, byte[]> helperMap) {
public HelperInjector(final String requestingName, final Map<String, byte[]> helperMap) {
this.requestingName = requestingName;
helperClassNames = helperMap.keySet();
dynamicTypeMap.putAll(helperMap);
}
public static HelperInjector forDynamicTypes(final Collection<DynamicType.Unloaded<?>> helpers) {
public static HelperInjector forDynamicTypes(
final String requestingName, final Collection<DynamicType.Unloaded<?>> helpers) {
final Map<String, byte[]> bytes = new HashMap<>(helpers.size());
for (final DynamicType.Unloaded<?> helper : helpers) {
bytes.put(helper.getTypeDescription().getName(), helper.getBytes());
}
return new HelperInjector(bytes);
return new HelperInjector(requestingName, bytes);
}
private Map<String, byte[]> getHelperMap() throws IOException {
@ -116,14 +129,9 @@ public class HelperInjector implements Transformer {
final Map<String, byte[]> classnameToBytes = getHelperMap();
final Map<String, Class<?>> classes;
if (classLoader == BOOTSTRAP_CLASSLOADER_PLACEHOLDER) {
classes =
ClassInjector.UsingInstrumentation.of(
new File(System.getProperty("java.io.tmpdir")),
ClassInjector.UsingInstrumentation.Target.BOOTSTRAP,
AgentInstaller.getInstrumentation())
.injectRaw(classnameToBytes);
classes = injectBootstrapClassLoader(classnameToBytes);
} else {
classes = new ClassInjector.UsingReflection(classLoader).injectRaw(classnameToBytes);
classes = injectClassLoader(classLoader, classnameToBytes);
}
// All agent helper classes are in the unnamed module
@ -134,16 +142,11 @@ public class HelperInjector implements Transformer {
helperModules.add(new WeakReference<>(javaModule.unwrap()));
}
} catch (final Exception e) {
final String classLoaderType =
classLoader == BOOTSTRAP_CLASSLOADER_PLACEHOLDER
? "<bootstrap>"
: classLoader.getClass().getName();
log.error(
"Error preparing helpers for {}. Failed to inject helper classes into instance {} of type {}",
"Error preparing helpers while processing {} for {}. Failed to inject helper classes into instance {}",
typeDescription,
requestingName,
classLoader,
classLoaderType,
e);
throw new RuntimeException(e);
}
@ -156,6 +159,31 @@ public class HelperInjector implements Transformer {
return builder;
}
private Map<String, Class<?>> injectBootstrapClassLoader(
final Map<String, byte[]> classnameToBytes) throws IOException {
// Mar 2020: Since we're proactively cleaning up tempDirs, we cannot share dirs per thread.
// If this proves expensive, we could do a per-process tempDir with
// a reference count -- but for now, starting simple.
// Failures to create a tempDir are propagated as IOException and handled by transform
File tempDir = createTempDir();
try {
return ClassInjector.UsingInstrumentation.of(
tempDir,
ClassInjector.UsingInstrumentation.Target.BOOTSTRAP,
AgentInstaller.getInstrumentation())
.injectRaw(classnameToBytes);
} finally {
// Delete fails silently
deleteTempDir(tempDir);
}
}
private Map<String, Class<?>> injectClassLoader(
final ClassLoader classLoader, final Map<String, byte[]> classnameToBytes) {
return new ClassInjector.UsingReflection(classLoader).injectRaw(classnameToBytes);
}
private void ensureModuleCanReadHelperModules(final JavaModule target) {
if (JavaModule.isSupported() && target != JavaModule.UNSUPPORTED && target.isNamed()) {
for (final WeakReference<Object> helperModuleReference : helperModules) {
@ -177,4 +205,18 @@ public class HelperInjector implements Transformer {
}
}
}
private static final File createTempDir() throws IOException {
return Files.createTempDirectory("datadog-temp-jars").toFile();
}
private static final void deleteTempDir(final File file) {
// Not using Files.delete for deleting the directory because failures
// create Exceptions which may prove expensive. Instead using the
// older File API which simply returns a boolean.
boolean deleted = file.delete();
if (!deleted) {
file.deleteOnExit();
}
}
}

View File

@ -120,7 +120,9 @@ public interface Instrumenter {
AgentBuilder.Identified.Extendable agentBuilder) {
final String[] helperClassNames = helperClassNames();
if (helperClassNames.length > 0) {
agentBuilder = agentBuilder.transform(new HelperInjector(helperClassNames));
agentBuilder =
agentBuilder.transform(
new HelperInjector(this.getClass().getSimpleName(), helperClassNames));
}
return agentBuilder;
}

View File

@ -337,8 +337,10 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
/** Get transformer that forces helper injection onto bootstrap classloader. */
private AgentBuilder.Transformer bootstrapHelperInjector(
final Collection<DynamicType.Unloaded<?>> helpers) {
// TODO: Better to pass through the context of the Instrumenter
return new AgentBuilder.Transformer() {
final HelperInjector injector = HelperInjector.forDynamicTypes(helpers);
final HelperInjector injector =
HelperInjector.forDynamicTypes(this.getClass().getSimpleName(), helpers);
@Override
public DynamicType.Builder<?> transform(

View File

@ -43,35 +43,28 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
final String name = target.getActualName();
if (name.startsWith("com.beust.jcommander.")
|| name.startsWith("com.carrotsearch.hppc.")
|| name.startsWith("com.couchbase.client.deps.")
|| name.startsWith("com.fasterxml.classmate.")
|| name.startsWith("com.fasterxml.jackson.")
|| name.startsWith("com.github.mustachejava.")
|| name.startsWith("com.jayway.jsonpath.")
|| name.startsWith("com.lightbend.lagom")
|| name.startsWith("com.lightbend.lagom.")
|| name.startsWith("javax.el.")
|| name.startsWith("net.sf.cglib.")
|| name.startsWith("org.apache.lucene")
|| name.startsWith("org.apache.tartarus")
|| name.startsWith("org.json.simple")
|| name.startsWith("org.objectweb.asm.")
|| name.startsWith("org.yaml.snakeyaml")) {
|| name.startsWith("org.apache.lucene.")
|| name.startsWith("org.apache.tartarus.")
|| name.startsWith("org.json.simple.")
|| name.startsWith("org.yaml.snakeyaml.")) {
return true;
}
if (name.startsWith("org.springframework.")) {
if (name.startsWith("org.springframework.aop.")
|| name.startsWith("org.springframework.asm.")
|| name.startsWith("org.springframework.cache.")
|| name.startsWith("org.springframework.dao.")
|| name.startsWith("org.springframework.ejb.")
|| name.startsWith("org.springframework.expression.")
|| name.startsWith("org.springframework.format.")
|| name.startsWith("org.springframework.instrument.")
|| name.startsWith("org.springframework.jca.")
|| name.startsWith("org.springframework.jdbc.")
|| name.startsWith("org.springframework.jms.")
|| name.startsWith("org.springframework.jmx.")
|| name.startsWith("org.springframework.jndi.")
|| name.startsWith("org.springframework.lang.")
@ -79,19 +72,20 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
|| name.startsWith("org.springframework.objenesis.")
|| name.startsWith("org.springframework.orm.")
|| name.startsWith("org.springframework.remoting.")
|| name.startsWith("org.springframework.scheduling.annotation")
|| name.startsWith("org.springframework.scripting.")
|| name.startsWith("org.springframework.stereotype.")
|| name.startsWith("org.springframework.transaction.")
|| name.startsWith("org.springframework.ui.")
|| name.startsWith("org.springframework.util.")
|| name.startsWith("org.springframework.validation.")) {
return true;
}
if (name.startsWith("org.springframework.data.")) {
if (name.equals(
"org.springframework.data.repository.core.support.RepositoryFactorySupport")) {
if (name.equals("org.springframework.data.repository.core.support.RepositoryFactorySupport")
|| name.startsWith(
"org.springframework.data.convert.ClassGeneratingEntityInstantiator$")
|| name.equals(
"org.springframework.data.jpa.repository.config.InspectionClassLoader")) {
return false;
}
return true;
@ -116,7 +110,12 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
if (name.startsWith("org.springframework.boot.")) {
// More runnables to deal with
if (name.startsWith("org.springframework.boot.autoconfigure.BackgroundPreinitializer$")
|| name.startsWith("org.springframework.boot.web.embedded.netty.NettyWebServer$")) {
|| name.startsWith("org.springframework.boot.autoconfigure.condition.OnClassCondition$")
|| name.startsWith("org.springframework.boot.web.embedded.netty.NettyWebServer$")
|| name.startsWith(
"org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer$")
|| name.equals(
"org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader")) {
return false;
}
return true;
@ -134,14 +133,25 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
if (name.startsWith("org.springframework.context.")) {
// More runnables to deal with
if (name.startsWith("org.springframework.context.support.AbstractApplicationContext$")) {
if (name.startsWith("org.springframework.context.support.AbstractApplicationContext$")
|| name.equals("org.springframework.context.support.ContextTypeMatchClassLoader")) {
return false;
}
return true;
}
if (name.startsWith("org.springframework.core.")) {
if (name.startsWith("org.springframework.core.task.")) {
if (name.startsWith("org.springframework.core.task.")
|| name.equals("org.springframework.core.DecoratingClassLoader")
|| name.equals("org.springframework.core.OverridingClassLoader")) {
return false;
}
return true;
}
if (name.startsWith("org.springframework.instrument.")) {
if (name.equals("org.springframework.instrument.classloading.SimpleThrowawayClassLoader")
|| name.equals("org.springframework.instrument.classloading.ShadowingClassLoader")) {
return false;
}
return true;
@ -155,9 +165,24 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
return true;
}
if (name.startsWith("org.springframework.jms.")) {
if (name.startsWith("org.springframework.jms.listener.")) {
return false;
}
return true;
}
if (name.startsWith("org.springframework.util.")) {
if (name.startsWith("org.springframework.util.concurrent.")) {
return false;
}
return true;
}
if (name.startsWith("org.springframework.web.")) {
if (name.startsWith("org.springframework.web.servlet.")
|| name.startsWith("org.springframework.web.reactive.")) {
|| name.startsWith("org.springframework.web.reactive.")
|| name.startsWith("org.springframework.web.context.request.async.")) {
return false;
}
return true;
@ -199,8 +224,12 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
return true;
}
if (name.startsWith("com.datastax.driver.")) {
if (name.startsWith("com.datastax.driver.core.Cluster$")) {
if (name.startsWith("com.couchbase.client.deps.")) {
// Couchbase library includes some packaged dependencies, unfortunately some of them are
// instrumented by java-concurrent instrumentation
if (name.startsWith("com.couchbase.client.deps.io.netty.")
|| name.startsWith("com.couchbase.client.deps.org.LatencyUtils.")
|| name.startsWith("com.couchbase.client.deps.com.lmax.disruptor.")) {
return false;
}
return true;
@ -227,7 +256,9 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
}
if (name.startsWith("com.google.inject.")) {
// We instrument Runnable there
if (name.startsWith("com.google.inject.internal.AbstractBindingProcessor$")) {
if (name.startsWith("com.google.inject.internal.AbstractBindingProcessor$")
|| name.startsWith("com.google.inject.internal.BytecodeGen$")
|| name.startsWith("com.google.inject.internal.cglib.core.internal.$LoadingCache$")) {
return false;
}
// We instrument Callable there
@ -237,7 +268,7 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
return true;
}
if (name.startsWith("com.google.api.")) {
if (name.equals("com.google.api.client.http.HttpRequest")) {
if (name.startsWith("com.google.api.client.http.HttpRequest")) {
return false;
}
return true;
@ -248,8 +279,24 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
|| name.startsWith("org.h2.jdbc.")
|| name.startsWith("org.h2.jdbcx.")
// Some runnables that get instrumented
|| name.equals("org.h2.util.Task")
|| name.equals("org.h2.store.FileLock")
|| name.equals("org.h2.engine.DatabaseCloser")) {
|| name.equals("org.h2.engine.DatabaseCloser")
|| name.equals("org.h2.engine.OnExitDatabaseCloser")) {
return false;
}
return true;
}
if (name.startsWith("com.carrotsearch.hppc.")) {
if (name.startsWith("com.carrotsearch.hppc.HashOrderMixing$")) {
return false;
}
return true;
}
if (name.startsWith("com.fasterxml.jackson.")) {
if (name.equals("com.fasterxml.jackson.module.afterburner.util.MyClassLoader")) {
return false;
}
return true;

View File

@ -41,12 +41,18 @@ public class GlobalIgnoresMatcher<T extends TypeDescription>
private static final Pattern COM_MCHANGE_PROXY =
Pattern.compile("com\\.mchange\\.v2\\.c3p0\\..*Proxy");
public static <T extends TypeDescription> ElementMatcher.Junction<T> globalIgnoresMatcher() {
return new GlobalIgnoresMatcher<>();
public static <T extends TypeDescription> ElementMatcher.Junction<T> globalIgnoresMatcher(
final boolean skipAdditionalLibraryMatcher) {
return new GlobalIgnoresMatcher<>(skipAdditionalLibraryMatcher);
}
private final ElementMatcher<T> additionalLibraryIgnoreMatcher =
AdditionalLibraryIgnoresMatcher.additionalLibraryIgnoresMatcher();
private final boolean skipAdditionalLibraryMatcher;
private GlobalIgnoresMatcher(final boolean skipAdditionalLibraryMatcher) {
this.skipAdditionalLibraryMatcher = skipAdditionalLibraryMatcher;
}
/**
* Be very careful about the types of matchers used in this section as they are called on every
@ -146,7 +152,8 @@ public class GlobalIgnoresMatcher<T extends TypeDescription>
|| name.contains("CGLIB$$")
|| name.contains("javassist")
|| name.contains(".asm.")
|| name.contains("$__sisu")) {
|| name.contains("$__sisu")
|| name.startsWith("org.springframework.core.$Proxy")) {
return true;
}
@ -154,7 +161,7 @@ public class GlobalIgnoresMatcher<T extends TypeDescription>
return true;
}
if (additionalLibraryIgnoreMatcher.matches(target)) {
if (!skipAdditionalLibraryMatcher && additionalLibraryIgnoreMatcher.matches(target)) {
return true;
}

View File

@ -117,7 +117,9 @@ public class MuzzleVersionScanPlugin {
// verify helper injector works
final String[] helperClassNames = defaultInstrumenter.helperClassNames();
if (helperClassNames.length > 0) {
new HelperInjector(createHelperMap(defaultInstrumenter))
new HelperInjector(
MuzzleVersionScanPlugin.class.getSimpleName(),
createHelperMap(defaultInstrumenter))
.transform(null, null, userClassLoader, null);
}
} catch (final Exception e) {

View File

@ -39,7 +39,7 @@ class HelperInjectionTest extends AgentSpecification {
def "helpers injected to non-delegating classloader"() {
setup:
String helperClassName = HelperInjectionTest.getPackage().getName() + '.HelperClass'
HelperInjector injector = new HelperInjector(helperClassName)
HelperInjector injector = new HelperInjector("test", helperClassName)
AtomicReference<URLClassLoader> emptyLoader = new AtomicReference<>(new URLClassLoader(new URL[0], (ClassLoader) null))
when:
@ -71,7 +71,7 @@ class HelperInjectionTest extends AgentSpecification {
ByteBuddyAgent.install()
AgentInstaller.installBytebuddyAgent(ByteBuddyAgent.getInstrumentation())
String helperClassName = HelperInjectionTest.getPackage().getName() + '.HelperClass'
HelperInjector injector = new HelperInjector(helperClassName)
HelperInjector injector = new HelperInjector("test", helperClassName)
URLClassLoader bootstrapChild = new URLClassLoader(new URL[0], (ClassLoader) null)
when:

View File

@ -18,6 +18,7 @@ package io.opentelemetry.auto.tooling
import io.opentelemetry.auto.common.exec.CommonTaskExecutor
import io.opentelemetry.auto.util.gc.GCUtils
import io.opentelemetry.auto.util.test.AgentSpecification
import spock.lang.Retry
import spock.lang.Subject
import java.lang.ref.WeakReference
@ -26,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger
import static java.util.concurrent.TimeUnit.MILLISECONDS
@Retry
class CleanerTest extends AgentSpecification {
@Subject

View File

@ -47,6 +47,12 @@ afterEvaluate {
annotationProcessor deps.autoservice
implementation deps.autoservice
// Include instrumentations instrumenting core JDK classes tp ensure interoperability with other instrumentation
testCompile project(':instrumentation:java-concurrent')
// FIXME: we should enable this, but currently this fails tests for google http client
//testCompile project(':instrumentation:http-url-connection')
testCompile project(':instrumentation:java-class-loader')
testCompile project(':testing')
testAnnotationProcessor deps.autoservice
testImplementation deps.autoservice

View File

@ -78,25 +78,18 @@ dependencies {
testCompile group: 'com.typesafe.akka', name: 'akka-http_2.11', version: '10.0.0'
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
testCompile project(':instrumentation:java-concurrent')
testCompile project(':instrumentation:trace-annotation')
lagomTestCompile project(':instrumentation:akka-http-10.0')
lagomTestCompile project(':instrumentation:trace-annotation')
lagomTestCompile project(':instrumentation:java-concurrent')
lagomTestCompile group: 'com.lightbend.lagom', name: 'lagom-javadsl-testkit_2.11', version: '1.4.0'
// There are some internal API changes in 10.1 that we would like to test separately for
version101TestCompile group: 'com.typesafe.akka', name: 'akka-http_2.11', version: '10.1.0'
version101TestCompile group: 'com.typesafe.akka', name: 'akka-stream_2.11', version: '2.5.11'
version101TestCompile project(':instrumentation:java-concurrent')
version101TestCompile project(':instrumentation:trace-annotation')
latestDepTestCompile group: 'com.typesafe.akka', name: 'akka-http_2.11', version: '+'
latestDepTestCompile group: 'com.typesafe.akka', name: 'akka-stream_2.11', version: '+'
latestDepTestCompile project(':instrumentation:java-concurrent')
latestDepTestCompile project(':instrumentation:trace-annotation')
}
test.dependsOn lagomTest

View File

@ -17,7 +17,7 @@ import akka.NotUsed
import akka.stream.javadsl.Source
import akka.stream.testkit.TestSubscriber.Probe
import akka.stream.testkit.javadsl.TestSink
import io.opentelemetry.auto.decorator.HttpServerDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpServerDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -18,7 +18,7 @@ package io.opentelemetry.auto.instrumentation.akkahttp;
import akka.http.scaladsl.model.HttpRequest;
import akka.http.scaladsl.model.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import java.net.URI;
import java.net.URISyntaxException;

View File

@ -59,9 +59,6 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
return new String[] {
AkkaHttpClientInstrumentation.class.getName() + "$OnCompleteHandler",
AkkaHttpClientInstrumentation.class.getName() + "$AkkaHttpHeaders",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".AkkaHttpClientDecorator",
};
}

View File

@ -18,7 +18,7 @@ package io.opentelemetry.auto.instrumentation.akkahttp;
import akka.http.scaladsl.model.HttpRequest;
import akka.http.scaladsl.model.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpServerDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpServerDecorator;
import io.opentelemetry.trace.Tracer;
import java.net.URI;
import java.net.URISyntaxException;

View File

@ -65,9 +65,6 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
AkkaHttpServerInstrumentation.class.getName() + "$AsyncWrapper$1",
AkkaHttpServerInstrumentation.class.getName() + "$AsyncWrapper$2",
packageName + ".AkkaHttpServerHeaders",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ServerDecorator",
"io.opentelemetry.auto.decorator.HttpServerDecorator",
packageName + ".AkkaHttpServerDecorator",
};
}

View File

@ -19,7 +19,7 @@ import akka.http.javadsl.model.HttpMethods
import akka.http.javadsl.model.HttpRequest
import akka.http.javadsl.model.headers.RawHeader
import akka.stream.ActorMaterializer
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.akkahttp.AkkaHttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
@ -29,7 +29,7 @@ import spock.lang.Shared
import static io.opentelemetry.trace.Span.Kind.CLIENT
class AkkaHttpClientInstrumentationTest extends HttpClientTest<AkkaHttpClientDecorator> {
class AkkaHttpClientInstrumentationTest extends HttpClientTest {
@Shared
ActorSystem system = ActorSystem.create()
@ -55,8 +55,8 @@ class AkkaHttpClientInstrumentationTest extends HttpClientTest<AkkaHttpClientDec
}
@Override
AkkaHttpClientDecorator decorator() {
return AkkaHttpClientDecorator.DECORATE
String component() {
return AkkaHttpClientDecorator.DECORATE.getComponentName()
}
@Override

View File

@ -25,11 +25,11 @@ import static io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint.EXCE
import static io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint.SUCCESS
import static io.opentelemetry.trace.Span.Kind.SERVER
abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<Object, AkkaHttpServerDecorator> {
abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<Object> {
@Override
AkkaHttpServerDecorator decorator() {
return AkkaHttpServerDecorator.DECORATE
String component() {
return AkkaHttpServerDecorator.DECORATE.getComponentName()
}
@Override
@ -61,7 +61,7 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<Object,
}
tags {
"$MoreTags.SPAN_TYPE" SpanTypes.HTTP_SERVER
"$Tags.COMPONENT" serverDecorator.getComponentName()
"$Tags.COMPONENT" component
"$Tags.HTTP_URL" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }
"$Tags.HTTP_METHOD" method
"$Tags.HTTP_STATUS" endpoint.status
@ -78,6 +78,7 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest<Object,
}
}
@Retry
class AkkaHttpServerInstrumentationTestSync extends AkkaHttpServerInstrumentationTest {
@Override
def startServer(int port) {
@ -90,7 +91,7 @@ class AkkaHttpServerInstrumentationTestSync extends AkkaHttpServerInstrumentatio
}
}
@Retry(mode = Retry.Mode.SETUP_FEATURE_CLEANUP)
@Retry
class AkkaHttpServerInstrumentationTestAsync extends AkkaHttpServerInstrumentationTest {
@Override
def startServer(int port) {

View File

@ -23,8 +23,6 @@ testSets {
dependencies {
compileOnly group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.0'
testCompile project(':instrumentation:java-concurrent')
testCompile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.0'
latestDepTestCompile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '+'

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.apachehttpasyncclient;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import java.net.URI;
import java.net.URISyntaxException;

View File

@ -15,17 +15,16 @@
*/
package io.opentelemetry.auto.instrumentation.apachehttpasyncclient;
import static io.opentelemetry.auto.decorator.HttpClientDecorator.DEFAULT_SPAN_NAME;
import static io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator.DEFAULT_SPAN_NAME;
import static io.opentelemetry.auto.instrumentation.apachehttpasyncclient.ApacheHttpAsyncClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.apachehttpasyncclient.ApacheHttpAsyncClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.apachehttpasyncclient.HttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
@ -58,7 +57,7 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/nio/client/HttpAsyncClient.class"));
return hasClassesNamed("org.apache.http.nio.client.HttpAsyncClient");
}
@Override
@ -72,9 +71,6 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
packageName + ".HttpHeadersInjectAdapter",
getClass().getName() + "$DelegatingRequestProducer",
getClass().getName() + "$TraceContinuedFutureCallback",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".ApacheHttpAsyncClientDecorator"
};
}

View File

@ -15,12 +15,11 @@
*/
package io.opentelemetry.auto.instrumentation.apachehttpasyncclient;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
@ -49,7 +48,7 @@ public class ApacheHttpClientRedirectInstrumentation extends Instrumenter.Defaul
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/client/RedirectStrategy.class"));
return hasClassesNamed("org.apache.http.client.RedirectStrategy");
}
@Override

View File

@ -24,7 +24,7 @@ import spock.lang.Shared
import java.util.concurrent.CompletableFuture
class ApacheHttpAsyncClientCallbackTest extends HttpClientTest<ApacheHttpAsyncClientDecorator> {
class ApacheHttpAsyncClientCallbackTest extends HttpClientTest {
@AutoCleanup
@Shared
@ -66,8 +66,8 @@ class ApacheHttpAsyncClientCallbackTest extends HttpClientTest<ApacheHttpAsyncCl
}
@Override
ApacheHttpAsyncClientDecorator decorator() {
return ApacheHttpAsyncClientDecorator.DECORATE
String component() {
return ApacheHttpAsyncClientDecorator.DECORATE.getComponentName()
}
@Override

View File

@ -22,7 +22,7 @@ import spock.lang.Shared
import java.util.concurrent.Future
class ApacheHttpAsyncClientNullCallbackTest extends HttpClientTest<ApacheHttpAsyncClientDecorator> {
class ApacheHttpAsyncClientNullCallbackTest extends HttpClientTest {
@AutoCleanup
@Shared
@ -51,8 +51,8 @@ class ApacheHttpAsyncClientNullCallbackTest extends HttpClientTest<ApacheHttpAsy
}
@Override
ApacheHttpAsyncClientDecorator decorator() {
return ApacheHttpAsyncClientDecorator.DECORATE
String component() {
return ApacheHttpAsyncClientDecorator.DECORATE.getComponentName()
}
@Override

View File

@ -24,7 +24,7 @@ import spock.lang.Shared
import java.util.concurrent.CountDownLatch
class ApacheHttpAsyncClientTest extends HttpClientTest<ApacheHttpAsyncClientDecorator> {
class ApacheHttpAsyncClientTest extends HttpClientTest {
@AutoCleanup
@Shared
@ -72,8 +72,8 @@ class ApacheHttpAsyncClientTest extends HttpClientTest<ApacheHttpAsyncClientDeco
}
@Override
ApacheHttpAsyncClientDecorator decorator() {
return ApacheHttpAsyncClientDecorator.DECORATE
String component() {
return ApacheHttpAsyncClientDecorator.DECORATE.getComponentName()
}
@Override

View File

@ -5,7 +5,7 @@ muzzle {
pass {
group = "commons-httpclient"
module = "commons-httpclient"
versions = "[3.0,4.0)"
versions = "[2.0,]"
assertInverse = true
}
}
@ -17,9 +17,9 @@ testSets {
}
dependencies {
compileOnly group: 'commons-httpclient', name: 'commons-httpclient', version: '3.0'
compileOnly group: 'commons-httpclient', name: 'commons-httpclient', version: '2.0'
testCompile group: 'commons-httpclient', name: 'commons-httpclient', version: '3.0'
testCompile group: 'commons-httpclient', name: 'commons-httpclient', version: '2.0'
latestDepTestCompile group: 'commons-httpclient', name: 'commons-httpclient', version: '+'
}

View File

@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0;
package io.opentelemetry.auto.instrumentation.commonshttpclient;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import java.net.URI;
import java.net.URISyntaxException;
@ -24,11 +24,11 @@ import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.StatusLine;
import org.apache.commons.httpclient.URIException;
public class ApacheHttpClientDecorator extends HttpClientDecorator<HttpMethod, HttpMethod> {
public static final ApacheHttpClientDecorator DECORATE = new ApacheHttpClientDecorator();
public class CommonsHttpClientDecorator extends HttpClientDecorator<HttpMethod, HttpMethod> {
public static final CommonsHttpClientDecorator DECORATE = new CommonsHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerFactory().get("io.opentelemetry.auto.apache-httpclient-3.0");
OpenTelemetry.getTracerFactory().get("io.opentelemetry.auto.apache-httpclient-2.0");
@Override
protected String getComponentName() {
@ -42,13 +42,12 @@ public class ApacheHttpClientDecorator extends HttpClientDecorator<HttpMethod, H
@Override
protected URI url(final HttpMethod httpMethod) throws URISyntaxException {
final org.apache.commons.httpclient.URI uri;
try {
uri = httpMethod.getURI();
// org.apache.commons.httpclient.URI -> java.net.URI
return new URI(httpMethod.getURI().toString());
} catch (final URIException e) {
return null;
throw new URISyntaxException("", e.getMessage());
}
return new URI(uri.toString());
}
@Override

View File

@ -13,18 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0;
package io.opentelemetry.auto.instrumentation.commonshttpclient;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0.ApacheHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0.ApacheHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0.HttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.instrumentation.commonshttpclient.CommonsHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.commonshttpclient.CommonsHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.commonshttpclient.HttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
@ -43,10 +42,16 @@ import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
@AutoService(Instrumenter.class)
public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
public class CommonsHttpClientInstrumentation extends Instrumenter.Default {
public ApacheHttpClientInstrumentation() {
super("httpclient", "apache-httpclient", "apache-http-client");
public CommonsHttpClientInstrumentation() {
super("apache-httpclient");
}
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("org.apache.commons.httpclient.HttpClient");
}
@Override
@ -57,34 +62,29 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpHeadersInjectAdapter",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".ApacheHttpClientDecorator"
packageName + ".CommonsHttpClientDecorator", packageName + ".HttpHeadersInjectAdapter",
};
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
isMethod()
.and(named("executeMethod"))
.and(not(isAbstract()))
.and(takesArguments(3))
.and(takesArgument(0, named("org.apache.commons.httpclient.HostConfiguration")))
.and(takesArgument(1, named("org.apache.commons.httpclient.HttpMethod")))
.and(takesArgument(2, named("org.apache.commons.httpclient.HttpState"))),
ApacheHttpClientInstrumentation.class.getName() + "$ExecuteAdvice");
.and(takesArgument(1, named("org.apache.commons.httpclient.HttpMethod"))),
CommonsHttpClientInstrumentation.class.getName() + "$ExecAdvice");
}
public static class ExecuteAdvice {
public static class ExecAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static SpanWithScope methodEnter(@Advice.Argument(1) final HttpMethod httpMethod) {
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(HttpClient.class);
if (callDepth > 0) {
return null;
}
final Span span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(httpMethod))
@ -94,13 +94,8 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
DECORATE.afterStart(span);
DECORATE.onRequest(span, httpMethod);
TRACER.getHttpTextFormat().inject(span.getContext(), httpMethod, SETTER);
final boolean awsClientCall =
httpMethod.getRequestHeaders("amz-sdk-invocation-id").length > 0;
// AWS calls are often signed, so we can't add headers without breaking the signature.
if (!awsClientCall) {
TRACER.getHttpTextFormat().inject(span.getContext(), httpMethod, SETTER);
}
return new SpanWithScope(span, scope);
}

View File

@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0;
package io.opentelemetry.auto.instrumentation.commonshttpclient;
import io.opentelemetry.context.propagation.HttpTextFormat;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpMethod;
public class HttpHeadersInjectAdapter implements HttpTextFormat.Setter<HttpMethod> {
@ -24,6 +25,6 @@ public class HttpHeadersInjectAdapter implements HttpTextFormat.Setter<HttpMetho
@Override
public void put(final HttpMethod carrier, final String key, final String value) {
carrier.addRequestHeader(key, value);
carrier.setRequestHeader(new Header(key, value));
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* 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.
*/
import io.opentelemetry.auto.instrumentation.commonshttpclient.CommonsHttpClientDecorator
import io.opentelemetry.auto.test.base.HttpClientTest
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.HttpMethod
import org.apache.commons.httpclient.methods.DeleteMethod
import org.apache.commons.httpclient.methods.GetMethod
import org.apache.commons.httpclient.methods.HeadMethod
import org.apache.commons.httpclient.methods.OptionsMethod
import org.apache.commons.httpclient.methods.PostMethod
import org.apache.commons.httpclient.methods.PutMethod
import org.apache.commons.httpclient.methods.TraceMethod
import spock.lang.Shared
class CommonsHttpClientTest extends HttpClientTest {
@Shared
HttpClient client = new HttpClient()
@Override
int doRequest(String method, URI uri, Map<String, String> headers, Closure callback) {
HttpMethod httpMethod
switch (method) {
case "GET":
httpMethod = new GetMethod(uri.toString())
break
case "PUT":
httpMethod = new PutMethod(uri.toString())
break
case "POST":
httpMethod = new PostMethod(uri.toString())
break
case "HEAD":
httpMethod = new HeadMethod(uri.toString())
break
case "DELETE":
httpMethod = new DeleteMethod(uri.toString())
break
case "OPTIONS":
httpMethod = new OptionsMethod(uri.toString())
break
case "TRACE":
httpMethod = new TraceMethod(uri.toString())
break
default:
throw new RuntimeException("Unsupported method: " + method)
}
headers.each { httpMethod.setRequestHeader(it.key, it.value) }
try {
client.executeMethod(httpMethod)
callback?.call()
return httpMethod.getStatusCode()
} finally {
httpMethod.releaseConnection()
}
}
@Override
String component() {
return CommonsHttpClientDecorator.DECORATE.getComponentName()
}
@Override
boolean testRedirects() {
// Generates 4 spans
false
}
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* 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.
*/
import io.opentelemetry.auto.instrumentation.apachehttpclient.v3_0.ApacheHttpClientDecorator
import io.opentelemetry.auto.test.base.HttpClientTest
import org.apache.commons.httpclient.HostConfiguration
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.HttpMethod
import org.apache.commons.httpclient.HttpState
import org.apache.commons.httpclient.methods.GetMethod
import org.apache.commons.httpclient.methods.HeadMethod
import org.apache.commons.httpclient.methods.PostMethod
import org.apache.commons.httpclient.methods.PutMethod
import spock.lang.Shared
import java.util.concurrent.ExecutionException
abstract class ApacheHttpClientTest extends HttpClientTest<ApacheHttpClientDecorator> {
@Shared
def client = new HttpClient()
@Override
ApacheHttpClientDecorator decorator() {
return ApacheHttpClientDecorator.DECORATE
}
@Override
int doRequest(String method, URI uri, Map<String, String> headers, Closure callback) {
def httpMethod
switch (method) {
case "GET":
httpMethod = new GetMethod(uri.toString())
break
case "POST":
httpMethod = new PostMethod(uri.toString())
break
case "PUT":
httpMethod = new PutMethod(uri.toString())
break
case "HEAD":
httpMethod = new HeadMethod(uri.toString())
break
default:
throw new IllegalStateException("Unexpected http method: " + method)
}
headers.entrySet().each {
httpMethod.addRequestHeader(it.key, it.value)
}
def statusCode = executeRequest(httpMethod, uri)
callback?.call()
httpMethod.releaseConnection()
return statusCode
}
abstract int executeRequest(HttpMethod request, URI uri)
@Override
boolean testCircularRedirects() {
// only creates 1 server request instead of 2 server requests before throwing exception like others
false
}
@Override
Integer statusOnRedirectError() {
return 302
}
def "basic #method request with circular redirects"() {
given:
def uri = server.address.resolve("/circular-redirect")
when:
doRequest(method, uri)
then:
def ex = thrown(Exception)
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
and:
assertTraces(1) {
trace(0, 2) {
clientSpan(it, 0, null, method, false, false, uri, statusOnRedirectError(), thrownException)
serverSpan(it, 1, span(0))
}
}
where:
method = "GET"
}
}
class ApacheClientHttpMethod extends ApacheHttpClientTest {
@Override
int executeRequest(HttpMethod httpMethod, URI uri) {
client.executeMethod(httpMethod)
}
}
class ApacheClientHostConfiguration extends ApacheHttpClientTest {
@Override
int executeRequest(HttpMethod httpMethod, URI uri) {
client.executeMethod(new HostConfiguration(), httpMethod)
}
}
class ApacheClientHttpState extends ApacheHttpClientTest {
@Override
int executeRequest(HttpMethod httpMethod, URI uri) {
client.executeMethod(new HostConfiguration(), httpMethod, new HttpState())
}
}

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.apachehttpclient;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import java.net.URI;
import org.apache.http.HttpResponse;

View File

@ -18,7 +18,7 @@ package io.opentelemetry.auto.instrumentation.apachehttpclient;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.ApacheHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.ApacheHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.HttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
@ -60,7 +60,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/client/HttpClient.class"));
return hasClassesNamed("org.apache.http.client.HttpClient");
}
@Override
@ -71,14 +71,11 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
getClass().getName() + "$HelperMethods",
packageName + ".HttpHeadersInjectAdapter",
getClass().getName() + "$WrappingStatusSettingResponseHandler",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".ApacheHttpClientDecorator",
packageName + ".HttpHeadersInjectAdapter",
packageName + ".HostAndRequestAsHttpUriRequest",
getClass().getName() + "$HelperMethods",
getClass().getName() + "$WrappingStatusSettingResponseHandler",
};
}

View File

@ -21,7 +21,7 @@ import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.message.BasicHeader
import spock.lang.Shared
class ApacheHttpClientResponseHandlerTest extends HttpClientTest<ApacheHttpClientDecorator> {
class ApacheHttpClientResponseHandlerTest extends HttpClientTest {
@Shared
def client = new DefaultHttpClient()
@ -50,7 +50,7 @@ class ApacheHttpClientResponseHandlerTest extends HttpClientTest<ApacheHttpClien
}
@Override
ApacheHttpClientDecorator decorator() {
return ApacheHttpClientDecorator.DECORATE
String component() {
return ApacheHttpClientDecorator.DECORATE.getComponentName()
}
}

View File

@ -24,13 +24,13 @@ import org.apache.http.message.BasicHttpRequest
import org.apache.http.protocol.BasicHttpContext
import spock.lang.Shared
abstract class ApacheHttpClientTest<T extends HttpRequest> extends HttpClientTest<ApacheHttpClientDecorator> {
abstract class ApacheHttpClientTest<T extends HttpRequest> extends HttpClientTest {
@Shared
def client = new DefaultHttpClient()
@Override
ApacheHttpClientDecorator decorator() {
return ApacheHttpClientDecorator.DECORATE
String component() {
return ApacheHttpClientDecorator.DECORATE.getComponentName()
}
@Override

View File

@ -52,9 +52,6 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".AwsSdkClientDecorator",
packageName + ".RequestMeta",
packageName + ".TracingRequestHandler",

View File

@ -56,9 +56,7 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
packageName + ".OnErrorDecorator",
packageName + ".RequestMeta",
packageName + ".OnErrorDecorator", packageName + ".RequestMeta",
};
}

View File

@ -20,7 +20,7 @@ import com.amazonaws.AmazonWebServiceResponse;
import com.amazonaws.Request;
import com.amazonaws.Response;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.trace.Span;
import java.net.URI;

View File

@ -15,7 +15,7 @@
*/
package io.opentelemetry.auto.instrumentation.aws.v0;
import io.opentelemetry.auto.decorator.BaseDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator;
public class OnErrorDecorator extends BaseDecorator {
public static final OnErrorDecorator DECORATE = new OnErrorDecorator();

View File

@ -15,12 +15,11 @@
*/
package io.opentelemetry.auto.instrumentation.aws.v0;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.amazonaws.AmazonWebServiceRequest;
@ -45,7 +44,7 @@ public final class RequestInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("com/amazonaws/AmazonWebServiceRequest.class"));
return hasClassesNamed("com.amazonaws.AmazonWebServiceRequest");
}
@Override

View File

@ -43,7 +43,7 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.amazonaws.services.sqs.AmazonSQSClientBuilder
import com.amazonaws.services.sqs.model.CreateQueueRequest
import com.amazonaws.services.sqs.model.SendMessageRequest
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -30,7 +30,7 @@ import com.amazonaws.services.rds.AmazonRDSClient
import com.amazonaws.services.rds.model.DeleteOptionGroupRequest
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.S3ClientOptions
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -25,8 +25,6 @@ dependencies {
testCompile project(':instrumentation:apache-httpclient:apache-httpclient-4.0')
// Also include netty instrumentation because it is used by aws async client
testCompile project(':instrumentation:netty:netty-4.1')
// Needed by netty async instrumentation
testCompile project(':instrumentation:java-concurrent')
testCompile group: 'software.amazon.awssdk', name: 'apache-client', version: '2.2.0'
testCompile group: 'software.amazon.awssdk', name: 's3', version: '2.2.0'
testCompile group: 'software.amazon.awssdk', name: 'rds', version: '2.2.0'
@ -37,7 +35,6 @@ dependencies {
latestDepTestCompile project(':instrumentation:apache-httpclient:apache-httpclient-4.0')
latestDepTestCompile project(':instrumentation:netty:netty-4.1')
latestDepTestCompile project(':instrumentation:java-concurrent')
latestDepTestCompile group: 'software.amazon.awssdk', name: 'apache-client', version: '+'
latestDepTestCompile group: 'software.amazon.awssdk', name: 's3', version: '+'

View File

@ -27,9 +27,6 @@ public abstract class AbstractAwsClientInstrumentation extends Instrumenter.Defa
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.HttpClientDecorator",
packageName + ".AwsSdkClientDecorator",
packageName + ".TracingExecutionInterceptor",
packageName + ".TracingExecutionInterceptor$ScopeHolder"

View File

@ -15,6 +15,7 @@
*/
package io.opentelemetry.auto.instrumentation.aws.v2;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -35,6 +36,12 @@ import software.amazon.awssdk.core.client.builder.SdkClientBuilder;
@AutoService(Instrumenter.class)
public final class AwsClientInstrumentation extends AbstractAwsClientInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("software.amazon.awssdk.core.client.builder.SdkClientBuilder");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return nameStartsWith("software.amazon.awssdk.")

View File

@ -16,6 +16,7 @@
package io.opentelemetry.auto.instrumentation.aws.v2;
import static io.opentelemetry.auto.instrumentation.aws.v2.TracingExecutionInterceptor.ScopeHolder.CURRENT;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -40,6 +41,13 @@ import software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRe
@AutoService(Instrumenter.class)
public final class AwsHttpClientInstrumentation extends AbstractAwsClientInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed(
"software.amazon.awssdk.core.internal.http.pipeline.stages.MakeHttpRequestStage");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return nameStartsWith("software.amazon.awssdk.")

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.aws.v2;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.HttpClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;

View File

@ -15,7 +15,7 @@
*/
package io.opentelemetry.auto.instrumentation.aws.v2;
import static io.opentelemetry.auto.decorator.HttpClientDecorator.DEFAULT_SPAN_NAME;
import static io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator.DEFAULT_SPAN_NAME;
import static io.opentelemetry.auto.instrumentation.aws.v2.AwsSdkClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.aws.v2.AwsSdkClientDecorator.TRACER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -18,7 +18,7 @@ package io.opentelemetry.auto.instrumentation.datastax.cassandra;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
import io.opentelemetry.auto.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.instrumentation.api.SpanTypes;
import io.opentelemetry.trace.Span;

View File

@ -47,9 +47,6 @@ public class CassandraClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
packageName + ".CassandraClientDecorator",
packageName + ".TracingSession",
packageName + ".TracingSession$1",

View File

@ -8,8 +8,6 @@ testSets {
}
dependencies {
testCompile project(':instrumentation:java-concurrent')
testCompile group: 'org.jboss.weld', name: 'weld-core', version: '2.3.0.Final'
testCompile group: 'org.jboss.weld.se', name: 'weld-se', version: '2.3.0.Final'
testCompile group: 'org.jboss.weld.se', name: 'weld-se-core', version: '2.3.0.Final'

View File

@ -51,9 +51,6 @@ public class CouchbaseBucketInstrumentation extends Instrumenter.Default {
public String[] helperClassNames() {
return new String[] {
"rx.__OpenTelemetryTracingUtil",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
"io.opentelemetry.auto.instrumentation.rxjava.SpanFinishingSubscription",
"io.opentelemetry.auto.instrumentation.rxjava.TracedSubscriber",
"io.opentelemetry.auto.instrumentation.rxjava.TracedOnSubscribe",
@ -81,7 +78,7 @@ public class CouchbaseBucketInstrumentation extends Instrumenter.Default {
return CallDepthThreadLocalMap.incrementCallDepth(CouchbaseCluster.class);
}
@Advice.OnMethodExit(onThrowable = Throwable.class)
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void subscribeResult(
@Advice.Enter final int callDepth,
@Advice.Origin final Method method,

View File

@ -15,7 +15,7 @@
*/
package io.opentelemetry.auto.instrumentation.couchbase.client;
import io.opentelemetry.auto.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.instrumentation.api.SpanTypes;
class CouchbaseClientDecorator extends DatabaseClientDecorator {

View File

@ -51,9 +51,6 @@ public class CouchbaseClusterInstrumentation extends Instrumenter.Default {
public String[] helperClassNames() {
return new String[] {
"rx.__OpenTelemetryTracingUtil",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
"io.opentelemetry.auto.instrumentation.rxjava.SpanFinishingSubscription",
"io.opentelemetry.auto.instrumentation.rxjava.TracedSubscriber",
"io.opentelemetry.auto.instrumentation.rxjava.TracedOnSubscribe",
@ -76,7 +73,7 @@ public class CouchbaseClusterInstrumentation extends Instrumenter.Default {
return CallDepthThreadLocalMap.incrementCallDepth(CouchbaseCluster.class);
}
@Advice.OnMethodExit(onThrowable = Throwable.class)
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void subscribeResult(
@Advice.Enter final int callDepth,
@Advice.Origin final Method method,

View File

@ -19,6 +19,7 @@ import com.couchbase.client.java.document.JsonDocument
import com.couchbase.client.java.document.json.JsonObject
import com.couchbase.client.java.env.CouchbaseEnvironment
import com.couchbase.client.java.query.N1qlQuery
import spock.lang.Retry
import spock.lang.Unroll
import spock.util.concurrent.BlockingVariable
import util.AbstractCouchbaseTest
@ -28,6 +29,7 @@ import java.util.concurrent.TimeUnit
import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
@Retry
@Unroll
class CouchbaseAsyncClientTest extends AbstractCouchbaseTest {
static final int TIMEOUT = 10

View File

@ -20,12 +20,14 @@ import com.couchbase.client.java.document.JsonDocument
import com.couchbase.client.java.document.json.JsonObject
import com.couchbase.client.java.env.CouchbaseEnvironment
import com.couchbase.client.java.query.N1qlQuery
import spock.lang.Retry
import spock.lang.Unroll
import util.AbstractCouchbaseTest
import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
@Retry
@Unroll
class CouchbaseClientTest extends AbstractCouchbaseTest {
def "test hasBucket #type"() {

View File

@ -29,7 +29,7 @@ import util.AbstractCouchbaseTest
import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
@Retry(count = 5, delay = 1)
@Retry(count = 10, delay = 5)
@Unroll
class CouchbaseSpringTemplateTest extends AbstractCouchbaseTest {

View File

@ -15,13 +15,12 @@
*/
package io.opentelemetry.auto.instrumentation.couchbase.client;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
@ -48,9 +47,7 @@ public class CouchbaseNetworkInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(
classLoaderHasNoResources(
"com/couchbase/client/core/endpoint/AbstractGenericHandler.class"));
return hasClassesNamed("com.couchbase.client.core.endpoint.AbstractGenericHandler");
}
@Override

View File

@ -9,7 +9,6 @@ apply from: "${rootDir}/gradle/instrumentation.gradle"
//}
dependencies {
testCompile project(':instrumentation:java-concurrent')
testCompile project(':instrumentation:jaxrs:jaxrs-2.0')
testCompile project(':instrumentation:servlet:request-3.0')

View File

@ -23,12 +23,12 @@ import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags
import io.opentelemetry.auto.instrumentation.jaxrs2.JaxRsAnnotationsDecorator
import io.opentelemetry.auto.instrumentation.servlet3.Servlet3Decorator
import io.opentelemetry.auto.test.asserts.TraceAssert
import io.opentelemetry.auto.test.base.HttpServerTest
import io.opentelemetry.auto.test.utils.PortUtils
import io.opentelemetry.sdk.trace.SpanData
import org.eclipse.jetty.servlet.ServletHandler
import spock.lang.Retry
import javax.ws.rs.GET
import javax.ws.rs.Path
@ -45,7 +45,9 @@ import static io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint.SUCC
import static io.opentelemetry.trace.Span.Kind.INTERNAL
import static io.opentelemetry.trace.Span.Kind.SERVER
class DropwizardTest extends HttpServerTest<DropwizardTestSupport, Servlet3Decorator> {
// Work around for: address already in use
@Retry
class DropwizardTest extends HttpServerTest<DropwizardTestSupport> {
@Override
DropwizardTestSupport startServer(int port) {
@ -72,13 +74,8 @@ class DropwizardTest extends HttpServerTest<DropwizardTestSupport, Servlet3Decor
}
@Override
Servlet3Decorator decorator() {
return new Servlet3Decorator() {
@Override
protected String getComponentName() {
return "jax-rs"
}
}
String component() {
return "jax-rs"
}
@Override
@ -121,7 +118,7 @@ class DropwizardTest extends HttpServerTest<DropwizardTestSupport, Servlet3Decor
@Override
void serverSpan(TraceAssert trace, int index, String traceID = null, String parentID = null, String method = "GET", ServerEndpoint endpoint = SUCCESS) {
trace.span(index) {
operationName "$method ${endpoint == PATH_PARAM ? "/path/{id}/param" : endpoint.resolvePath(address).path}"
operationName "$method ${endpoint == PATH_PARAM ? "/path/{id}/param" : endpoint.resolvePath(address).path}"
spanKind SERVER
errored endpoint.errored
if (parentID != null) {
@ -133,7 +130,7 @@ class DropwizardTest extends HttpServerTest<DropwizardTestSupport, Servlet3Decor
tags {
"$MoreTags.RESOURCE_NAME" "$method ${endpoint == PATH_PARAM ? "/path/{id}/param" : endpoint.resolvePath(address).path}"
"$MoreTags.SPAN_TYPE" SpanTypes.HTTP_SERVER
"$Tags.COMPONENT" serverDecorator.getComponentName()
"$Tags.COMPONENT" component
"$MoreTags.NET_PEER_IP" { it == null || it == "127.0.0.1" } // Optional
"$MoreTags.NET_PEER_PORT" Long
"$Tags.HTTP_URL" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }

View File

@ -15,19 +15,18 @@
*/
package io.opentelemetry.auto.instrumentation.dropwizard.view;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.dropwizard.views.View;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.BaseDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
import io.opentelemetry.auto.instrumentation.api.Tags;
@ -51,7 +50,7 @@ public final class DropwizardViewInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("io/dropwizard/views/ViewRenderer.class"));
return hasClassesNamed("io.dropwizard.views.ViewRenderer");
}
@Override
@ -61,9 +60,7 @@ public final class DropwizardViewInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator", getClass().getName() + "$RenderAdvice"
};
return new String[] {getClass().getName() + "$RenderAdvice"};
}
@Override

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.elasticsearch;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.auto.instrumentation.api.SpanTypes;
import io.opentelemetry.auto.instrumentation.api.Tags;

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.elasticsearch;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.DatabaseClientDecorator;
import io.opentelemetry.auto.instrumentation.api.MoreTags;
import io.opentelemetry.auto.instrumentation.api.SpanTypes;
import io.opentelemetry.trace.Span;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import groovy.json.JsonSlurper
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -45,9 +45,6 @@ public class Elasticsearch5RestClientInstrumentation extends Instrumenter.Defaul
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
"io.opentelemetry.auto.instrumentation.elasticsearch.ElasticsearchRestClientDecorator",
packageName + ".RestResponseListener",
};

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import groovy.json.JsonSlurper
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import groovy.json.JsonSlurper
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -46,9 +46,6 @@ public class Elasticsearch6RestClientInstrumentation extends Instrumenter.Defaul
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
"io.opentelemetry.auto.instrumentation.elasticsearch.ElasticsearchRestClientDecorator",
packageName + ".RestResponseListener",
};

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import groovy.json.JsonSlurper
import io.opentelemetry.auto.decorator.HttpClientDecorator
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator
import io.opentelemetry.auto.instrumentation.api.MoreTags
import io.opentelemetry.auto.instrumentation.api.SpanTypes
import io.opentelemetry.auto.instrumentation.api.Tags

View File

@ -177,15 +177,7 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
result.index == indexName
and:
assertTraces(6) {
sortTraces {
// IndexAction and PutMappingAction run in separate threads and so their order is not always the same
if (traces[3][0].attributes[MoreTags.RESOURCE_NAME].stringValue == "IndexAction") {
def tmp = traces[3]
traces[3] = traces[4]
traces[4] = tmp
}
}
assertTraces(5) {
trace(0, 1) {
span(0) {
operationName "elasticsearch.query"
@ -236,23 +228,7 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
}
}
}
trace(3, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(4, 1) {
trace(3, 2) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -268,8 +244,23 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
"elasticsearch.request.write.type" indexType
}
}
span(1) {
operationName "elasticsearch.query"
spanKind CLIENT
childOf span(0)
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(5, 1) {
trace(4, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT

View File

@ -83,13 +83,8 @@ class Elasticsearch2SpringRepositoryTest extends AgentTestRunner {
repo.index(doc) == doc
and:
def excludes = {
// sometimes PutMappingAction is present and sometimes it is not
// (only seems to happen with Elasticsearch 2.x, later versions seem to always have PutMappingAction)
it[0].attributes[MoreTags.RESOURCE_NAME].stringValue == "PutMappingAction"
}
assertTracesWithFilter(2, excludes) {
trace(0, 1) {
assertTraces(2) {
trace(0, 2) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -105,6 +100,21 @@ class Elasticsearch2SpringRepositoryTest extends AgentTestRunner {
"elasticsearch.request.write.type" "doc"
}
}
span(1) {
operationName "elasticsearch.query"
spanKind CLIENT
childOf span(0)
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(1, 1) {
span(0) {

View File

@ -145,15 +145,7 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
template.queryForList(query, Doc) == [new Doc()]
and:
assertTraces(7) {
sortTraces {
// IndexAction and PutMappingAction run in separate threads and so their order is not always the same
if (traces[3][0].attributes[MoreTags.RESOURCE_NAME].stringValue == "IndexAction") {
def tmp = traces[3]
traces[3] = traces[4]
traces[4] = tmp
}
}
assertTraces(6) {
trace(0, 1) {
span(0) {
operationName "elasticsearch.query"
@ -202,10 +194,26 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
}
}
}
trace(3, 1) {
trace(3, 2) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "IndexAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "IndexAction"
"elasticsearch.request" "IndexRequest"
"elasticsearch.request.indices" indexName
"elasticsearch.request.write.type" indexType
}
}
span(1) {
operationName "elasticsearch.query"
spanKind CLIENT
childOf span(0)
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
@ -219,23 +227,6 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
}
}
trace(4, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "IndexAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "IndexAction"
"elasticsearch.request" "IndexRequest"
"elasticsearch.request.indices" indexName
"elasticsearch.request.write.type" indexType
}
}
}
trace(5, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -254,7 +245,7 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
}
}
}
trace(6, 1) {
trace(5, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -298,7 +289,7 @@ class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
.withId("b")
.build())
template.refresh(indexName)
TEST_WRITER.waitForTraces(6)
TEST_WRITER.waitForTraces(5)
TEST_WRITER.clear()
and:

View File

@ -59,9 +59,6 @@ public class Elasticsearch2TransportClientInstrumentation extends Instrumenter.D
"com.google.common.base.Joiner$1",
"com.google.common.base.Joiner$2",
"com.google.common.base.Joiner$MapJoiner",
"io.opentelemetry.auto.decorator.BaseDecorator",
"io.opentelemetry.auto.decorator.ClientDecorator",
"io.opentelemetry.auto.decorator.DatabaseClientDecorator",
"io.opentelemetry.auto.instrumentation.elasticsearch.ElasticsearchTransportClientDecorator",
packageName + ".TransportActionListener",
};

View File

@ -177,15 +177,7 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
result.index == indexName
and:
assertTraces(6) {
sortTraces {
// IndexAction and PutMappingAction run in separate threads and so their order is not always the same
if (traces[3][0].attributes[MoreTags.RESOURCE_NAME].stringValue == "IndexAction") {
def tmp = traces[3]
traces[3] = traces[4]
traces[4] = tmp
}
}
assertTraces(5) {
trace(0, 1) {
span(0) {
operationName "elasticsearch.query"
@ -239,23 +231,7 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
}
}
}
trace(3, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(4, 1) {
trace(3, 2) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -274,8 +250,23 @@ class Elasticsearch2NodeClientTest extends AgentTestRunner {
"elasticsearch.request.write.type" indexType
}
}
span(1) {
operationName "elasticsearch.query"
spanKind CLIENT
childOf span(0)
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(5, 1) {
trace(4, 1) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT

View File

@ -83,13 +83,8 @@ class Elasticsearch2SpringRepositoryTest extends AgentTestRunner {
repo.index(doc) == doc
and:
def excludes = {
// sometimes PutMappingAction is present and sometimes it is not
// (only seems to happen with Elasticsearch 2.x, later versions seem to always have PutMappingAction)
it[0].attributes[MoreTags.RESOURCE_NAME].stringValue == "PutMappingAction"
}
assertTracesWithFilter(2, excludes) {
trace(0, 1) {
assertTraces(2) {
trace(0, 2) {
span(0) {
operationName "elasticsearch.query"
spanKind CLIENT
@ -108,6 +103,21 @@ class Elasticsearch2SpringRepositoryTest extends AgentTestRunner {
"elasticsearch.request.write.type" "doc"
}
}
span(1) {
operationName "elasticsearch.query"
spanKind CLIENT
childOf span(0)
tags {
"$MoreTags.SERVICE_NAME" "elasticsearch"
"$MoreTags.RESOURCE_NAME" "PutMappingAction"
"$MoreTags.SPAN_TYPE" SpanTypes.ELASTICSEARCH
"$Tags.COMPONENT" "elasticsearch-java"
"$Tags.DB_TYPE" "elasticsearch"
"elasticsearch.action" "PutMappingAction"
"elasticsearch.request" "PutMappingRequest"
"elasticsearch.request.indices" indexName
}
}
}
trace(1, 1) {
span(0) {

Some files were not shown because too many files have changed in this diff Show More