Migrate base decorators to new agent api

This commit is contained in:
Trask Stalnaker 2019-10-19 11:20:54 -07:00
parent d635e6d8a9
commit f67e3b98db
15 changed files with 344 additions and 38 deletions

View File

@ -2,6 +2,8 @@ apply from: "${rootDir}/gradle/java.gradle"
minimumBranchCoverage = 0.6
excludedClassesCoverage += ['datadog.trace.agent.tooling.*']
// this exclusion is temporary, until deprecated methods are removed (see subsequent commit)
excludedClassesCoverage += ['datadog.trace.agent.decorator.*']
configurations {
// classpath used by the instrumentation muzzle plugin

View File

@ -5,6 +5,8 @@ import static java.util.Collections.singletonMap;
import datadog.trace.api.Config;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentScope;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
@ -23,7 +25,7 @@ public abstract class BaseDecorator {
protected final float traceAnalyticsSampleRate;
protected BaseDecorator() {
Config config = Config.get();
final Config config = Config.get();
final String[] instrumentationNames = instrumentationNames();
traceAnalyticsEnabled =
instrumentationNames.length > 0
@ -42,12 +44,20 @@ public abstract class BaseDecorator {
return false;
}
@Deprecated
public Scope afterStart(final Scope scope) {
assert scope != null;
afterStart(scope.span());
return scope;
}
public AgentScope afterStart(final AgentScope scope) {
assert scope != null;
afterStart(scope.span());
return scope;
}
@Deprecated
public Span afterStart(final Span span) {
assert span != null;
if (spanType() != null) {
@ -60,23 +70,56 @@ public abstract class BaseDecorator {
return span;
}
public AgentSpan afterStart(final AgentSpan span) {
assert span != null;
if (spanType() != null) {
span.setTag(DDTags.SPAN_TYPE, spanType());
}
span.setTag(Tags.COMPONENT.getKey(), component());
if (traceAnalyticsEnabled) {
span.setTag(DDTags.ANALYTICS_SAMPLE_RATE, traceAnalyticsSampleRate);
}
return span;
}
@Deprecated
public Scope beforeFinish(final Scope scope) {
assert scope != null;
beforeFinish(scope.span());
return scope;
}
public AgentScope beforeFinish(final AgentScope scope) {
assert scope != null;
beforeFinish(scope.span());
return scope;
}
@Deprecated
public Span beforeFinish(final Span span) {
assert span != null;
return span;
}
public AgentSpan beforeFinish(final AgentSpan span) {
assert span != null;
return span;
}
@Deprecated
public Scope onError(final Scope scope, final Throwable throwable) {
assert scope != null;
onError(scope.span(), throwable);
return scope;
}
public AgentScope onError(final AgentScope scope, final Throwable throwable) {
assert scope != null;
onError(scope.span(), throwable);
return scope;
}
@Deprecated
public Span onError(final Span span, final Throwable throwable) {
assert span != null;
if (throwable != null) {
@ -89,6 +132,16 @@ public abstract class BaseDecorator {
return span;
}
public AgentSpan onError(final AgentSpan span, final Throwable throwable) {
assert span != null;
if (throwable != null) {
span.setError(true);
span.addThrowable(throwable instanceof ExecutionException ? throwable.getCause() : throwable);
}
return span;
}
@Deprecated
public Span onPeerConnection(final Span span, final InetSocketAddress remoteConnection) {
assert span != null;
if (remoteConnection != null) {
@ -100,6 +153,19 @@ public abstract class BaseDecorator {
return span;
}
public AgentSpan onPeerConnection(
final AgentSpan span, final InetSocketAddress remoteConnection) {
assert span != null;
if (remoteConnection != null) {
onPeerConnection(span, remoteConnection.getAddress());
span.setTag(Tags.PEER_HOSTNAME.getKey(), remoteConnection.getHostName());
span.setTag(Tags.PEER_PORT.getKey(), remoteConnection.getPort());
}
return span;
}
@Deprecated
public Span onPeerConnection(final Span span, final InetAddress remoteAddress) {
assert span != null;
if (remoteAddress != null) {
@ -113,6 +179,19 @@ public abstract class BaseDecorator {
return span;
}
public AgentSpan onPeerConnection(final AgentSpan span, final InetAddress remoteAddress) {
assert span != null;
if (remoteAddress != null) {
span.setTag(Tags.PEER_HOSTNAME.getKey(), remoteAddress.getHostName());
if (remoteAddress instanceof Inet4Address) {
span.setTag(Tags.PEER_HOST_IPV4.getKey(), remoteAddress.getHostAddress());
} else if (remoteAddress instanceof Inet6Address) {
span.setTag(Tags.PEER_HOST_IPV6.getKey(), remoteAddress.getHostAddress());
}
}
return span;
}
/**
* This method is used to generate an acceptable span (operation) name based on a given method
* reference. Anonymous classes are named based on their parent.

View File

@ -1,6 +1,7 @@
package datadog.trace.agent.decorator;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
@ -21,4 +22,14 @@ public abstract class ClientDecorator extends BaseDecorator {
Tags.SPAN_KIND.set(span, spanKind());
return super.afterStart(span);
}
@Override
public AgentSpan afterStart(final AgentSpan span) {
assert span != null;
if (service() != null) {
span.setTag(DDTags.SERVICE_NAME, service());
}
span.setTag(Tags.SPAN_KIND.getKey(), spanKind());
return super.afterStart(span);
}
}

View File

@ -2,6 +2,7 @@ package datadog.trace.agent.decorator;
import datadog.trace.api.Config;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
@ -13,6 +14,7 @@ public abstract class DatabaseClientDecorator<CONNECTION> extends ClientDecorato
protected abstract String dbInstance(CONNECTION connection);
@Deprecated
@Override
public Span afterStart(final Span span) {
assert span != null;
@ -20,6 +22,13 @@ public abstract class DatabaseClientDecorator<CONNECTION> extends ClientDecorato
return super.afterStart(span);
}
@Override
public AgentSpan afterStart(final AgentSpan span) {
assert span != null;
span.setTag(Tags.DB_TYPE.getKey(), dbType());
return super.afterStart(span);
}
/**
* This should be called when the connection is being used, not when it's created.
*
@ -27,6 +36,7 @@ public abstract class DatabaseClientDecorator<CONNECTION> extends ClientDecorato
* @param connection
* @return
*/
@Deprecated
public Span onConnection(final Span span, final CONNECTION connection) {
assert span != null;
if (connection != null) {
@ -41,9 +51,37 @@ public abstract class DatabaseClientDecorator<CONNECTION> extends ClientDecorato
return span;
}
/**
* This should be called when the connection is being used, not when it's created.
*
* @param span
* @param connection
* @return
*/
public AgentSpan onConnection(final AgentSpan span, final CONNECTION connection) {
assert span != null;
if (connection != null) {
span.setTag(Tags.DB_USER.getKey(), dbUser(connection));
final String instanceName = dbInstance(connection);
span.setTag(Tags.DB_INSTANCE.getKey(), instanceName);
if (instanceName != null && Config.get().isDbClientSplitByInstance()) {
span.setTag(DDTags.SERVICE_NAME, instanceName);
}
}
return span;
}
@Deprecated
public Span onStatement(final Span span, final String statement) {
assert span != null;
Tags.DB_STATEMENT.set(span, statement);
return span;
}
public AgentSpan onStatement(final AgentSpan span, final String statement) {
assert span != null;
span.setTag(Tags.DB_STATEMENT.getKey(), statement);
return span;
}
}

View File

@ -3,6 +3,7 @@ package datadog.trace.agent.decorator;
import datadog.trace.api.Config;
import datadog.trace.api.DDSpanTypes;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import java.net.URI;
@ -32,6 +33,7 @@ public abstract class HttpClientDecorator<REQUEST, RESPONSE> extends ClientDecor
return null;
}
@Deprecated
public Span onRequest(final Span span, final REQUEST request) {
assert span != null;
if (request != null) {
@ -83,6 +85,60 @@ public abstract class HttpClientDecorator<REQUEST, RESPONSE> extends ClientDecor
return span;
}
public AgentSpan onRequest(final AgentSpan span, final REQUEST request) {
assert span != null;
if (request != null) {
span.setTag(Tags.HTTP_METHOD.getKey(), method(request));
// Copy of HttpServerDecorator url handling
try {
final URI url = url(request);
if (url != null) {
final StringBuilder urlNoParams = new StringBuilder();
if (url.getScheme() != null) {
urlNoParams.append(url.getScheme());
urlNoParams.append("://");
}
if (url.getHost() != null) {
urlNoParams.append(url.getHost());
if (url.getPort() > 0 && url.getPort() != 80 && url.getPort() != 443) {
urlNoParams.append(":");
urlNoParams.append(url.getPort());
}
}
final String path = url.getPath();
if (path.isEmpty()) {
urlNoParams.append("/");
} else {
urlNoParams.append(path);
}
span.setTag(Tags.HTTP_URL.getKey(), urlNoParams.toString());
if (Config.get().isHttpClientTagQueryString()) {
span.setTag(DDTags.HTTP_QUERY, url.getQuery());
span.setTag(DDTags.HTTP_FRAGMENT, url.getFragment());
}
}
} catch (final Exception e) {
log.debug("Error tagging url", e);
}
span.setTag(Tags.PEER_HOSTNAME.getKey(), hostname(request));
final Integer port = port(request);
// Negative or Zero ports might represent an unset/null value for an int type. Skip setting.
if (port != null && port > 0) {
span.setTag(Tags.PEER_PORT.getKey(), port);
}
if (Config.get().isHttpClientSplitByDomain()) {
span.setTag(DDTags.SERVICE_NAME, hostname(request));
}
}
return span;
}
@Deprecated
public Span onResponse(final Span span, final RESPONSE response) {
assert span != null;
if (response != null) {
@ -97,4 +153,19 @@ public abstract class HttpClientDecorator<REQUEST, RESPONSE> extends ClientDecor
}
return span;
}
public AgentSpan onResponse(final AgentSpan span, final RESPONSE response) {
assert span != null;
if (response != null) {
final Integer status = status(response);
if (status != null) {
span.setTag(Tags.HTTP_STATUS.getKey(), status);
if (Config.get().getHttpClientErrorStatuses().contains(status)) {
span.setError(true);
}
}
}
return span;
}
}

View File

@ -3,6 +3,7 @@ package datadog.trace.agent.decorator;
import datadog.trace.api.Config;
import datadog.trace.api.DDSpanTypes;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import java.net.URI;
@ -41,6 +42,7 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE> extends
return Config.get().isTraceAnalyticsEnabled();
}
@Deprecated
public Span onRequest(final Span span, final REQUEST request) {
assert span != null;
if (request != null) {
@ -84,6 +86,50 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE> extends
return span;
}
public AgentSpan onRequest(final AgentSpan span, final REQUEST request) {
assert span != null;
if (request != null) {
span.setTag(Tags.HTTP_METHOD.getKey(), method(request));
// Copy of HttpClientDecorator url handling
try {
final URI url = url(request);
if (url != null) {
final StringBuilder urlNoParams = new StringBuilder();
if (url.getScheme() != null) {
urlNoParams.append(url.getScheme());
urlNoParams.append("://");
}
if (url.getHost() != null) {
urlNoParams.append(url.getHost());
if (url.getPort() > 0 && url.getPort() != 80 && url.getPort() != 443) {
urlNoParams.append(":");
urlNoParams.append(url.getPort());
}
}
final String path = url.getPath();
if (path.isEmpty()) {
urlNoParams.append("/");
} else {
urlNoParams.append(path);
}
span.setTag(Tags.HTTP_URL.getKey(), urlNoParams.toString());
if (Config.get().isHttpServerTagQueryString()) {
span.setTag(DDTags.HTTP_QUERY, url.getQuery());
span.setTag(DDTags.HTTP_FRAGMENT, url.getFragment());
}
}
} catch (final Exception e) {
log.debug("Error tagging url", e);
}
// TODO set resource name from URL.
}
return span;
}
@Deprecated
public Span onConnection(final Span span, final CONNECTION connection) {
assert span != null;
if (connection != null) {
@ -103,6 +149,28 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE> extends
return span;
}
public AgentSpan onConnection(final AgentSpan span, final CONNECTION connection) {
assert span != null;
if (connection != null) {
span.setTag(Tags.PEER_HOSTNAME.getKey(), peerHostname(connection));
final String ip = peerHostIP(connection);
if (ip != null) {
if (VALID_IPV4_ADDRESS.matcher(ip).matches()) {
span.setTag(Tags.PEER_HOST_IPV4.getKey(), ip);
} else if (ip.contains(":")) {
span.setTag(Tags.PEER_HOST_IPV6.getKey(), ip);
}
}
final Integer port = peerPort(connection);
// Negative or Zero ports might represent an unset/null value for an int type. Skip setting.
if (port != null && port > 0) {
span.setTag(Tags.PEER_PORT.getKey(), port);
}
}
return span;
}
@Deprecated
public Span onResponse(final Span span, final RESPONSE response) {
assert span != null;
if (response != null) {
@ -118,6 +186,21 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE> extends
return span;
}
public AgentSpan onResponse(final AgentSpan span, final RESPONSE response) {
assert span != null;
if (response != null) {
final Integer status = status(response);
if (status != null) {
span.setTag(Tags.HTTP_STATUS.getKey(), status);
if (Config.get().getHttpServerErrorStatuses().contains(status)) {
span.setError(true);
}
}
}
return span;
}
// @Override
// public Span onError(final Span span, final Throwable throwable) {
// assert span != null;

View File

@ -1,12 +1,14 @@
package datadog.trace.agent.decorator;
import datadog.trace.api.DDTags;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
public abstract class OrmClientDecorator extends DatabaseClientDecorator {
public abstract String entityName(final Object entity);
@Deprecated
public Span onOperation(final Span span, final Object entity) {
assert span != null;
@ -18,4 +20,16 @@ public abstract class OrmClientDecorator extends DatabaseClientDecorator {
}
return span;
}
public AgentSpan onOperation(final AgentSpan span, final Object entity) {
assert span != null;
if (entity != null) {
final String name = entityName(entity);
if (name != null) {
span.setTag(DDTags.RESOURCE_NAME, name);
} // else we keep any existing resource.
}
return span;
}
}

View File

@ -1,11 +1,13 @@
package datadog.trace.agent.decorator;
import datadog.trace.api.Config;
import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
public abstract class ServerDecorator extends BaseDecorator {
@Deprecated
@Override
public Span afterStart(final Span span) {
assert span != null;
@ -13,4 +15,12 @@ public abstract class ServerDecorator extends BaseDecorator {
span.setTag(Config.LANGUAGE_TAG_KEY, Config.LANGUAGE_TAG_VALUE);
return super.afterStart(span);
}
@Override
public AgentSpan afterStart(final AgentSpan span) {
assert span != null;
span.setTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER);
span.setTag(Config.LANGUAGE_TAG_KEY, Config.LANGUAGE_TAG_VALUE);
return super.afterStart(span);
}
}

View File

@ -2,20 +2,18 @@ package datadog.trace.agent.decorator
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.DDTags
import datadog.trace.instrumentation.api.AgentScope
import datadog.trace.instrumentation.api.AgentSpan
import datadog.trace.util.test.DDSpecification
import io.opentracing.Scope
import io.opentracing.Span
import io.opentracing.tag.Tags
import spock.lang.Shared
import static io.opentracing.log.Fields.ERROR_OBJECT
class BaseDecoratorTest extends DDSpecification {
@Shared
def decorator = newDecorator()
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test afterStart"() {
when:
@ -60,8 +58,8 @@ class BaseDecoratorTest extends DDSpecification {
then:
if (error) {
1 * span.setTag(Tags.ERROR.key, true)
1 * span.log([(ERROR_OBJECT): error])
1 * span.setError(true)
1 * span.addThrowable(error)
}
0 * _
@ -79,25 +77,25 @@ class BaseDecoratorTest extends DDSpecification {
def "test assert null span"() {
when:
decorator.afterStart((Span) null)
decorator.afterStart((AgentSpan) null)
then:
thrown(AssertionError)
when:
decorator.onError((Span) null, null)
decorator.onError((AgentSpan) null, null)
then:
thrown(AssertionError)
when:
decorator.onPeerConnection((Span) null, null)
decorator.onError((AgentSpan) null, null)
then:
thrown(AssertionError)
when:
decorator.beforeFinish((Span) null)
decorator.onPeerConnection((AgentSpan) null, null)
then:
thrown(AssertionError)
@ -105,19 +103,19 @@ class BaseDecoratorTest extends DDSpecification {
def "test assert null scope"() {
when:
decorator.afterStart((Scope) null)
decorator.onError((AgentScope) null, null)
then:
thrown(AssertionError)
when:
decorator.onError((Scope) null, null)
decorator.onError((AgentScope) null, null)
then:
thrown(AssertionError)
when:
decorator.beforeFinish((Scope) null)
decorator.beforeFinish((AgentScope) null)
then:
thrown(AssertionError)
@ -125,8 +123,8 @@ class BaseDecoratorTest extends DDSpecification {
def "test assert non-null scope"() {
setup:
def span = Mock(Span)
def scope = Mock(Scope)
def span = Mock(AgentSpan)
def scope = Mock(AgentScope)
when:
decorator.afterStart(scope)

View File

@ -1,12 +1,12 @@
package datadog.trace.agent.decorator
import datadog.trace.api.DDTags
import io.opentracing.Span
import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.tag.Tags
class ClientDecoratorTest extends BaseDecoratorTest {
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test afterStart"() {
setup:

View File

@ -2,14 +2,14 @@ package datadog.trace.agent.decorator
import datadog.trace.api.Config
import datadog.trace.api.DDTags
import io.opentracing.Span
import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.tag.Tags
import static datadog.trace.agent.test.utils.ConfigUtils.withConfigOverride
class DatabaseClientDecoratorTest extends ClientDecoratorTest {
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test afterStart"() {
setup:
@ -83,19 +83,19 @@ class DatabaseClientDecoratorTest extends ClientDecoratorTest {
def decorator = newDecorator()
when:
decorator.afterStart((Span) null)
decorator.afterStart((AgentSpan) null)
then:
thrown(AssertionError)
when:
decorator.onConnection(null, null)
decorator.onConnection((AgentSpan) null, null)
then:
thrown(AssertionError)
when:
decorator.onStatement(null, null)
decorator.onStatement((AgentSpan) null, null)
then:
thrown(AssertionError)

View File

@ -2,7 +2,7 @@ package datadog.trace.agent.decorator
import datadog.trace.api.Config
import datadog.trace.api.DDTags
import io.opentracing.Span
import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.tag.Tags
import spock.lang.Shared
@ -13,7 +13,7 @@ class HttpClientDecoratorTest extends ClientDecoratorTest {
@Shared
def testUrl = new URI("http://myhost/somepath")
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test onRequest"() {
setup:
@ -63,7 +63,6 @@ class HttpClientDecoratorTest extends ClientDecoratorTest {
}
1 * span.setTag(Tags.HTTP_METHOD.key, null)
1 * span.setTag(Tags.PEER_HOSTNAME.key, null)
1 * span.setTag(Tags.PEER_PORT.key, null)
0 * _
where:
@ -98,7 +97,7 @@ class HttpClientDecoratorTest extends ClientDecoratorTest {
1 * span.setTag(Tags.HTTP_STATUS.key, status)
}
if (error) {
1 * span.setTag(Tags.ERROR.key, true)
1 * span.setError(true)
}
0 * _
@ -121,13 +120,13 @@ class HttpClientDecoratorTest extends ClientDecoratorTest {
def decorator = newDecorator()
when:
decorator.onRequest(null, null)
decorator.onRequest((AgentSpan) null, null)
then:
thrown(AssertionError)
when:
decorator.onResponse(null, null)
decorator.onRequest((AgentSpan) null, null)
then:
thrown(AssertionError)

View File

@ -2,14 +2,14 @@ package datadog.trace.agent.decorator
import datadog.trace.api.Config
import datadog.trace.api.DDTags
import io.opentracing.Span
import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.tag.Tags
import static datadog.trace.agent.test.utils.ConfigUtils.withConfigOverride
class HttpServerDecoratorTest extends ServerDecoratorTest {
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test onRequest"() {
setup:
@ -115,7 +115,7 @@ class HttpServerDecoratorTest extends ServerDecoratorTest {
1 * span.setTag(Tags.HTTP_STATUS.key, status)
}
if (error) {
1 * span.setTag(Tags.ERROR.key, true)
1 * span.setError(true)
}
0 * _
@ -138,13 +138,13 @@ class HttpServerDecoratorTest extends ServerDecoratorTest {
def decorator = newDecorator()
when:
decorator.onRequest(null, null)
decorator.onRequest((AgentSpan) null, null)
then:
thrown(AssertionError)
when:
decorator.onResponse(null, null)
decorator.onRequest((AgentSpan) null, null)
then:
thrown(AssertionError)

View File

@ -1,6 +1,7 @@
package datadog.trace.agent.decorator
import datadog.trace.api.DDTags
import datadog.trace.instrumentation.api.AgentSpan
class OrmClientDecoratorTest extends DatabaseClientDecoratorTest {
@ -29,7 +30,7 @@ class OrmClientDecoratorTest extends DatabaseClientDecoratorTest {
decorator = newDecorator({ e -> null })
when:
decorator.onOperation(null, null)
decorator.onOperation((AgentSpan) null, null)
then:
thrown(AssertionError)

View File

@ -2,12 +2,12 @@ package datadog.trace.agent.decorator
import datadog.trace.api.Config
import datadog.trace.api.DDTags
import io.opentracing.Span
import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.tag.Tags
class ServerDecoratorTest extends BaseDecoratorTest {
def span = Mock(Span)
def span = Mock(AgentSpan)
def "test afterStart"() {
def decorator = newDecorator()