I'm working with using Spring Boot for the first time and am setting up distributed tracing for my application. I've added Spring Cloud Slueth to my app and I could see the spans and traces being generated when my endpoints are being called, but I'm trouble getting it to integrate with Aws Sdk 2.x (using the Dynamo async client). I have a few questions about integrations:
- What is the best way to a trace http calls through the aws sdk. The only way I've been able to do it is to implement the ExecutionInterceptor and manually create a span:
@Component
@Log4j2
public class AwsExecutionInterceptor implements ExecutionInterceptor {
public static final String CLIENT_CALL_SPAN = "ClientCallSpan";
public static final ExecutionAttribute<Span> ATTRIBUTE = new ExecutionAttribute<>(
CLIENT_CALL_SPAN);
private final Tracer tracer;
@Autowired
public AwsExecutionInterceptor(Tracer tracer) {
this.tracer = tracer;
}
@Override
public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
Span clientCallSpan = this.tracer.nextSpan().name("clientCall").start();
log.info("Starting new span");
executionAttributes.putAttribute(ATTRIBUTE, clientCallSpan);
}
@Override
public void afterExecution(Context.AfterExecution context, ExecutionAttributes executionAttributes) {
Span span = executionAttributes.getAttribute(ATTRIBUTE);
span.end();
log.info("Span closed");
}
}
- Is there a way to get trace ids to propagate to the the logs from the netty threadpool that are logged via the aws sdk? I am providing an executor via the advanced options, but traces aren't propagated to logs from netty threads. Here is an example:
public class AwsExecutorConfig {
@Bean("AwsClientExecutor")
public Executor executor() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50,
10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10_000));
executor.allowCoreThreadTimeOut(true);
return executor;
}
}
@Autowired
public DynamoConfig(AwsExecutionInterceptor executionInterceptor,
@Qualifier("AwsClientExecutor") Executor executor) {
@Bean(destroyMethod = "close")
public DynamoDbAsyncClient dynamoDbAsyncClient() {
var builder = DynamoDbAsyncClient.builder();
builder.overrideConfiguration(
ClientOverrideConfiguration.builder()
.addExecutionInterceptor(executionInterceptor).build());
builder.asyncConfiguration(
b -> b.advancedOption(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR,
executor));
return builder.build();
}
}
With this, I can see logs like the following from the sdk,
2021-07-20 10:26:04.369 DEBUG [,c9ae653fd2254266,c9ae653fd2254266] 2873 --- [pool-2-thread-5] s.a.a.m.internal.DefaultMetricCollector : Collected metrics records: MetricCollection(...)
but other logs don't have any traces, for example:
2021-07-20 10:26:04.360 DEBUG [,,] 2873 --- [tyEventLoop-0-2] software.amazon.awssdk.request : Received successful response: 200
2021-07-20 10:26:04.361 TRACE [,,] 2873 --- [tyEventLoop-0-2] software.amazon.awssdk.request : Parsing service response JSON.
2021-07-20 10:26:04.361 DEBUG [,,] 2873 --- [tyEventLoop-0-2] software.amazon.awssdk.requestId : x-amzn-RequestId : af0d9968-3202-480f-9e3c-8312ae6963c8
2021-07-20 10:26:04.361 DEBUG [,,] 2873 --- [tyEventLoop-0-2] software.amazon.awssdk.requestId : x-amz-id-2 : not available
2021-07-20 10:26:04.367 TRACE [,,] 2873 --- [tyEventLoop-0-2] software.amazon.awssdk.request : Done parsing service response.
The spring cloud sleuth docs mention integration with the Netty Http client, but I'm not sure how to do this with the AWS SDK. Any help with this would be greatly appreciated