- Technology stack: Java 8+, OpenTracing, JDBC
- Status: Under development and used in production
Why not opentracing-contrib/java-jdbc❓
- operation name not customizable
- span tags not customizable
java.sql.Driver
approach requiresGlobalTracer
- no support for
javax.sql.DataSource
DataSource dataSource = new DataSourceTracer(tracer)
.trace(originalDataSource);
- OpenTracing instrumentation for any
DataSource
- Customizable operation name
- Customizable span tags/logs
- Convention over configuration (i.e. meaningful default values)
- Java 8 or higher
- OpenTracing
- datasource-proxy
Add the following dependency to your project:
<dependency>
<groupId>org.zalando</groupId>
<artifactId>opentracing-jdbc</artifactId>
<version>${opentracing-jdbc.version}</version>
</dependency>
new DataSourceTracer(tracer)
.withOperationName(new CustomOperationName())
.withAdditionalSpanDecorator(new CustomSpanDecorator());
A new span will be started for each statement.
The following tags/logs are supported out of the box:
Tag/Log Field | Decorator | Example |
---|---|---|
component |
ComponentSpanDecorator |
JDBC |
db.instance |
DatabaseInstanceSpanDecorator |
db |
db.statement |
DatabaseStatementSpanDecorator |
SELECT * FROM user WHERE id = ? |
db.type |
DatabaseTypeSpanDecorator |
sql |
db.user |
DatabaseUserSpanDecorator |
root |
peer.address ¹ |
PeerAddressSpanDecorator |
postgres://localhost |
peer.hostname |
PeerSpanDecorator |
localhost |
peer.ipv4 |
PeerSpanDecorator |
127.0.0.1 |
peer.ipv6 |
PeerSpanDecorator |
::1 |
peer.port |
PeerSpanDecorator |
5432 |
error |
ErrorSpanDecorator |
true |
error.kind (log) |
ErrorSpanDecorator |
SocketTimeoutException |
error.object (log) |
ErrorSpanDecorator |
(exception instance) |
message (log) |
ErrorMessageSpanDecorator |
Connection timed out |
stack (log) |
ErrorStackSpanDecorator |
SocketTimeoutException at [...] |
¹ Disabled by default due to security concerns (may expose passwords)
Custom SpanDecorator
implementations that are registered using Java's Service Provider Interface mechanism will be picked up automatically by default.
The operation name, by default, is derived from the Statement
's method that was used to execute it. Usually one of execute
, update
, executeQuery
, executeUpdate
, executeBatch
, etc.
The OperationName
interface can be implemented in order to customize the operation name:
new DataSourceTracer(tracer)
.withOperationName((method, queries) ->
toSnakeCase(method.getName()));
Another alternative that is built-in is the StoredProcedureOperationName
that
looks for queries with the format SELECT * FROM my_function(..)
and will
extract the name of the function as the operation name.
new DataSourceTracer(tracer)
.withOperationName(new StoredProcedureOperationName());
If you have questions, concerns, bug reports, etc., please file an issue in this repository's Issue Tracker.
To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. For more details, check the contribution guidelines.