Merge tag 'v0.46.0' into dd-merge
This commit is contained in:
commit
2298885678
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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() {}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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: '+'
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: '+'
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: '+'
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"() {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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)}" }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue