Skip to content

Commit

Permalink
Improve resource naming for spring data repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
amarziali committed Dec 15, 2022
1 parent c99feac commit bec4940
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import java.lang.reflect.Method
import java.lang.reflect.Proxy

import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
import static datadog.trace.api.config.TraceInstrumentationConfig.SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan

@Retry(count = 3, delay = 1000, mode = Retry.Mode.SETUP_FEATURE_CLEANUP)
Expand Down Expand Up @@ -74,7 +75,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {

def "test empty repo"() {
setup:

injectSysConfig(SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME, "false")
when:
def result = repo.findAll()

Expand Down Expand Up @@ -135,7 +136,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {
sortSpansByStart()
trace(3) {
span {
resourceName "ElasticsearchRepository.index"
resourceName "DocRepository.index"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down Expand Up @@ -210,7 +211,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {
sortSpansByStart()
trace(2) {
span {
resourceName "CrudRepository.findById"
resourceName "DocRepository.findById"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down Expand Up @@ -254,7 +255,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {
sortSpansByStart()
trace(3) {
span {
resourceName "ElasticsearchRepository.index"
resourceName "DocRepository.index"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down Expand Up @@ -304,7 +305,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {
}
trace(2) {
span {
resourceName "CrudRepository.findById"
resourceName "DocRepository.findById"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down Expand Up @@ -347,7 +348,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {
sortSpansByStart()
trace(3) {
span {
resourceName "CrudRepository.deleteById"
resourceName "DocRepository.deleteById"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down Expand Up @@ -397,7 +398,7 @@ class Elasticsearch53SpringRepositoryTest extends AgentTestRunner {

trace(2) {
span {
resourceName "CrudRepository.findAll"
resourceName "DocRepository.findAll"
operationName "repository.operation"
tags {
"$Tags.COMPONENT" "spring-data"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ public final class InterceptingRepositoryProxyPostProcessor
@Override
public void postProcess(
final ProxyFactory factory, final RepositoryInformation repositoryInformation) {
factory.addAdvice(0, RepositoryInterceptor.INSTANCE);
factory.addAdvice(0, new RepositoryInterceptor(repositoryInformation.getRepositoryInterface()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
import org.springframework.data.repository.Repository;

final class RepositoryInterceptor implements MethodInterceptor {
public static final MethodInterceptor INSTANCE = new RepositoryInterceptor();
private final Class<?> repositoryInterface;

private RepositoryInterceptor() {}
RepositoryInterceptor(Class<?> repositoryInterface) {
this.repositoryInterface = repositoryInterface;
}

@Override
public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
Expand All @@ -31,7 +33,7 @@ public Object invoke(final MethodInvocation methodInvocation) throws Throwable {

final AgentSpan span = startSpan(REPOSITORY_OPERATION);
DECORATOR.afterStart(span);
DECORATOR.onOperation(span, invokedMethod);
DECORATOR.onOperation(span, invokedMethod, repositoryInterface);

final AgentScope scope = activateSpan(span);
scope.setAsyncPropagation(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

package datadog.trace.instrumentation.springdata;

import datadog.trace.api.Config;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
import datadog.trace.bootstrap.instrumentation.decorator.ClientDecorator;
import java.lang.reflect.Method;
import javax.annotation.Nullable;

public final class SpringDataDecorator extends ClientDecorator {
public static final CharSequence REPOSITORY_OPERATION =
UTF8BytesString.create("repository.operation");
public static final CharSequence SPRING_DATA = UTF8BytesString.create("spring-data");
public static final SpringDataDecorator DECORATOR = new SpringDataDecorator();

private SpringDataDecorator() {}

@Override
protected String service() {
return null;
Expand All @@ -35,13 +35,14 @@ protected CharSequence component() {
return SPRING_DATA;
}

public AgentSpan onOperation(final AgentSpan span, final Method method) {
public void onOperation(
final AgentSpan span, final Method method, @Nullable final Class<?> repositoryIntf) {
assert span != null;
assert method != null;

if (method != null) {
if (repositoryIntf != null && Config.get().isSpringDataRepositoryInterfaceResourceName()) {
span.setResourceName(spanNameForMethod(repositoryIntf, method));
} else {
span.setResourceName(spanNameForMethod(method));
}
return span;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file includes software developed at SignalFx

import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.config.TraceInstrumentationConfig
import datadog.trace.bootstrap.instrumentation.api.Tags
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import spring.jpa.JpaCustomer
Expand Down Expand Up @@ -51,6 +52,7 @@ class SpringJpaTest extends AgentTestRunner {
TEST_WRITER.clear()

setup:
injectSysConfig(TraceInstrumentationConfig.SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME, useEnhancedNaming)
def customer = new JpaCustomer("Bob", "Anonymous")

expect:
Expand All @@ -61,7 +63,7 @@ class SpringJpaTest extends AgentTestRunner {
trace(2) {
span {
operationName "repository.operation"
resourceName "JpaRepository.findAll"
resourceName "${intfName}.findAll"
errored false
measured true
tags {
Expand Down Expand Up @@ -100,7 +102,7 @@ class SpringJpaTest extends AgentTestRunner {
trace(2) {
span {
operationName "repository.operation"
resourceName "CrudRepository.save"
resourceName "${intfName}.save"
errored false
measured true
tags {
Expand Down Expand Up @@ -139,7 +141,7 @@ class SpringJpaTest extends AgentTestRunner {
trace(3) {
span {
operationName "repository.operation"
resourceName "CrudRepository.save"
resourceName "${intfName}.save"
errored false
measured true
tags {
Expand Down Expand Up @@ -227,7 +229,7 @@ class SpringJpaTest extends AgentTestRunner {
trace(3) {
span {
operationName "repository.operation"
resourceName "CrudRepository.delete"
resourceName "${intfName}.delete"
errored false
measured true
tags {
Expand Down Expand Up @@ -269,5 +271,9 @@ class SpringJpaTest extends AgentTestRunner {
}
}
TEST_WRITER.clear()
where:
useEnhancedNaming | intfName
"true" | "JpaCustomerRepository"
"false" | "CrudRepository"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
package spring.jpa;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;

public interface JpaCustomerRepository extends JpaRepository<JpaCustomer, Long> {
public interface JpaCustomerRepository extends CrudRepository<JpaCustomer, Long> {
List<JpaCustomer> findByLastName(String lastName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SpringBootWebfluxIntegrationTest extends AbstractServerSmokeTest {
protected Set<String> expectedTraces() {
return [
"\\[netty\\.request:GET /fruits/\\{name}\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:CrudRepository\\.findAll\\[h2.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findAll\\[h2.query:.*",
Pattern.quote("[netty.request:GET /hello[WebController.hello:WebController.hello]]")
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SpringBootWebmvcIntegrationTest extends AbstractServerSmokeTest {
@Override
protected Set<String> expectedTraces() {
return [
"\\[servlet\\.request:GET /fruits\\[spring\\.handler:FruitController\\.listFruits\\[repository\\.operation:CrudRepository\\.findAll\\[h2\\.query:.*",
"\\[servlet\\.request:GET /fruits\\[spring\\.handler:FruitController\\.listFruits\\[repository\\.operation:FruitRepository\\.findAll\\[h2\\.query:.*",
"\\[servlet\\.request:GET /fruits/\\{name}\\[spring\\.handler:FruitController\\.findOneFruit\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SpringBootWebfluxIntegrationTest extends AbstractServerSmokeTest {
protected Set<String> expectedTraces() {
return [
"\\[netty\\.request:GET /fruits/\\{name}\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:CrudRepository\\.findAll\\[h2.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findAll\\[h2.query:.*",
Pattern.quote("[netty.request:GET /hello[WebController.hello:WebController.hello]]")
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SpringBootWebfluxIntegrationTest extends AbstractServerSmokeTest {
protected Set<String> expectedTraces() {
return [
"\\[netty\\.request:GET /fruits/\\{name}\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:CrudRepository\\.findAll\\[h2.query:.*",
"\\[netty\\.request:GET /fruits\\[FruitRouter\\.lambda:FruitRouter\\.lambda]\\[repository\\.operation:FruitRepository\\.findAll\\[h2.query:.*",
Pattern.quote("[netty.request:GET /hello[WebController.hello:WebController.hello]]")
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class SpringBootWebmvcIntegrationTest extends AbstractServerSmokeTest {
@Override
protected Set<String> expectedTraces() {
return [
"\\[servlet\\.request:GET /fruits\\[repository\\.operation:CrudRepository\\.findAll\\[h2\\.query:.*",
"\\[servlet\\.request:GET /fruits\\[repository\\.operation:FruitRepository\\.findAll\\[h2\\.query:.*",
//FIXME: it should rather be
//"\\[servlet\\.request:GET /fruits\\[spring\\.handler:FruitController\\.listFruits\\[repository\\.operation:CrudRepository\\.findAll\\[h2\\.query:.*",
//"\\[servlet\\.request:GET /fruits\\[spring\\.handler:FruitController\\.listFruits\\[repository\\.operation:FruitRepository\\.findAll\\[h2\\.query:.*",
"\\[servlet\\.request:GET /fruits/banana\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*"
//FIXME: it should rather be:
// "\\[servlet\\.request:GET /fruits/\\{name}\\[spring\\.handler:FruitController\\.findOneFruit\\[repository\\.operation:FruitRepository\\.findByName\\[h2\\.query:.*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public final class TraceInstrumentationConfig {
public static final String SERVLET_ROOT_CONTEXT_SERVICE_NAME =
"trace.servlet.root-context.service.name";

public static final String SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME =
"spring-data.repository.interface.resource-name";

public static final String RESOLVER_CACHE_CONFIG = "resolver.cache.config";
public static final String RESOLVER_USE_LOADCLASS = "resolver.use.loadclass";
public static final String RESOLVER_RESET_INTERVAL = "resolver.reset.interval";
Expand Down
10 changes: 10 additions & 0 deletions internal-api/src/main/java/datadog/trace/api/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
import static datadog.trace.api.config.TraceInstrumentationConfig.SERVLET_ASYNC_TIMEOUT_ERROR;
import static datadog.trace.api.config.TraceInstrumentationConfig.SERVLET_PRINCIPAL_ENABLED;
import static datadog.trace.api.config.TraceInstrumentationConfig.SERVLET_ROOT_CONTEXT_SERVICE_NAME;
import static datadog.trace.api.config.TraceInstrumentationConfig.SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME;
import static datadog.trace.api.config.TracerConfig.AGENT_HOST;
import static datadog.trace.api.config.TracerConfig.AGENT_NAMED_PIPE;
import static datadog.trace.api.config.TracerConfig.AGENT_PORT_LEGACY;
Expand Down Expand Up @@ -561,6 +562,8 @@ static class HostNameHolder {
private final boolean servletPrincipalEnabled;
private final boolean servletAsyncTimeoutError;

private final boolean springDataRepositoryInterfaceResourceName;

private final int xDatadogTagsMaxLength;

private final boolean traceAgentV05Enabled;
Expand Down Expand Up @@ -837,6 +840,9 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins

splitByTags = tryMakeImmutableSet(configProvider.getList(SPLIT_BY_TAGS));

springDataRepositoryInterfaceResourceName =
configProvider.getBoolean(SPRING_DATA_REPOSITORY_INTERFACE_RESOURCE_NAME, true);

scopeDepthLimit = configProvider.getInteger(SCOPE_DEPTH_LIMIT, DEFAULT_SCOPE_DEPTH_LIMIT);

scopeStrictMode = configProvider.getBoolean(SCOPE_STRICT_MODE, false);
Expand Down Expand Up @@ -1976,6 +1982,10 @@ public boolean isServletPrincipalEnabled() {
return servletPrincipalEnabled;
}

public boolean isSpringDataRepositoryInterfaceResourceName() {
return springDataRepositoryInterfaceResourceName;
}

public int getxDatadogTagsMaxLength() {
return xDatadogTagsMaxLength;
}
Expand Down

0 comments on commit bec4940

Please sign in to comment.