Skip to content

sqlQuery metrics always emit null remoteAddress for JDBC/Avatica queries #19230

@dprmfl

Description

@dprmfl

Description

remoteAddress is always null for queries executed via JDBC/Avatica, even though it's a documented dimension for sqlQuery/time, sqlQuery/bytes, and sqlQuery/planningTimeMs
(see metrics docs). The HTTP SQL API populates it correctly.

HTTP SQL API (/druid/v2/sql/)

curl -X POST http://localhost:8082/druid/v2/sql/ \
  -H 'Content-Type: application/json' \
  -d '{"query": "SELECT COUNT(*) FROM wikipedia"}'
{ "metric": "sqlQuery/time", "remoteAddress": "127.0.0.1", "value": 123 }

JDBC/Avatica (/druid/v2/sql/avatica/)

Connection conn = DriverManager.getConnection(
    "jdbc:avatica:remote:url=http://localhost:8082/druid/v2/sql/avatica/");
conn.createStatement().executeQuery("SELECT COUNT(*) FROM wikipedia");
{ "metric": "sqlQuery/time", "remoteAddress": null, "value": 123 }

Motivation

Without remoteAddress in JDBC metrics, operators can't debug which client is causing slow queries, attribute load to specific tenants, or meet audit requirements (GDPR, HIPAA, SOC2). This is especially painful given how widely JDBC is used — Tableau, Superset, and most BI tools connect via Avatica.

Root cause

In PreparedStatement.java and SqlStatementFactory.java, remoteAddress is hardcoded as null when constructing DirectStatement via the Avatica path. The HTTP path (SqlResource.java) correctly passes httpRequest.getRemoteAddr().

Proposed fix

  1. DruidAvaticaJsonHandler — capture remoteAddr from the incoming
    request and stash it in a ThreadLocal
  2. DruidMeta.openDruidConnection() — pull from ThreadLocal, inject
    into the connection context map
  3. PreparedStatement — read from context, pass to DirectStatement
    (parameterized query path)
  4. SqlStatementFactory — same, for the direct query path

This approach requires no changes to DruidConnection or any data
structures — remoteAddress flows entirely through the existing
context map mechanism.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions