The AWS Documentation for AWS X-Ray currently doesn't give any solutions for Java projects that do not use Tomcat JDBC.
In order to instrument database queries using spring-boot-data-jpa
, you need to also include Tomcat JDBC as a dependency, and set up a Tomcat DataSource object along with your Hikari one, and include the XRay interceptor as a JDBC interceptor by either:
- Adding it in your config using:
dataSource.setJdbcInterceptors("com.amazonaws.xray.sql.postgres.TracingInterceptor;");
- As a property:
spring.datasource.jdbc-interceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor
Gradle:
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation "com.amazonaws:aws-java-sdk-core"
implementation "com.amazonaws:aws-xray-recorder-sdk-core" // Required for core xray features
implementation "com.amazonaws:aws-xray-recorder-sdk-spring" // Required for spring annotations
implementation "com.amazonaws:aws-xray-recorder-sdk-sql-postgres" // required for db callouts
implementation 'org.apache.tomcat:tomcat-jdbc:9.0.31'
...
}
Database Configuration (Spring):
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
final org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setUsername(getUsername());
dataSource.setPassword(getPassword());
dataSource.setUrl(POSTGRES_URL_PREFIX
+ getHost()
+ ":" + getPort()
+ "/" + getName()
+ "?stringtype=unspecified");
dataSource.setDriverClassName(getDriver());
dataSource.setJdbcInterceptors("com.amazonaws.xray.sql.postgres.TracingInterceptor;");
final HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setDataSource(dataSource);
return hikariDataSource;
}
I find this quite clunky, and I would rather not have to have Tomcat JDBC as an additional dependency if possible.
Is there no way around this without using Tomcat?
Other notes:
Spring Boot 2.1.7
Gradle 6.0.1
AWS SDK for Java 2.4.0