Copyright © 2022

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

2. Getting Started

If you are getting started with Datasource Micrometer, start by reading this section. It answers the basic “what?”, “how?” and “why?” questions. It includes an introduction to Datasource Micrometer, along with installation instructions.

2.1. Introducing Datasource Micrometer

The Datasource Micrometer provides Micrometer Observation API instrumentation for JDBC operations.

It provides consistent observability for JDBC-based data access by instrumenting common database interactions such as:

  • Connection acquisition and release

  • Query execution

  • Result set fetching

  • Generated key retrieval

Datasource Micrometer integrates naturally with the Micrometer ecosystem and can emit metrics and spans to a variety of monitoring and tracing backends.

The instrumentation implementation uses datasource-proxy to provide a proxy for JDBC operations.

2.1.1. Background

The Micrometer v1.10.0 introduced the new Observation API and Micrometer Tracing module. The Observation API allows measuring(observing) any interested behavior from the code in action. Then, notifies it to the registered handlers. The Micrometer Tracing module provides an observation handler implementation that creates distributed traces(spans). It uses a tracer that has abstracted the popular tracer implementations and gives the vendor free APIs for tracing.

In Spring Boot 2.x, the Spring Cloud Sleuth provided the instrumentation to the many components including JDBC operations. It was a central library that provides tracing instrumentation to the Spring Boot applications. However, with the new observability, the responsibility for instrumentation has shifted to the individual component. For example, Spring Framework will provide native instrumentation support for its components using the Observation API. As a result, there will be no Spring Cloud Sleuth for Spring Boot 3.

This Datasource Micrometer project provides instrumentation on the JDBC operations to cover what was provided by the Spring Cloud Sleuth but with the Observation API. The initial version aims users to smoothly transition from Spring Boot 2.x with Spring Cloud Sleuth to the Spring Boot 3 in JDBC instrumentation. In addition, since the Observation API and Micrometer Tracing are independent from Spring ecosystem, the instrumentation is available to the non-spring applications as well.

2.1.2. Modules

Datasource Micrometer is composed of several modules that can be combined depending on your observability needs.

datasource-micrometer

The core module provides JDBC instrumentation using Micrometer Observation.

If you are a Micrometer user but not using Spring Boot, you can directly use the datasource-micrometer module, which does not have a dependency on the Spring.

datasource-micrometer-opentelemetry

The datasource-micrometer-opentelemetry module maps JDBC observations produced by Datasource Micrometer to the stable parts of OpenTelemetry Semantic Conventions.

This module uses JSqlParser to analyze queries.

It focuses on query execution, which is the only JDBC interaction currently covered by OpenTelemetry Semantic Conventions.

datasource-micrometer-spring-boot

The Spring Boot module provides auto-configuration for Datasource Micrometer.

When present on the classpath, it:

  • Automatically instruments DataSource beans

  • Registers default observation conventions

  • Integrates with Spring Boot’s Micrometer and Observation infrastructure

In addition, when the datasource-micrometer-opentelemetry module is available on the classpath, OpenTelemetry support is automatically enabled via auto-configuration.

This is the recommended entry point for most Spring Boot applications.

datasource-micrometer-bom

The datasource-micrometer-bom module provides a Bill of Materials (BOM) for Datasource Micrometer modules.

It can be used to manage consistent dependency versions across Datasource Micrometer artifacts.

2.1.3. Choosing the Right Setup

The following summarizes common usage scenarios:

  • Use datasource-micrometer if you want low-level JDBC observations without Spring Boot.

  • Use datasource-micrometer-spring-boot for standard Micrometer-based observability in Spring Boot applications.

  • Add datasource-micrometer-opentelemetry if you want JDBC spans and metrics to follow OpenTelemetry Semantic Conventions.

2.2. Installation

2.2.1. Maven and Gradle

datasource-micrometer

Maven
<dependency>
    <groupId>net.ttddyy.observation</groupId>
    <artifactId>datasource-micrometer</artifactId>
    <version>2.2.0</version>
</dependency>
Gradle
dependencies {
    implementation "net.ttddyy.observation:datasource-micrometer:2.2.0"
}

datasource-micrometer-opentelemetry

Maven
<dependency>
    <groupId>net.ttddyy.observation</groupId>
    <artifactId>datasource-micrometer-opentelemetry</artifactId>
    <version>2.2.0</version>
</dependency>
Gradle
dependencies {
    implementation "net.ttddyy.observation:datasource-micrometer-opentelemetry:2.2.0"
}

datasource-micrometer-spring-boot

Maven
<dependency>
    <groupId>net.ttddyy.observation</groupId>
    <artifactId>datasource-micrometer-spring-boot</artifactId>
    <version>2.2.0</version>
</dependency>
Gradle
dependencies {
    implementation "net.ttddyy.observation:datasource-micrometer-spring-boot:2.2.0"
}

datasource-micrometer-bom

Maven
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>net.ttddyy.observation</groupId>
            <artifactId>datasource-micrometer-bom</artifactId>
            <version>2.2.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
Gradle
dependencies {
    implementation platform("net.ttddyy.observation:datasource-micrometer-bom:2.2.0")
}

2.2.2. Setup

datasource-micrometer

// Register the tracing observation handlers
ObservationRegistry observationRegistry = ObservationRegistry.create();
ObservationConfig observationConfig = observationRegistry.observationConfig();
observationConfig.observationHandler(new ConnectionTracingObservationHandler(tracer));
observationConfig.observationHandler(new QueryTracingObservationHandler(tracer));
observationConfig.observationHandler(new ResultSetTracingObservationHandler(tracer));
//  add other necessary handlers

// Create a DataSource proxy with the observation listener
DataSource dataSource = ...
DataSourceObservationListener listener = new DataSourceObservationListener(observationRegistry);
DataSource instrumented = ProxyDataSourceBuilder.create(dataSource).listener(listener).methodListener(listener).build;

// Use the instrumented DataSource

datasource-micrometer-spring-boot

The auto-configuration class automatically sets up the observation on your DataSource bean.

2.3. Migration from Spring Cloud Sleuth

Datasource Micrometer deliberately provides similar property names to ease the migration from Spring Cloud Sleuth. Most of the JDBC related properties from spring.sleuth.jdbc and spring.sleuth.jdbc.datasource-proxy map to the jdbc and jdbc.datasource-proxy properties.

Please reference the list of application properties in Spring Cloud Sleuth and Datasource Micrometer.

3. Using Datasource Micrometer

This section goes into more detail about how you should use Datasource Micrometer.

3.1. Types of Observations

The Datasource Micrometer creates Connection, Query, Generated Keys(from v1.1), and ResultSet observations.

The Connection observation represents the database connection operations. It is the base observation, as any database access requires a connection. The Query observation provides query execution details, such as execution time, SQL query, bind parameters, etc. The Generated Keys observation records generated keys when auto-generated keys feature is used for the insert statements. The ResultSet observation shows how the operations fetched the data from the query result, including the number of retrieved rows.

To configure these observations, see How to Add Tracing Observation Handlers for JDBC operations.
For Spring Boot, see How to Choose What To Observe.

3.2. Features

3.2.1. HikariCP Support

jdbc.datasource.driver and jdbc.datasource.pool tags are available when the target datasource is a HikariDataSource.

The HikariJdbcObservationFilter provides this feature and this observation filter needs to be registered to the ObservationRegistry.

ObservationRegistry registry = ...
registry.observationConfig().observationFilter(new HikariJdbcObservationFilter());

It is auto configured in datasource-micrometer-spring-boot and can be disabled with jdbc.hikari.enabled=false.

Spring Cloud Refresh Compatibility

When used with Spring Cloud, an error similar to the following may occur during a refresh operation:

ExistingValue must be an instance of com.zaxxer.hikari.HikariDataSource

This happens because Spring Cloud’s refresh logic expects the DataSource bean to be an instance of HikariDataSource. However, Datasource Micrometer wraps the original DataSource with a proxy, so the bean is no longer directly an instance of HikariDataSource.

To avoid this issue, configure Datasource Micrometer to create the proxy using Spring’s proxy infrastructure:

jdbc.datasource-proxy.type=SPRING_PROXY
The SPRING_PROXY type was introduced in versions 1.4 and 2.2, and is the default starting with those versions.

When SPRING_PROXY is used, the proxy is created using Spring’s ProxyFactory. This allows Spring Cloud’s refresh mechanism to unwrap the proxy and access the underlying HikariDataSource bean.

For more details, see Issue #99.

3.2.2. Remote IP and Port

For spans, remote IP and port are retrieved from the datasource url.

3.2.3. Remote Service Name

The datasource name is used as the remote service name in spans. The name is specified when creating a proxy datasource by datasource-proxy.

DataSource instrumented =
    ProxyDataSourceBuilder.create(dataSource)
        .name("myDS")    // Specify datasource name
        .listener(listener)
        .methodListener(listener)
        .build;

For datasource-micrometer-spring-boot, the datasource name is resolved by looking the catalog name at start up (or the connection pool name for Hikari, then fallback to its beanname) by default.

3.2.4. Application Events

Since version 1.1, datasource-micrometer-spring-boot can publish Spring’s application events for query executions and method invocations on proxied JDBC classes. This feature is disabled by default and can be enabled by setting the property jdbc.event.enabled=true. When enabled, it publishes events - JdbcQueryExecutionEvent and JdbcMethodExecutionEvenet.

3.3. Limitations

3.3.1. Open Session In View

The following limitation applies only to versions prior to v1.2. Starting with v1.2, the duration of the connection observation scope has been shortened, and OIV is handled correctly. For more details, see issue gh-82.

When working with Open-In-View (Open Session In View (OSIV) or Open EntityManager In View (OEIV)), special care is required. This is because OIV delays closing the database connection, which can affect the boundaries of observations.

For example, consider the following code:

@GetMapping("/")
List<Car> cars() {
  return Observation.createNotStarted("my.observation", registry).observe(() -> {
    return repository.findAll();  // DB access
  });
}

With OIV disabled, the observation interaction looks like this:

Action                | Name
----------------------|--------------------
START Observation     | "http.server.requests"
OPEN Scope            | "http.server.requests"
START Observation     | "my.observation"
OPEN Scope            | "my.observation"
START Observation     | "jdbc.connection"
OPEN Scope            | "jdbc.connection"
...                   | ...
CLOSE Scope           | "jdbc.connection"
STOP Observation      | "jdbc.connection"
CLOSE Scope           | "my.observation"
STOP Observation      | "my.observation"
CLOSE Scope           | "http.server.requests"
STOP Observation      | "http.server.requests"

With OIV enabled, the order changes:

Action                | Name
----------------------|--------------------
START Observation     | "http.server.requests"
OPEN Scope            | "http.server.requests"
START Observation     | "my.observation"
OPEN Scope            | "my.observation"
START Observation     | "jdbc.connection"
OPEN Scope            | "jdbc.connection"
...                   | ...
CLOSE Scope           | "my.observation"      <==
STOP Observation      | "my.observation"      <==
CLOSE Scope           | "jdbc.connection"     <==
STOP Observation      | "jdbc.connection"     <==
CLOSE Scope           | "http.server.requests"
STOP Observation      | "http.server.requests"

As you can see, when OIV is enabled, the jdbc.connection observation/scope is closed after the my.observation observation/scope. Since scopes must be closed in the reverse order of their opening, this swapped order can cause leaks in thread-local bound values (such as spans), because opening and closing scopes trigger thread-local operations.

The example above uses an explicitly created observation, but the same applies if you use the @Observed annotation or another instrumentation library. Therefore, when OIV is enabled, pay careful attention to observation boundaries — especially if the observation includes database access.

In upcoming versions, we plan to narrow the scope of connection observations to better support the OIV pattern.

Post-v1.2 Behavior

Starting with v1.2, the scope of the connection observation has been shortened, so OIV now works correctly.
The observation order looks like this:

Action                | Name
----------------------|--------------------
START Observation     | "http.server.requests"
OPEN Scope            | "http.server.requests"
START Observation     | "my.observation"
OPEN Scope            | "my.observation"
START Observation     | "jdbc.connection"
OPEN Scope            | "jdbc.connection"
CLOSE Scope           | "jdbc.connection"  <== Immediately after acquiring a connection
...                   | ...
CLOSE Scope           | "my.observation"
STOP Observation      | "my.observation"
STOP Observation      | "jdbc.connection"  <==
CLOSE Scope           | "http.server.requests"
STOP Observation      | "http.server.requests"

4. OpenTelemetry Semantic Conventions

4.1. Module Overview

The datasource-micrometer-opentelemetry module integrates Datasource Micrometer with OpenTelemetry Semantic Conventions.

This module maps JDBC observations produced by Datasource Micrometer to the stable parts of OpenTelemetry Semantic Conventions v1.39.0, enabling OpenTelemetry-compliant spans and metrics while continuing to use Micrometer Observation as the underlying instrumentation mechanism.

In Spring Boot applications, datasource-micrometer-spring-boot detects this module on the classpath and automatically configures the necessary beans.

4.2. Supported Scope

OpenTelemetry Semantic Conventions currently define specifications primarily for database query execution.

As a result, this module focuses on query-level observability while remaining compatible with Datasource Micrometer’s broader JDBC instrumentation model.

Supported by this module:

  • Query execution spans

  • Query execution metrics

Not defined by the OpenTelemetry specification:

  • Connection lifecycle

  • Result set fetching

  • Generated key retrieval

These additional JDBC interactions are still instrumented by Datasource Micrometer unless explicitly disabled. (see Notes)

4.3. Query Analysis

The OpenTelemetry specification requires structured information derived from SQL statements.

This module analyzes SQL queries using JSqlParser in order to:

  • Determine the database operation (SELECT, INSERT, UPDATE, DELETE, etc.)

  • Produce normalized query representations

  • Optionally sanitize literal values

  • Optionally generate summarized query forms

Query analysis behavior is fully configurable via properties.

4.4. Provided Components

The following components are provided by this module:

  • OpenTelemetryQueryObservationConvention
    An Observation Convention that maps query execution observations to OpenTelemetry semantic conventions for spans.

  • OpenTelemetryMeterObservationHandler
    A Meter Observation Handler that emits metrics following OpenTelemetry database client metric specifications.

  • OpenTelemetryQueryAnalyzer
    Performs SQL query analysis using JSqlParser and produces OpenTelemetry-compatible attributes.

These components integrate with the existing Datasource Micrometer observation infrastructure.

4.5. Spring Boot Support

When the datasource-micrometer-opentelemetry module is present on the classpath, datasource-micrometer-spring-boot automatically activates OpenTelemetry-specific auto-configuration.

The DataSourceObservationOpenTelemetryAutoConfiguration class provides:

  • An OpenTelemetryQueryObservationConvention bean for query execution spans

  • An OpenTelemetryMeterObservationHandler bean for OpenTelemetry-compatible metrics

  • Supporting infrastructure beans required for OpenTelemetry semantic mapping

No additional manual configuration is required beyond adding the module to the classpath.

4.5.1. Properties

All OpenTelemetry-related features can be controlled using Spring Boot properties.

Global Enablement
jdbc.opentelemetry.enabled

Enables or disables all OpenTelemetry-specific functionality.

Spans and Metrics
jdbc.opentelemetry.spans.enabled
jdbc.opentelemetry.metrics.enabled

Control whether OpenTelemetry spans and metrics are emitted.

Query Analysis
jdbc.opentelemetry.analysis.enabled
jdbc.opentelemetry.analysis.summary.enabled
jdbc.opentelemetry.analysis.sanitize.enabled

Control SQL query parsing, summarization, and sanitization behavior.

See JdbcOpenTelemetryProperties or Common Spring Boot application properties for the complete list of available options and default values.

4.6. Notes

Datasource Micrometer instruments multiple JDBC interaction types:

  • CONNECTION – Connection acquisition and close

  • QUERY – Query execution

  • FETCH – ResultSet interaction

  • KEYS – Generated key retrieval

OpenTelemetry Semantic Conventions define specifications only for query execution.

By default, this module replaces the observation convention for QUERY interactions only. This ensures that OpenTelemetry-compliant spans and metrics are emitted for query execution, while other JDBC interactions continue to use Datasource Micrometer’s default conventions.

If you want to emit observability data only for query execution, you can restrict instrumentation using:

jdbc.include=QUERY

This disables connection, fetch, and key-related observations while preserving OpenTelemetry-compliant query instrumentation.

5. “How-to” Guides

This section provides answers to some common “how do I do that…​?” questions. Its coverage is not exhaustive, but it does cover quite a lot.

We are also more than happy to extend this section. If you want to add a “how-to”, send us a pull request.

5.1. datasource-micrometer

5.1.1. How to instrument DataSource

The DataSourceObservationListener provides the observation logic. It is implemented as a datasource-proxy listener. Follow the datasource-proxy usage to create a proxied DataSource with the listener. Then adds tracing observation handlers to the ObservationRegistry.

ObservationRegistry observationRegistry = ...
DataSourceObservationListener listener = new DataSourceObservationListener(observationRegistry);
DataSource instrumented = ProxyDataSourceBuilder.create(dataSource).listener(listener).methodListener(listener).build;

5.1.2. How to Add Tracing Observation Handlers for JDBC operations

There are 3 tracing observation handlers that react to the observations from DataSourceObservationListener.

  • ConnectionTracingObservationHandler

  • QueryTracingObservationHandler

  • ResultSetTracingObservationHandler

generated-keys are also handled by ResultSetTracingObservationHandler.
ObservationRegistry registry = ...
registry.observationConfig().observationHandler(new ConnectionTracingObservationHandler(tracer));
registry.observationConfig().observationHandler(new QueryTracingObservationHandler(tracer));
registry.observationConfig().observationHandler(new ResultSetTracingObservationHandler(tracer));

5.1.3. How to Instrument ResultSet

By default, datasource-proxy does not create a proxy for ResultSet. This, in turn, does not instrument the ResultSet. You need to explicitly enable the ResultSet proxy creation. Then, ResultSet get instrumented automatically.

ProxyDataSourceBuilder builder =
    ProxyDataSourceBuilder.create(dataSource)
        .listener(listener)
        .methodListener(listener)
        .proxyResultSet();  // enable ResultSet proxy creation
DataSource instrumented = builder.build();

5.1.4. How to Instrument Generated Keys

By default, datasource-proxy does not create a proxy for the generated-keys. You need to explicitly enable the generated-keys proxy creation.

ProxyDataSourceBuilder builder =
    ProxyDataSourceBuilder.create(dataSource)
        .listener(listener)
        .methodListener(listener)
        .proxyGeneratedKeys();  // enable Generated-Keys proxy creation
DataSource instrumented = builder.build();
When tracking of ResultSet operations is disabled (see How to Disable Tracking of ResultSet Operations), the jdbc.genearted-keys tag shows an empty value.

5.1.5. How to Include Bind Parameter Values

Bind parameter values - values from setInt, setString, etc operations on prepared and callable statement - are not tagged to spans by default. The DataSourceObservationListener class has a toggle to enable this. When it is enabled, values are tagged to the query spans as jdbc.params[]

DataSourceObservationListener listener = ...;
listener.setIncludeParameterValues(true);

5.2. datasource-micrometer-spring-boot

5.2.1. How to Disable JDBC Instrumentation

Set the jdbc.datasource-proxy.enabled property to false.

5.2.2. How to Disable Hikari-specific Observation

Set the jdbc.hikari.enabled property to false.

5.2.3. How to Choose What To Observe

Specify jdbc.includes property. By default, the property is set to include(observe) all(CONNECTION, QUERY, KEYS, FETCH) types.

5.2.4. How to Include the Bind Parameter Values in Spans

Set the jdbc.datasource-proxy.include-parameter-values property to true.

5.2.5. How to Enable and Configure Query Logging

To enable the query logging, set the jdbc.datasource-proxy.query.enable-logging property to true.

jdbc.datasource-proxy.query.enable-logging=true

# logging configuration
jdbc.datasource-proxy.logging=slf4j
jdbc.datasource-proxy.query.log-level=DEBUG
jdbc.datasource-proxy.query.logger-name=my.query-logger
jdbc.datasource-proxy.multiline=false

# spring boot log level property
logging.level.my.query-logger=DEBUG

5.2.6. How to Customize the ProxyDataSource Name

Create a custom DataSourceNameResolver bean. It replaces the default bean, DefaultDataSourceNameResolver.

5.2.7. How to Customize the ProxyDataSource Creation

The ProxyDataSourceBuilderCustomizer beans are automatically called before creating a proxy datasource. This callback API allows you to customize the ProxyDataSourceBuilder.

For example, you can use ProxyDataSourceBuilderCustomizer to specify the datasource proxy name. In turn, it becomes the remote service name of the spans.

@Bean
public ProxyDataSourceBuilderCustomizer myCustomizer(){
    return (builder, dataSource, beanName, dataSourceName) -> {
        builder.name("MyAppDataSource");
    };
}

5.2.8. How to Modify the Query in Span

If you want to modify the query string in the span (in high cardinality tags), use ObservationFilter to update the tag value. For example, you could perform sanitization, truncation, etc on the query.

This approach is generally applicable to modify any tags in span.

ObservationFilter is applied when the observation stops. The modification will not be available for timers created by DefaultMeterObservationHandler since it sets the timers at observation start.
@Bean
public ObservationFilter observationFilter() {
    String tagKey = String.format(QueryHighCardinalityKeyNames.QUERY.asString(), 0); // There might be multiple queries, only modify the first
    return (context) -> {
        KeyValue tag = context.getHighCardinalityKeyValue(tagKey);
        if(tag != null) {
            String query = tag.getValue();

            // ... modify query

            context.addHighCardinalityKeyValue(KeyValue.of(tagKey, modifiedQuery));
        }
        return context;
    };
}

5.2.9. How to Enable Application Events

Set the jdbc.event.enabled property to true.

5.2.10. How to Selectively Tag Queries

Instead of tagging all queries, you can define an ObservationPredicate bean to selectively tag queries.

@Bean
ObservationPredicate myObservationPredicate() {
    return (name, context) -> {
        if(context instanceof QueryContext queryContext) {
            return queryContext.getQueries().stream().noneMatch(query -> query.contains("QUERY TO IGNORE"));
        }
        return true;
    };
}

A Kotlin-flavored implementation can be found on this issue comment.

5.2.11. How to Use Custom ObservationConvention

Define beans for your custom observation conventions, which will then be automatically detected and applied to the listener.

5.2.12. How to Switch to Use ProxyDataSource

Since version 1.4, the default proxy implementation is a Spring AOP proxy (SPRING_PROXY).

If you want to use the JDK proxy implementation, set:

jdbc.datasource-proxy.type=PROXY

To use ProxyDataSource from datasource-proxy (the behavior used before version 1.1), set:

jdbc.datasource-proxy.type=CONCRETE

5.2.13. How to Disable Tracking of ResultSet Operations

Starting from version 1.1, interactions with a ResultSet are tracked and made available through ResultSetContext. However, in rare cases - such as a ResultSet is kept open for a long time and heavily interact with - this may lead to memory pressure.

To disable this tracking:

  • Call DataSourceObservationListener#setIncludeResultSetOperations(false), or

  • In Spring Boot, set the property jdbc.resultset-operations.enabled=false.

This configuration option was introduced in version 1.1.2.

Disabling this will also make an empty value on the jdbc.generated-keys tag from the Generated Keys span, as the generated key value will no longer be recorded.

5.2.14. How to fix “ExistingValue must be an instance of com.zaxxer.hikari.HikariDataSource” error

When using Spring Cloud refresh (for example via /actuator/refresh), you may encounter the following error:

ExistingValue must be an instance of com.zaxxer.hikari.HikariDataSource

This occurs because the DataSource bean is wrapped with a proxy.

Configure Datasource Micrometer to use the Spring proxy type:

jdbc.datasource-proxy.type=SPRING_PROXY

For background and details, see Spring Cloud Refresh Compatibility.

6. Appendix

6.1. Common Spring Boot application properties

Various properties can be specified inside your application.properties file, inside your application.yml file, or as command line switches. This appendix provides a list of common Datasource Micrometer properties and references to the underlying classes that consume them.

Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. Also, you can define your own properties.
Name Default Description

jdbc.datasource-proxy.enabled

true

Whether to enable JDBC instrumentation.

jdbc.datasource-proxy.include-parameter-values

false

Whether to tag actual query parameter values.

jdbc.datasource-proxy.json-format

false

Use json output for logging query. @see ProxyDataSourceBuilder#asJson()

jdbc.datasource-proxy.logging

slf4j

Logging to use for logging queries.

jdbc.datasource-proxy.multiline

true

Use multiline output for logging query. @see ProxyDataSourceBuilder#multiline()

jdbc.datasource-proxy.query.enable-logging

false

Enable logging all queries to the log.

jdbc.datasource-proxy.query.log-level

DEBUG

Severity of query logger.

jdbc.datasource-proxy.query.logger-name

Name of query logger.

jdbc.datasource-proxy.slow-query.enable-logging

false

Enable logging slow queries to the log.

jdbc.datasource-proxy.slow-query.log-level

WARN

Severity of slow query logger.

jdbc.datasource-proxy.slow-query.logger-name

Name of slow query logger.

jdbc.datasource-proxy.slow-query.threshold

300

Number of seconds to consider query as slow.

jdbc.datasource-proxy.type

spring-proxy

Type for the generating DataSource.

jdbc.event.enabled

false

Enable publishing query/method execution events.

jdbc.excluded-data-source-bean-names

List of DataSource bean names that will not be decorated.

jdbc.hikari.enabled

true

Whether to enable Hikari-specific observation support.

jdbc.includes

Which types of tracing we would like to include.

jdbc.opentelemetry.analysis.cache.enabled

true

Whether to enable cache for query analysis.

jdbc.opentelemetry.analysis.cache.max-size

1000

Cache size for query analysis.

jdbc.opentelemetry.analysis.enabled

true

Whether to perform query analysis.

jdbc.opentelemetry.analysis.sanitize.enabled

true

Whether to sanitize queries for "db.query.text".

jdbc.opentelemetry.analysis.summary.enabled

true

Whether to summarize queries for "db.query.summary".

jdbc.opentelemetry.attributes.overrides

Overrides any matching attributes.

jdbc.opentelemetry.enabled

true

Whether to enable OpenTelemetry Semantic Conventions support.

jdbc.opentelemetry.metrics.enabled

true

Whether to enable support for OpenTelemetry Semantic Conventions for metrics.

jdbc.opentelemetry.spans.enabled

true

Whether to enable support for OpenTelemetry Semantic Conventions for spans.

jdbc.resultset-operations.enabled

true

Enable recording operations on ResultSet.

6.2. Observability Metrics and Spans

6.2.1. Observability - Conventions

Below you can find a list of all GlobalObservationConvention and ObservationConvention declared by this project.

Table 1. ObservationConvention implementations

ObservationConvention Class Name

Applicable ObservationContext Class Name

net.ttddyy.observation.tracing.ConnectionObservationConvention

ConnectionContext

net.ttddyy.observation.tracing.QueryObservationConvention

QueryContext

net.ttddyy.observation.tracing.GeneratedKeysObservationConvention

ResultSetContext

net.ttddyy.observation.tracing.ResultSetObservationConvention

ResultSetContext

6.2.2. Observability - Metrics

Below you can find a list of all metrics declared by this project.

Connection

Span created when a JDBC connection takes place.

Metric name jdbc.connection. Type timer.

Metric name jdbc.connection.active. Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 2. Low cardinality Keys

Name

Description

jdbc.datasource.driver (required)

Name of the JDBC datasource driver. (HikariCP only)

jdbc.datasource.name (required)

Name of the JDBC datasource.

jdbc.datasource.pool (required)

Name of the JDBC datasource pool. (HikariCP only)

Since, events were set on this documented entry, they will be converted to the following counters.

Connection - jdbc connection acquired

When the connection is acquired. This event is recorded right after successful "getConnection()" call.

Metric name jdbc.connection.acquired. Type counter.

Connection - jdbc connection commit

When the connection is committed.

Metric name jdbc.connection.commit. Type counter.

Connection - jdbc connection rollback

When the connection is rolled back.

Metric name jdbc.connection.rollback. Type counter.

Generated Keys

Span created when generated keys are returned.

Metric name jdbc.generated-keys. Type timer.

Metric name jdbc.generated-keys.active. Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 3. Low cardinality Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

Query

Span created when executing a query.

Metric name jdbc.query. Type timer.

Metric name jdbc.query.active. Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 4. Low cardinality Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

Result Set

Span created when working with JDBC result set.

Metric name jdbc.result-set. Type timer.

Metric name jdbc.result-set.active. Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 5. Low cardinality Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

6.2.3. Observability - Spans

Below you can find a list of all spans declared by this project.

Connection Span

Span created when a JDBC connection takes place.

Span name connection.

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 6. Tag Keys

Name

Description

jdbc.datasource.driver (required)

Name of the JDBC datasource driver. (HikariCP only)

jdbc.datasource.name (required)

Name of the JDBC datasource.

jdbc.datasource.pool (required)

Name of the JDBC datasource pool. (HikariCP only)

Table 7. Event Values

Name

Description

acquired

When the connection is acquired. This event is recorded right after successful "getConnection()" call.

commit

When the connection is committed.

rollback

When the connection is rolled back.

Generated Keys Span

Span created when generated keys are returned.

Span name generated-keys.

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 8. Tag Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

jdbc.generated-keys (required)

Generated keys.

Query Span

Span created when executing a query.

Span name query.

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 9. Tag Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

jdbc.params[%s] (required)

JDBC query parameter values. (since the name contains %s the final value will be resolved at runtime)

jdbc.query[%s] (required)

Name of the JDBC query. (since the name contains %s the final value will be resolved at runtime)

jdbc.row-affected (required)

Result of "executeUpdate()", "executeLargeUpdate()", "executeBatch()", or "executeLargeBatch()" on "Statement". For batch operations, the value is represented as array.

Result Set Span

Span created when working with JDBC result set.

Span name result-set.

Fully qualified name of the enclosing class net.ttddyy.observation.tracing.JdbcObservationDocumentation.

All tags must be prefixed with jdbc prefix!
Table 10. Tag Keys

Name

Description

jdbc.datasource.name (required)

Name of the JDBC datasource.

jdbc.row-count (required)

Number of SQL rows.