From 61e3554922985fedc9a159677571bd2e0290905d Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 30 Jun 2026 21:50:10 -0400 Subject: [PATCH 1/2] Peel dbUser out of DatabaseClientDecorator into a param-injected TagExtractor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The null-ratio scan showed dbUser was the sparsest template method on DatabaseClientDecorator: 28/30 leaves returned null (only JDBC and Vertx-SQL provide a real user). That sparsity is the SQL/NoSQL false-generalization showing through — db.user is a SQL-auth concept the NoSQL/cache stores can only answer with null, yet every DB span paid a virtual dbUser() call to set DB_USER=null. Replaces the dbUser template method with a param-injected connection-tags extractor: - DatabaseClientDecorator gains onConnection(span, conn, TagExtractor); the 2-arg overload delegates with a shared no-op extractor. The extractor is passed as a caller-side constant so it devirtualizes+inlines at a monomorphic advice site (rather than a virtual provider method). dbInstance/dbHostname stay for now (they are DERIVED — feed service-name split — a later peel). - The 2 SQL providers set db.user themselves: JDBC folds it into ConnectionInfoExtractor; Vertx-SQL gets VertxSqlConnectionExtractor, both applied via the param form. db.user is set unconditionally to preserve the prior (present-check-free) behavior exactly. - The 26 NoSQL/cache decorators shed their dead `return null` dbUser override. Behavior-preserving. agent-bootstrap decorator tests updated (the mock interaction-asserts for the old mechanism; these are Spock migration candidates) and green; JDBCInstrumentationV0Test 87/87. Vertx-SQL's extractor is auto-injected as a transitive helper (its tests are container-gated / CI-only). Co-Authored-By: Claude Opus 4.8 --- .../decorator/DatabaseClientDecorator.java | 33 ++++++++++++++++-- ...ocessingDatabaseClientDecoratorTest.groovy | 5 --- .../DatabaseClientDecoratorTest.groovy | 34 +++++++++++++++---- .../decorator/OrmClientDecoratorTest.groovy | 5 --- .../aerospike4/AerospikeClientDecorator.java | 5 --- .../client/CouchbaseClientDecorator.java | 5 --- .../client/CouchbaseClientDecorator.java | 5 --- .../client/CouchbaseClientDecorator.java | 5 --- .../datanucleus/DatanucleusDecorator.java | 5 --- .../cassandra/CassandraClientDecorator.java | 5 --- .../cassandra4/CassandraClientDecorator.java | 5 --- .../ElasticsearchRestClientDecorator.java | 5 --- ...ElasticsearchTransportClientDecorator.java | 5 --- .../hibernate/HibernateDecorator.java | 5 --- .../ignite/v2/cache/IgniteCacheDecorator.java | 5 --- .../jdbc/ConnectionInfoExtractor.java | 4 +++ .../instrumentation/jdbc/JDBCDecorator.java | 11 ++---- .../jedis/JedisClientDecorator.java | 5 --- .../jedis30/JedisClientDecorator.java | 5 --- .../clients/jedis/JedisClientDecorator.java | 5 --- .../lettuce4/LettuceClientDecorator.java | 5 --- .../lettuce5/LettuceClientDecorator.java | 5 --- .../instrumentation/mongo/MongoDecorator.java | 5 --- .../OpensearchRestClientDecorator.java | 5 --- .../OpensearchTransportClientDecorator.java | 5 --- .../rediscala/RediscalaClientDecorator.java | 5 --- .../redisson/RedissonClientDecorator.java | 5 --- .../redisson23/RedissonClientDecorator.java | 5 --- .../redisson30/RedissonClientDecorator.java | 5 --- .../spymemcached/MemcacheClientDecorator.java | 5 --- .../java/io/valkey/ValkeyClientDecorator.java | 5 --- .../VertxRedisClientDecorator.java | 5 --- .../VertxSqlClientDecorator.java | 7 +--- .../VertxSqlConnectionExtractor.java | 26 ++++++++++++++ 34 files changed, 92 insertions(+), 163 deletions(-) create mode 100644 dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlConnectionExtractor.java diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecorator.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecorator.java index 7336a059bdc..7c108758e24 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecorator.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecorator.java @@ -16,6 +16,7 @@ import datadog.trace.api.naming.SpanNaming; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.bootstrap.instrumentation.api.TagExtractor; import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString; import java.util.function.BiConsumer; @@ -55,12 +56,15 @@ public String getDbType() { protected abstract String dbType(); - protected abstract String dbUser(CONNECTION connection); - protected abstract String dbInstance(CONNECTION connection); protected abstract CharSequence dbHostname(CONNECTION connection); + /** + * No-op connection-tag extractor: the default for stores that contribute no pure connection tags. + */ + private static final TagExtractor NO_CONNECTION_TAGS = (connection, span) -> {}; + /** * This should be called when the connection is being used, not when it's created. * @@ -69,8 +73,26 @@ public String getDbType() { * @return */ public AgentSpan onConnection(final AgentSpan span, final CONNECTION connection) { + return onConnection(span, connection, noConnectionTags()); + } + + /** + * As {@link #onConnection(AgentSpan, Object)}, but with a {@link TagExtractor} for the store's + * pure connection tags (e.g. {@code db.user} for SQL) injected as a parameter. + * + *

Passing the extractor as a caller-side argument — rather than fetching it from a virtual + * method — is what preserves inlining: at a monomorphic advice site the extractor is a {@code + * static final} constant, so when this (small) method inlines, {@code extractor.extract(...)} + * devirtualizes and inlines too. It replaces the previous per-store template methods (the + * sparsely overridden {@code dbUser}, which most NoSQL stores could only answer with {@code + * null}) and is the seam for disentangling pure tag extraction from the derivation below. + */ + public AgentSpan onConnection( + final AgentSpan span, + final CONNECTION connection, + final TagExtractor connectionTags) { if (connection != null) { - span.setTag(Tags.DB_USER, dbUser(connection)); + connectionTags.extract(connection, span); onInstance(span, dbInstance(connection)); CharSequence hostName = dbHostname(connection); if (hostName != null) { @@ -84,6 +106,11 @@ public AgentSpan onConnection(final AgentSpan span, final CONNECTION connection) return span; } + @SuppressWarnings("unchecked") + protected static TagExtractor noConnectionTags() { + return (TagExtractor) NO_CONNECTION_TAGS; + } + protected AgentSpan onInstance(final AgentSpan span, final String dbInstance) { if (dbInstance != null) { span.setTag(Tags.DB_INSTANCE, dbInstance); diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DBTypeProcessingDatabaseClientDecoratorTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DBTypeProcessingDatabaseClientDecoratorTest.groovy index 624100fcc50..c7794fcda1f 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DBTypeProcessingDatabaseClientDecoratorTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DBTypeProcessingDatabaseClientDecoratorTest.groovy @@ -67,11 +67,6 @@ class DBTypeProcessingDatabaseClientDecoratorTest extends ClientDecoratorTest { return "test-db" } - @Override - protected String dbUser(Map map) { - return map.user - } - @Override protected String dbInstance(Map map) { return map.instance diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecoratorTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecoratorTest.groovy index 93852ccc88c..6f6bab2e8fa 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecoratorTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecoratorTest.groovy @@ -51,7 +51,8 @@ class DatabaseClientDecoratorTest extends ClientDecoratorTest { then: if (session) { - 1 * span.setTag(Tags.DB_USER, session.user) + // db.user is no longer set by the 2-arg onConnection (it used to come from the dbUser template + // method); it now arrives via the connection-tags extractor of the 3-arg form (see below). if (session.instance != null) { 1 * span.setTag(Tags.DB_INSTANCE, session.instance) } @@ -88,6 +89,32 @@ class DatabaseClientDecoratorTest extends ClientDecoratorTest { true | true | true | [user: "test-user", instance: "test-instance"] } + def "test onConnection applies the connection-tags extractor"() { + setup: + def decorator = newDecorator() + def session = [user: "test-user"] + + when: + decorator.onConnection(span, session, { Map m, AgentSpan s -> s.setTag(Tags.DB_USER, m.user) }) + + then: + 1 * span.setTag(Tags.DB_USER, "test-user") + 0 * _ + } + + def "test onConnection with a null connection skips the extractor"() { + setup: + def decorator = newDecorator() + def extractor = Mock(datadog.trace.bootstrap.instrumentation.api.TagExtractor) + + when: + decorator.onConnection(span, null, extractor) + + then: + 0 * extractor.extract(_, _) + 0 * _ + } + def "test onStatement"() { setup: def decorator = newDecorator() @@ -134,11 +161,6 @@ class DatabaseClientDecoratorTest extends ClientDecoratorTest { return "test-db" } - @Override - protected String dbUser(Map map) { - return map.user - } - @Override protected String dbInstance(Map map) { return map.instance diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/OrmClientDecoratorTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/OrmClientDecoratorTest.groovy index f5c2995ccaa..8778ca6be09 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/OrmClientDecoratorTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/OrmClientDecoratorTest.groovy @@ -35,11 +35,6 @@ class OrmClientDecoratorTest extends DatabaseClientDecoratorTest { return "test-db" } - @Override - protected String dbUser(Object o) { - return "test-user" - } - @Override protected String dbInstance(Object o) { return "test-user" diff --git a/dd-java-agent/instrumentation/aerospike-4.0/src/main/java/datadog/trace/instrumentation/aerospike4/AerospikeClientDecorator.java b/dd-java-agent/instrumentation/aerospike-4.0/src/main/java/datadog/trace/instrumentation/aerospike4/AerospikeClientDecorator.java index e00683755c9..4b403f37809 100644 --- a/dd-java-agent/instrumentation/aerospike-4.0/src/main/java/datadog/trace/instrumentation/aerospike4/AerospikeClientDecorator.java +++ b/dd-java-agent/instrumentation/aerospike-4.0/src/main/java/datadog/trace/instrumentation/aerospike4/AerospikeClientDecorator.java @@ -50,11 +50,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Node node) { - return null; - } - @Override protected String dbInstance(final Node node) { return null; diff --git a/dd-java-agent/instrumentation/couchbase/couchbase-2.0/src/main/java/datadog/trace/instrumentation/couchbase/client/CouchbaseClientDecorator.java b/dd-java-agent/instrumentation/couchbase/couchbase-2.0/src/main/java/datadog/trace/instrumentation/couchbase/client/CouchbaseClientDecorator.java index cd592761951..0b8e57673f3 100644 --- a/dd-java-agent/instrumentation/couchbase/couchbase-2.0/src/main/java/datadog/trace/instrumentation/couchbase/client/CouchbaseClientDecorator.java +++ b/dd-java-agent/instrumentation/couchbase/couchbase-2.0/src/main/java/datadog/trace/instrumentation/couchbase/client/CouchbaseClientDecorator.java @@ -42,11 +42,6 @@ protected String dbType() { return "couchbase"; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/main/java/datadog/trace/instrumentation/couchbase_31/client/CouchbaseClientDecorator.java b/dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/main/java/datadog/trace/instrumentation/couchbase_31/client/CouchbaseClientDecorator.java index 803b53e7e49..de988fa86ee 100644 --- a/dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/main/java/datadog/trace/instrumentation/couchbase_31/client/CouchbaseClientDecorator.java +++ b/dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/main/java/datadog/trace/instrumentation/couchbase_31/client/CouchbaseClientDecorator.java @@ -51,11 +51,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/main/java/datadog/trace/instrumentation/couchbase_32/client/CouchbaseClientDecorator.java b/dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/main/java/datadog/trace/instrumentation/couchbase_32/client/CouchbaseClientDecorator.java index 642f88eb739..985cf901f6d 100644 --- a/dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/main/java/datadog/trace/instrumentation/couchbase_32/client/CouchbaseClientDecorator.java +++ b/dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/main/java/datadog/trace/instrumentation/couchbase_32/client/CouchbaseClientDecorator.java @@ -51,11 +51,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/DatanucleusDecorator.java b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/DatanucleusDecorator.java index bbd970de659..1de3ea5b480 100644 --- a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/DatanucleusDecorator.java +++ b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/DatanucleusDecorator.java @@ -68,11 +68,6 @@ protected String dbType() { return null; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-3.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientDecorator.java b/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-3.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientDecorator.java index 09f83cd84fa..a3967b4c4d2 100644 --- a/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-3.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientDecorator.java +++ b/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-3.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientDecorator.java @@ -62,11 +62,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Session session) { - return null; - } - @Override protected String dbInstance(final Session session) { return session.getLoggedKeyspace(); diff --git a/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-4.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra4/CassandraClientDecorator.java b/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-4.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra4/CassandraClientDecorator.java index 73badd7fbd2..a4356c6f74c 100644 --- a/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-4.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra4/CassandraClientDecorator.java +++ b/dd-java-agent/instrumentation/datastax-cassandra/datastax-cassandra-4.0/src/main/java/datadog/trace/instrumentation/datastax/cassandra4/CassandraClientDecorator.java @@ -67,11 +67,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Session session) { - return null; - } - @Override protected String dbInstance(final Session session) { return session.getKeyspace().map(Objects::toString).orElse(null); diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchRestClientDecorator.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchRestClientDecorator.java index 0741e14a39e..ea133164520 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchRestClientDecorator.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchRestClientDecorator.java @@ -57,11 +57,6 @@ protected String dbType() { return "elasticsearch"; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchTransportClientDecorator.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchTransportClientDecorator.java index 172a7a56ef8..0ceb11c5bfd 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchTransportClientDecorator.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-common/src/main/java/datadog/trace/instrumentation/elasticsearch/ElasticsearchTransportClientDecorator.java @@ -45,11 +45,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/HibernateDecorator.java b/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/HibernateDecorator.java index 6c7aa6b9798..e7f4136e139 100644 --- a/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/HibernateDecorator.java +++ b/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/HibernateDecorator.java @@ -40,11 +40,6 @@ protected String dbType() { return null; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheDecorator.java b/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheDecorator.java index ef372f24a06..64b2649f7b8 100644 --- a/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheDecorator.java +++ b/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheDecorator.java @@ -56,11 +56,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(IgniteCache igniteCache) { - return null; - } - @Override protected String dbInstance(IgniteCache igniteCache) { return null; diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInfoExtractor.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInfoExtractor.java index 4f001e3c73f..db1d0b4c14d 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInfoExtractor.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInfoExtractor.java @@ -2,6 +2,7 @@ import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_POOL_NAME; import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_SCHEMA; +import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_USER; import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_WAREHOUSE; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -27,6 +28,9 @@ private ConnectionInfoExtractor() {} @Override public void extract(final DBInfo info, final AgentSpan span) { + // DB_USER is set unconditionally to preserve the prior DatabaseClientDecorator behavior (it set + // db.user from dbUser(info) without a present-check); the rest skip null/empty. + span.setTag(DB_USER, info.getUser()); setTagIfPresent(span, DB_WAREHOUSE, info.getWarehouse()); setTagIfPresent(span, DB_SCHEMA, info.getSchema()); setTagIfPresent(span, DB_POOL_NAME, info.getPoolName()); diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 32b59beafbc..d3799172c20 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -128,11 +128,6 @@ protected String dbType() { return "jdbc"; } - @Override - protected String dbUser(final DBInfo info) { - return info.getUser(); - } - @Override protected String dbInstance(final DBInfo info) { if (info.getInstance() != null) { @@ -150,10 +145,10 @@ protected String dbHostname(final DBInfo info) { public AgentSpan onConnection(final AgentSpan span, DBInfo dbInfo) { if (dbInfo != null) { processDatabaseType(span, dbInfo.getType()); - - span.setTags(dbInfo, ConnectionInfoExtractor.INSTANCE); } - return super.onConnection(span, dbInfo); + // Pure connection tags (db.user / warehouse / schema / pool) are injected via the param form; + // the base applies them under its own null-check alongside instance/hostname derivation. + return super.onConnection(span, dbInfo, ConnectionInfoExtractor.INSTANCE); } public static DBInfo parseDBInfo( diff --git a/dd-java-agent/instrumentation/jedis/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisClientDecorator.java b/dd-java-agent/instrumentation/jedis/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisClientDecorator.java index f85167f6ba2..012880d4a5b 100644 --- a/dd-java-agent/instrumentation/jedis/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisClientDecorator.java +++ b/dd-java-agent/instrumentation/jedis/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisClientDecorator.java @@ -40,11 +40,6 @@ protected String dbType() { return REDIS; } - @Override - protected String dbUser(final Connection connection) { - return null; - } - @Override protected String dbInstance(final Connection connection) { return null; diff --git a/dd-java-agent/instrumentation/jedis/jedis-3.0/src/main/java/datadog/trace/instrumentation/jedis30/JedisClientDecorator.java b/dd-java-agent/instrumentation/jedis/jedis-3.0/src/main/java/datadog/trace/instrumentation/jedis30/JedisClientDecorator.java index edaaa9278b3..e0bd1c94911 100644 --- a/dd-java-agent/instrumentation/jedis/jedis-3.0/src/main/java/datadog/trace/instrumentation/jedis30/JedisClientDecorator.java +++ b/dd-java-agent/instrumentation/jedis/jedis-3.0/src/main/java/datadog/trace/instrumentation/jedis30/JedisClientDecorator.java @@ -41,11 +41,6 @@ protected String dbType() { return REDIS; } - @Override - protected String dbUser(final Connection connection) { - return null; - } - @Override protected String dbInstance(final Connection connection) { return null; diff --git a/dd-java-agent/instrumentation/jedis/jedis-4.0/src/main/java/redis/clients/jedis/JedisClientDecorator.java b/dd-java-agent/instrumentation/jedis/jedis-4.0/src/main/java/redis/clients/jedis/JedisClientDecorator.java index ccbfc3d3418..8e8e51027dd 100644 --- a/dd-java-agent/instrumentation/jedis/jedis-4.0/src/main/java/redis/clients/jedis/JedisClientDecorator.java +++ b/dd-java-agent/instrumentation/jedis/jedis-4.0/src/main/java/redis/clients/jedis/JedisClientDecorator.java @@ -40,11 +40,6 @@ protected String dbType() { return REDIS; } - @Override - protected String dbUser(final Connection connection) { - return null; - } - @Override protected String dbInstance(final Connection connection) { return null; diff --git a/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/LettuceClientDecorator.java b/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/LettuceClientDecorator.java index 31b8c2e67e2..034fbd8fb28 100644 --- a/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/LettuceClientDecorator.java +++ b/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/LettuceClientDecorator.java @@ -45,11 +45,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(final RedisURI connection) { - return null; - } - @Override protected String dbInstance(final RedisURI connection) { return null; diff --git a/dd-java-agent/instrumentation/lettuce/lettuce-5.0/src/main/java/datadog/trace/instrumentation/lettuce5/LettuceClientDecorator.java b/dd-java-agent/instrumentation/lettuce/lettuce-5.0/src/main/java/datadog/trace/instrumentation/lettuce5/LettuceClientDecorator.java index a8442a1f320..00b2582295d 100644 --- a/dd-java-agent/instrumentation/lettuce/lettuce-5.0/src/main/java/datadog/trace/instrumentation/lettuce5/LettuceClientDecorator.java +++ b/dd-java-agent/instrumentation/lettuce/lettuce-5.0/src/main/java/datadog/trace/instrumentation/lettuce5/LettuceClientDecorator.java @@ -41,11 +41,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(final RedisURI connection) { - return null; - } - @Override protected String dbInstance(final RedisURI connection) { return null; diff --git a/dd-java-agent/instrumentation/mongo/mongo-common/src/main/java/datadog/trace/instrumentation/mongo/MongoDecorator.java b/dd-java-agent/instrumentation/mongo/mongo-common/src/main/java/datadog/trace/instrumentation/mongo/MongoDecorator.java index bb6c0f7d8bd..030586fdf53 100644 --- a/dd-java-agent/instrumentation/mongo/mongo-common/src/main/java/datadog/trace/instrumentation/mongo/MongoDecorator.java +++ b/dd-java-agent/instrumentation/mongo/mongo-common/src/main/java/datadog/trace/instrumentation/mongo/MongoDecorator.java @@ -52,11 +52,6 @@ protected final String dbType() { return DB_TYPE; } - @Override - protected final String dbUser(final CommandStartedEvent event) { - return null; - } - @Override protected final String dbHostname(CommandStartedEvent event) { final ConnectionDescription connectionDescription = event.getConnectionDescription(); diff --git a/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientDecorator.java b/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientDecorator.java index ec07a1c8e55..0d98fe70401 100644 --- a/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientDecorator.java +++ b/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientDecorator.java @@ -55,11 +55,6 @@ protected String dbType() { return "opensearch"; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientDecorator.java b/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientDecorator.java index a91b3dffcbc..b36fe4ac655 100644 --- a/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientDecorator.java +++ b/dd-java-agent/instrumentation/opensearch/opensearch-common/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientDecorator.java @@ -44,11 +44,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final Object o) { - return null; - } - @Override protected String dbInstance(final Object o) { return null; diff --git a/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaClientDecorator.java b/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaClientDecorator.java index 3205409a63e..303bbc8e71c 100644 --- a/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaClientDecorator.java +++ b/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaClientDecorator.java @@ -43,11 +43,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(final RedisConnectionInfo redisConnectionInfo) { - return null; - } - @Override protected String dbInstance(final RedisConnectionInfo redisConnectionInfo) { return null; diff --git a/dd-java-agent/instrumentation/redisson/redisson-2.0.0/src/main/java/datadog/trace/instrumentation/redisson/RedissonClientDecorator.java b/dd-java-agent/instrumentation/redisson/redisson-2.0.0/src/main/java/datadog/trace/instrumentation/redisson/RedissonClientDecorator.java index 481fd745e3b..d115e6883bb 100644 --- a/dd-java-agent/instrumentation/redisson/redisson-2.0.0/src/main/java/datadog/trace/instrumentation/redisson/RedissonClientDecorator.java +++ b/dd-java-agent/instrumentation/redisson/redisson-2.0.0/src/main/java/datadog/trace/instrumentation/redisson/RedissonClientDecorator.java @@ -42,11 +42,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(CommandData commandData) { - return null; - } - @Override protected String dbInstance(CommandData commandData) { return null; diff --git a/dd-java-agent/instrumentation/redisson/redisson-2.3.0/src/main/java/datadog/trace/instrumentation/redisson23/RedissonClientDecorator.java b/dd-java-agent/instrumentation/redisson/redisson-2.3.0/src/main/java/datadog/trace/instrumentation/redisson23/RedissonClientDecorator.java index 19e452b3f14..cfc96c62da5 100644 --- a/dd-java-agent/instrumentation/redisson/redisson-2.3.0/src/main/java/datadog/trace/instrumentation/redisson23/RedissonClientDecorator.java +++ b/dd-java-agent/instrumentation/redisson/redisson-2.3.0/src/main/java/datadog/trace/instrumentation/redisson23/RedissonClientDecorator.java @@ -42,11 +42,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(CommandData commandData) { - return null; - } - @Override protected String dbInstance(CommandData commandData) { return null; diff --git a/dd-java-agent/instrumentation/redisson/redisson-3.10.3/src/main/java/datadog/trace/instrumentation/redisson30/RedissonClientDecorator.java b/dd-java-agent/instrumentation/redisson/redisson-3.10.3/src/main/java/datadog/trace/instrumentation/redisson30/RedissonClientDecorator.java index 4d157fb8f06..3fe22fddc6d 100644 --- a/dd-java-agent/instrumentation/redisson/redisson-3.10.3/src/main/java/datadog/trace/instrumentation/redisson30/RedissonClientDecorator.java +++ b/dd-java-agent/instrumentation/redisson/redisson-3.10.3/src/main/java/datadog/trace/instrumentation/redisson30/RedissonClientDecorator.java @@ -42,11 +42,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(CommandData commandData) { - return null; - } - @Override protected String dbInstance(CommandData commandData) { return null; diff --git a/dd-java-agent/instrumentation/spymemcached-2.10/src/main/java/datadog/trace/instrumentation/spymemcached/MemcacheClientDecorator.java b/dd-java-agent/instrumentation/spymemcached-2.10/src/main/java/datadog/trace/instrumentation/spymemcached/MemcacheClientDecorator.java index bcfc58674d5..ea01cf282b5 100644 --- a/dd-java-agent/instrumentation/spymemcached-2.10/src/main/java/datadog/trace/instrumentation/spymemcached/MemcacheClientDecorator.java +++ b/dd-java-agent/instrumentation/spymemcached-2.10/src/main/java/datadog/trace/instrumentation/spymemcached/MemcacheClientDecorator.java @@ -44,11 +44,6 @@ protected String dbType() { return DB_TYPE; } - @Override - protected String dbUser(final MemcachedConnection session) { - return null; - } - @Override protected String dbInstance(final MemcachedConnection connection) { return null; diff --git a/dd-java-agent/instrumentation/valkey-java-5.3/src/main/java/io/valkey/ValkeyClientDecorator.java b/dd-java-agent/instrumentation/valkey-java-5.3/src/main/java/io/valkey/ValkeyClientDecorator.java index 0e0e6cf43bf..ebb8ef0bc6c 100644 --- a/dd-java-agent/instrumentation/valkey-java-5.3/src/main/java/io/valkey/ValkeyClientDecorator.java +++ b/dd-java-agent/instrumentation/valkey-java-5.3/src/main/java/io/valkey/ValkeyClientDecorator.java @@ -40,11 +40,6 @@ protected String dbType() { return VALKEY; } - @Override - protected String dbUser(final Connection connection) { - return null; - } - @Override protected String dbInstance(final Connection connection) { return null; diff --git a/dd-java-agent/instrumentation/vertx/vertx-redis-client/vertx-redis-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_redis_client/VertxRedisClientDecorator.java b/dd-java-agent/instrumentation/vertx/vertx-redis-client/vertx-redis-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_redis_client/VertxRedisClientDecorator.java index dec7fe39d02..f04c3498365 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-redis-client/vertx-redis-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_redis_client/VertxRedisClientDecorator.java +++ b/dd-java-agent/instrumentation/vertx/vertx-redis-client/vertx-redis-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_redis_client/VertxRedisClientDecorator.java @@ -54,11 +54,6 @@ protected String dbType() { return "redis"; } - @Override - protected String dbUser(final SocketAddress socketAddress) { - return null; - } - @Override protected String dbInstance(final SocketAddress socketAddress) { return null; diff --git a/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlClientDecorator.java b/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlClientDecorator.java index d95a6c65137..43fcb7f268e 100644 --- a/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlClientDecorator.java +++ b/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlClientDecorator.java @@ -53,11 +53,6 @@ protected String dbType() { return "vertx-sql"; } - @Override - protected String dbUser(final DBInfo info) { - return info.getUser(); - } - @Override protected String dbInstance(final DBInfo info) { if (info.getInstance() != null) { @@ -92,7 +87,7 @@ public AgentSpan startAndDecorateSpanForStatement( if (dbInfo != null) { processDatabaseType(span, dbInfo.getType()); } - super.onConnection(span, dbInfo); + super.onConnection(span, dbInfo, VertxSqlConnectionExtractor.INSTANCE); if (null != dbQueryInfo) { span.setResourceName(dbQueryInfo.getSql()); span.setTag(DB_OPERATION, dbQueryInfo.getOperation()); diff --git a/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlConnectionExtractor.java b/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlConnectionExtractor.java new file mode 100644 index 00000000000..880188e2826 --- /dev/null +++ b/dd-java-agent/instrumentation/vertx/vertx-sql-client-3.9/src/main/java/datadog/trace/instrumentation/vertx_sql_client_39/VertxSqlConnectionExtractor.java @@ -0,0 +1,26 @@ +package datadog.trace.instrumentation.vertx_sql_client_39; + +import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_USER; + +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.TagExtractor; +import datadog.trace.bootstrap.instrumentation.jdbc.DBInfo; + +/** + * Named singleton {@link TagExtractor} for Vertx-SQL's pure connection tags ({@code db.user}). The + * SQL-family counterpart to the NoSQL stores that contribute none — injected via the param form of + * {@code DatabaseClientDecorator.onConnection} rather than the removed {@code dbUser} template + * method. + */ +public final class VertxSqlConnectionExtractor implements TagExtractor { + public static final VertxSqlConnectionExtractor INSTANCE = new VertxSqlConnectionExtractor(); + + private VertxSqlConnectionExtractor() {} + + @Override + public void extract(final DBInfo info, final AgentSpan span) { + // Unconditional to preserve the prior DatabaseClientDecorator behavior (db.user was set from + // dbUser(info) with no present-check). + span.setTag(DB_USER, info.getUser()); + } +} From f4cad2100e1c70924748539ff45c3264e79c3913 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 30 Jun 2026 22:05:21 -0400 Subject: [PATCH 2/2] Add DatabaseClientConnectionBenchmark: param-injected extractor inlining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acceptance harness for the dbUser peel's inlining claim. Exercises the real DatabaseClientDecorator.onConnection param-form at a mono call site (one static-final extractor — the production shape) vs mega (8 rotating extractor types — the worst case of a single shared site). PrintInlining (mono) confirms the chain collapses: DatabaseClientDecorator ::onConnection inline (hot) and the concrete extractor's extract() devirtualizes and inlines (the abstract TagExtractor::extract slot is bypassed). mega only costs ~14% here because the trivial extractor bodies fit HotSpot's polymorphic inline ceiling; larger real bodies would fall to a virtual call sooner, so mega is an optimistic worst-case. The production shape is mono. Co-Authored-By: Claude Opus 4.8 --- .../DatabaseClientConnectionBenchmark.java | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientConnectionBenchmark.java diff --git a/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientConnectionBenchmark.java b/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientConnectionBenchmark.java new file mode 100644 index 00000000000..ff70c1f147c --- /dev/null +++ b/dd-java-agent/agent-bootstrap/src/jmh/java/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientConnectionBenchmark.java @@ -0,0 +1,209 @@ +package datadog.trace.bootstrap.instrumentation.decorator; + +import static datadog.trace.bootstrap.instrumentation.api.Tags.DB_USER; +import static java.util.concurrent.TimeUnit.SECONDS; + +import datadog.trace.api.GlobalTracer; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.TagExtractor; +import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString; +import datadog.trace.common.writer.Writer; +import datadog.trace.core.CoreTracer; +import datadog.trace.core.DDSpan; +import java.util.List; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +/** + * Acceptance test for the {@code dbUser} peel: measures the param-injected connection-tags {@link + * TagExtractor} form of {@link DatabaseClientDecorator#onConnection(AgentSpan, Object, + * TagExtractor)} — the shape that replaced the sparsely-overridden {@code dbUser} template method. + * + *

One decorator type is used throughout (so the receiver and the {@code dbInstance}/{@code + * dbHostname} template calls stay monomorphic); only the injected extractor varies, to isolate the + * question raised in review: does passing the extractor as a caller-side constant devirtualize and + * inline? + * + *

{@code mode}: + * + *

    + *
  • mono — a single {@code static final} extractor at the call site (the production + * shape: each integration's advice passes its own constant). Expect {@code extract()} to + * devirtualize and inline when {@code onConnection} inlines. + *
  • mega — {@link #TYPES} distinct extractor types cycled through the one site (the + * worst case: a single shared site that never sees a stable type). Characterizes the downside + * if the call is not inlined. + *
+ * + *

Run with {@code -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining} to confirm the mechanism + * (the tree, not just the number) — look for {@code DatabaseClientDecorator::onConnection} and the + * extractor {@code extract} bodies. + */ +@State(Scope.Thread) +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(SECONDS) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) +@Threads(8) +public class DatabaseClientConnectionBenchmark { + + private static final int TYPES = 8; + private static final String CONN = "bench-user"; + + /** The mono call site: a single static-final constant extractor. */ + private static final TagExtractor MONO = new E0(); + + @Param({"mono", "mega"}) + String mode; + + private boolean mega; + private BenchDbDecorator decorator; + private AgentSpan span; + private TagExtractor[] extractors; + private int idx; + + @SuppressWarnings("unchecked") + @Setup(Level.Trial) + public void setUp() { + CoreTracer tracer = + CoreTracer.builder().strictTraceWrites(true).writer(new NoOpWriter()).build(); + GlobalTracer.forceRegister(tracer); + decorator = new BenchDbDecorator(); + span = tracer.startSpan("benchmark", "db.query"); + extractors = + new TagExtractor[] { + new E0(), new E1(), new E2(), new E3(), new E4(), new E5(), new E6(), new E7() + }; + mega = "mega".equals(mode); + } + + @Benchmark + public AgentSpan onConnection() { + if (mega) { + int i = idx; + idx = (i + 1 == TYPES) ? 0 : i + 1; + return decorator.onConnection(span, CONN, extractors[i]); + } + return decorator.onConnection(span, CONN, MONO); + } + + // Eight structurally-identical but distinct extractor types (so the mega site sees a rotating + // type). + static final class E0 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E1 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E2 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E3 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E4 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E5 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E6 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class E7 implements TagExtractor { + public void extract(String c, AgentSpan s) { + s.setTag(DB_USER, c); + } + } + + static final class BenchDbDecorator extends DatabaseClientDecorator { + private static final CharSequence COMPONENT = UTF8BytesString.create("benchmark"); + + @Override + protected String[] instrumentationNames() { + return new String[] {"benchmark"}; + } + + @Override + protected String service() { + return "benchmark-db"; + } + + @Override + protected CharSequence component() { + return COMPONENT; + } + + @Override + protected CharSequence spanType() { + return "sql"; + } + + @Override + protected String dbType() { + return "benchdb"; + } + + @Override + protected String dbInstance(String connection) { + return connection; + } + + @Override + protected CharSequence dbHostname(String connection) { + return null; + } + } + + private static class NoOpWriter implements Writer { + @Override + public void write(final List trace) {} + + @Override + public void start() {} + + @Override + public boolean flush() { + return false; + } + + @Override + public void close() {} + + @Override + public void incrementDropCounts(final int spanCount) {} + } +}