Send traces with spring-boot-sleuth to Datadog - spring-boot

I have spring-boot application and it has the next dependencies:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation "com.datadoghq:dd-java-agent:0.75.0"
annotationProcessor "com.datadoghq:dd-java-agent:0.75.0"
testImplementation 'org.springframework.boot:spring-boot-starter-test'}
bootRun {
jvmArgs = ["-javaagent:" + configurations.runtimeClasspath.files.find { f -> f.path.contains('dd-java-agent') }.path]
}
I execute Datadog agent in the container and configure it there(KEY, ENV).
When I use API from dd-trace (like datadog.trace.api.Trace), I can see traces in Datadog. But when I use sleuth API to create spans/tags/events I cant see traces.
Is it possible to use sleuth API to send traces to Datadog via Datadog agent? If yes, what do I need to do for it?

Spring Cloud Sleuth supports two tracing libraries:
Brave: the tracing lib of OpenZipkin (Sleuth uses this by default)
OpenTelemetry: you need to add Sleuth-OTel but it is in incubator so not recommended in production, also OpenTelemetry Java is still in alpha
There are a few things you can do:
It seems Datadog supports both of the above through the OTel collector: see the docs how to set it up
There is a zipkin to datadog proxy
There is a zipkin-datadog reporter
You can write your own for Sleuth, see: https://github.com/spring-cloud/spring-cloud-sleuth/issues/707
You can ask Datadog to add "native" support for the Zipkin format: https://github.com/DataDog/dd-trace-java/issues/351

Related

Fail to disable AWS SQS configuration Spring Cloud AQS Messaging 2.2.0

I have a Spring profile dbmigration that should not need the AWS SQS bean or configuration. However, I am not being able to disable this configuration when I run with this profile.
Those are the only dependencies I have in my project:
val awsSdkVersion = "1.12.131"
[...]
// SQS Dependencies
implementation("org.springframework.cloud:spring-cloud-aws-messaging:2.2.6.RELEASE")
implementation("com.amazonaws:aws-java-sdk-core:$awsSdkVersion")
implementation("com.amazonaws:aws-java-sdk-sts:$awsSdkVersion")
Here are some guides I tried to follow:
https://davidagood.com/disable-spring-cloud-aws/
Spring boot cannot start with aws starter dependency
Turning off Spring Boot AWS Autoconfiguration
Also, I think is important to know that my configuration files are:
application.yml
application-dbmigration.yml
And I tried to change the library to: org.springframework.cloud:spring-cloud-starter-aws-messaging:2.2.6.RELEASE, also no success
Even tried to update to another version of this library:
val awsSdkVersion = "1.12.131"
val springCloudAwsVersion = "2.3.1"
[...]
implementation("io.awspring.cloud:spring-cloud-aws-messaging:${springCloudAwsVersion}")
implementation("io.awspring.cloud:spring-cloud-aws-autoconfigure:${springCloudAwsVersion}")
implementation("com.amazonaws:aws-java-sdk-core:$awsSdkVersion")
implementation("com.amazonaws:aws-java-sdk-sts:$awsSdkVersion")
No success.
I would prefer to do it through the configurations and application settings, instead of having to add #Profile("!dbmigration") in every Bean or Component related to SQS on my code.

Spring cloud bus not updating config property for all instances

I am using spring cloud bus with kafka to update the config property for multiple instances at once.
I have a cloud-config server running on localhost:8888,
Find the below property for cloud config server :
server.port=8888
spring.application.name=clientServer
spring.cloud.config.server.default-label=master
spring.cloud.config.server.git.uri=https://github.com/kumawatanupriya/demo-cloud-config.git
management.endpoints.web.exposure.include=*
management.endpoint.env.post.enabled=true
spring.cloud.config.enabled=false
spring.cloud.bus.enabled=true
spring.cloud.stream.kafka.binder.brokers=localhost:9092
spring.cloud.stream.kafka.binder.zkNodes=localhost:2181
Find the below dependencies used for cloud config server :
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-bus-kafka'
implementation 'org.springframework.cloud:spring-cloud-config-server'
implementation 'org.springframework.cloud:spring-cloud-config-monitor'
I am running 3 instances of cloud-config-client on localhost:8080, 7011, 7012.
Find the below property for cloud config client :
spring.config.import=configserver:http://localhost:8888
management.endpoints.web.exposure.include=*
management.endpoint.env.post.enabled=true
spring.cloud.bus.enabled=true
spring.cloud.bus.refresh.enabled=true
spring.cloud.bus.env.enabled=true
endpoints.spring.cloud.bus.refresh.enabled=true
endpoints.spring.cloud.bus.env.enabled=true
spring.cloud.bus.trace.enabled=true
spring.cloud.stream.kafka.binder.autoAddPartitions=true
spring.cloud.stream.kafka.binder.brokers=localhost:9092
spring.cloud.stream.kafka.binder.zkNodes=localhost:2181
spring.profiles.active=test
Find the below dependencies used for config client :
implementation 'org.springframework.boot:spring-boot-starter-web'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-bus-kafka'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-stream'
implementation "org.springframework.cloud:spring-cloud-stream-binder-kafka"
I have a git repo with config file including property inventory.initial.mode.
When i update this property in github and hit this bus refresh endpoint localhost:8080/actuator/busrefresh. it only changes the value for one instances localhost:8080, it doesn't change it for 7011, 7012.
I tried hitting config-server refresh enpoint as well localhost:8888/actuator/busrefresh, but it also didn't update the value.
I added the monitor as well in config-server still it's not updating.
please help me identify the issue.
What am I doing wrong??

Integrating SpringCloudSleuth With AWS X-Ray

I've an ECS cluster running Fargate instances with Springboot apps & want to enable tracing with least number of code changes. There're the two approaches I started looking at:
Use AWS-Xray : Steps -> Add dependencies, add aWSXRayServletFilter, run X-Ray daemon in a separate container.
Use Spring Cloud Sleuth : Steps -> Add dependency & property, integrate with X-Ray
So the second approach saves you number of steps in modifying your code, the issues is I couldn't find any good doc to integrate Spring Cloud Sleuth with X-Ray, can anyone point me to correct direction?
I tried reading number of docs including: https://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html
I came across this when looking for a solution for option two. AFAIK, you still have to use the X-Ray daemon. I had to look across multiple GitHub repos and issues to solve the problem so am providing the solution here.
I used Gradle for my solution but this can be easily translated to Maven as well.
Add the BOM for spring cloud
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:2021.0.3")
}
}
Add the following dependencies to the project.
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
implementation 'org.springframework.cloud:spring-cloud-sleuth-zipkin'
implementation 'io.zipkin.aws:zipkin-reporter-xray-udp:0.23.4'
Then Add configuration to define the Bean which is used for reporting to the X-Ray daemon.
#Configuration
public class TracingConfiguration {
#Bean(ZipkinAutoConfiguration.REPORTER_BEAN_NAME)
Reporter<Span> reporter() {
return XRayUDPReporter.create();
}
}
Define the propagation type as aws for Sleuth as per the documentation.
spring.sleuth.propagation.type=aws
I haven't tried it yet, but from the documentation you can combine the following
An amazon/aws-xray-daemon
zipkin-aws with the experimental X-Ray Storage. They have a Docker image for zipkin-aws. You need to point it to the XRay daemon. This will be running as a Zipkin server listening on port 9411.
Then you use Spring Cloud Sleuth's instrumentation and AsyncZipkinSender.
By doing this approach, you can decouple yourself from AWS as long as you have a different zipkin server.
currently AWS X-Ray SDK doesn't have integration with Spring Cloud Sleuth. In order to using AWS X-Ray, the first approach would be the best way to do it.

Disable distributed tracing for development

We are setting up microservice framework.
We use following stack for distributed tracing.
Spring boot
Kafka
Zipkin
Following is how the configuration is done
In gradle.build (or pom.xml) following starter dependencies added
compile 'org.springframework.cloud:spring-cloud-starter-sleuth'
compile 'org.springframework.cloud:spring-cloud-sleuth-zipkin'
compile 'org.springframework.cloud:spring-cloud-starter-bus-kafka'
Add one AlwaysSampler bean
#Bean
public Sampler defaultSampler() {
return Sampler.ALWAYS_SAMPLE;
}
If we have kafka running, things work automatically.
But if kafka is not running, server does not start - this is mostly the case for development environment.
If I want to stop this, I have to comment out all the code mentioned here (as we use starter dependency with spring boot, it automatically configures as I understand).
Can we just make some changes in properties (or yaml) files so that I don't need to go and comment out all these code?
Or probably another way to disable this without doing some commenting, etc.
You can add the following setting on your properties key to disable zipkin, source.
spring.zipkin.enabled=false
Better yet, create separate development properties (like application-dev.properties) to avoid changing above setting everytime you want to run in your machine: https://stackoverflow.com/a/34846351/4504053

Configuring SpringBoot 2 application for Micrometer for AWS cloudwatch

I have a springboot 2 application, and I want to display metrics in AWS Cloudwatch.
I have included micrometer cloudwatch dependency in pom.
Here setting is documented for various metric systems but not cloudwatch.
Whar else configurations I need to do for cloudwatch?
First of all you may have to add some additional dependecies. I needed the following:
org.springframework.boot - spring-boot-starter-actuator
org.springframework.cloud - spring-cloud-starter-aws
io.micrometer - micrometer-core
io.micrometer - micrometer-registry-cloudwatch
Boot was not able to manage the versions for these dependencies except for actuator in my case, so you might have to figure out the right versions for you.
Firthermore some application properties have to be set:
# disable unwanted features to prevent autoconfigure which will produce errors and abort of application startup eventually
# alternatively you can try to configure those features correctly if you intend to use them
cloud.aws.stack.auto=false
# enable micrometer for cloudwatch (only where there is actually access to it)
management.metrics.export.cloudwatch.enabled=true
# set the namespace that will contain the metrics for this application
management.metrics.export.cloudwatch.namespace=test
# set max batch size to the actual maximum (if not a bug in certain versions of micrometer for cloudwatch will send
# batches that are too big)
management.metrics.export.cloudwatch.batchSize=20
The next step will be in AWS. The role associated with your EC2-instance (or whatever you are using) needs to have the permission CloudWatch:PutMetricData.
Using this configuration should enable CloudWatch-Monitoring for your Spring-Boot-Application.
One of the sources I encountered stated that you should use:
cloud.aws.credentials.instanceProfile=false
This will prevent Spring Boot from automatically obtaining credentials that are necessary to push metrics to CloudWatch. You could also provide own credentials another way, but I didn't try that.

Resources