Skip to content

Client config reporting — stage 1 (groundwork): SESSION_ID + DRIVER_CONFIG plumbing#967

Open
nikagra wants to merge 1 commit into
scylladb:scylla-4.xfrom
nikagra:feature/driver-config-reporting
Open

Client config reporting — stage 1 (groundwork): SESSION_ID + DRIVER_CONFIG plumbing#967
nikagra wants to merge 1 commit into
scylladb:scylla-4.xfrom
nikagra:feature/driver-config-reporting

Conversation

@nikagra

@nikagra nikagra commented Jul 22, 2026

Copy link
Copy Markdown

What ☑️

Stage 1 (groundwork) of driver configuration reporting: the mechanism for the driver to report its effective client configuration to ScyllaDB at connection time, so operators can inspect driver settings (via system.clients.client_options) while investigating incidents. Follows the cross-driver JSON schema design.

This is phase 1 of 2 and is intentionally a draft — it lands the plumbing; the full configuration report (all groups) comes in phase 2.

Behavior 🚸

Gated behind a new option advanced.client-config-reporting.enabled, which ships disabled — when off there is zero change on the wire. When enabled:

  • SESSION_ID — a dedicated, driver-generated per-session UUID, sent on every connection (control and pool) as a STARTUP option, so the server can group all of a session's connections. Independent of the user-settable CLIENT_ID (so it is guaranteed unique per session).
  • DRIVER_CONFIG — a compact JSON blob, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in phase 2.

Both entries are produced by a new DriverConfigReporter, invoked per connection from ProtocolInitHandler and evaluated fresh (so toggling the flag at runtime takes effect on new connections). Reporting is fail-safe: any failure while building the report is swallowed and never breaks connection initialization.

Changes ✍️

  • New option registered consistently: DefaultDriverOption, TypedDriverOption, OptionsMap.driverDefaults(), reference.conf.
  • New DriverConfigReporter / DefaultDriverConfigReporter on the driver context (per-session singleton holding the dedicated session id).
  • Control connection marked via a new DriverChannelOptions.reportConfig flag; hook added in ProtocolInitHandler.

Testing 🔨

Unit tests 💻

  • New DefaultDriverConfigReporterTest; updated ProtocolInitHandlerTest and ChannelFactoryTestBase.
  • Config-consistency guards green (TypedDriverOptionTest, MapBasedDriverConfigLoaderTest, TypesafeDriverConfigTest).
  • Full core unit test suite green: 3865 tests, 0 failures.

Manual tests ✋

Environment: 🌌

  • Single node ScyllaDB 2026.2 on CCM
  • Minimal programmatic config:
    • CLIENT_CONFIG_REPORTING_ENABLED ➡️ true
    • contact point: 127.0.0.1:9042

Sample 1: Control connection STARTUP frame

Note

Note both DRIVER_CONFIG and SESSION_ID are present

Frame 38: 387 bytes on wire (3096 bits), 387 bytes captured (3096 bits) on interface lo, id 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 46926, Dst Port: 9042, Seq: 10, Ack: 486, Len: 321
Cassandra CQL Protocol
    Version: 0x04
        .... 0100 = Protocol version: 4
        0000 .... = Direction: Request (0x0)
    Flags: 0x00
        .... ...0 = Compression: False
        .... ..0. = Tracing: False
        .... .0.. = Custom Payload: False
        .... 0... = Warning: False
        0000 .... = Reserved: 0x0
    Stream Identifier: 0
    .000 0001 = Opcode: STARTUP (1)
    Message Length: 312
    Message STARTUP
        String Map Size: 9
        String Length: 11
        String: CQL_VERSION
        String Length: 5
        String: 3.0.0
        String Length: 14
        String: DRIVER_VERSION
        String Length: 17
        String: 4.19.2.1-SNAPSHOT
        String Length: 9
        String: CLIENT_ID
        String Length: 36
        String: 74fd4af1-3983-427d-b7bf-a09a2e3a8d6c
        String Length: 13
        String: DRIVER_CONFIG
        String Length: 13
        String: {"version":1}
        String Length: 28
        String: SCYLLA_LWT_ADD_METADATA_MARK
        String Length: 11
        String: -2147483648
        String Length: 22
        String: SCYLLA_USE_METADATA_ID
        String Length: 0
        String: 
        String Length: 11
        String: DRIVER_NAME
        String Length: 20
        String: ScyllaDB Java Driver
        String Length: 18
        String: TABLETS_ROUTING_V1
        String Length: 0
        String: 
        String Length: 10
        String: SESSION_ID
        String Length: 36
        String: 540dae6d-3f30-4fb0-ba63-d1c28a3a52b6

Sample 2: Connection STARTUP frame

Note

Note just SESSION_ID is present

Frame 70: 357 bytes on wire (2856 bits), 357 bytes captured (2856 bits) on interface lo, id 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 46928, Dst Port: 9042, Seq: 10, Ack: 486, Len: 291
Cassandra CQL Protocol
    Version: 0x04
        .... 0100 = Protocol version: 4
        0000 .... = Direction: Request (0x0)
    Flags: 0x00
        .... ...0 = Compression: False
        .... ..0. = Tracing: False
        .... .0.. = Custom Payload: False
        .... 0... = Warning: False
        0000 .... = Reserved: 0x0
    Stream Identifier: 0
    .000 0001 = Opcode: STARTUP (1)
    Message Length: 282
    Message STARTUP
        String Map Size: 8
        String Length: 11
        String: CQL_VERSION
        String Length: 5
        String: 3.0.0
        String Length: 14
        String: DRIVER_VERSION
        String Length: 17
        String: 4.19.2.1-SNAPSHOT
        String Length: 9
        String: CLIENT_ID
        String Length: 36
        String: 74fd4af1-3983-427d-b7bf-a09a2e3a8d6c
        String Length: 28
        String: SCYLLA_LWT_ADD_METADATA_MARK
        String Length: 11
        String: -2147483648
        String Length: 22
        String: SCYLLA_USE_METADATA_ID
        String Length: 0
        String: 
        String Length: 11
        String: DRIVER_NAME
        String Length: 20
        String: ScyllaDB Java Driver
        String Length: 18
        String: TABLETS_ROUTING_V1
        String Length: 0
        String: 
        String Length: 10
        String: SESSION_ID
        String Length: 36
        String: 540dae6d-3f30-4fb0-ba63-d1c28a3a52b6

Sample 3: Control connection STARTUP frame (CLIENT_CONFIG_REPORTING_ENABLED is false)

Note

Note neither DRIVER_CONFIG nor SESSION_ID is present

Frame 133: 307 bytes on wire (2456 bits), 307 bytes captured (2456 bits) on interface lo, id 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 32862, Dst Port: 9042, Seq: 10, Ack: 486, Len: 241
Cassandra CQL Protocol
    Version: 0x04
        .... 0100 = Protocol version: 4
        0000 .... = Direction: Request (0x0)
    Flags: 0x00
        .... ...0 = Compression: False
        .... ..0. = Tracing: False
        .... .0.. = Custom Payload: False
        .... 0... = Warning: False
        0000 .... = Reserved: 0x0
    Stream Identifier: 0
    .000 0001 = Opcode: STARTUP (1)
    Message Length: 232
    Message STARTUP
        String Map Size: 7
        String Length: 11
        String: CQL_VERSION
        String Length: 5
        String: 3.0.0
        String Length: 22
        String: SCYLLA_USE_METADATA_ID
        String Length: 0
        String: 
        String Length: 11
        String: DRIVER_NAME
        String Length: 20
        String: ScyllaDB Java Driver
        String Length: 18
        String: TABLETS_ROUTING_V1
        String Length: 0
        String: 
        String Length: 14
        String: DRIVER_VERSION
        String Length: 17
        String: 4.19.2.1-SNAPSHOT
        String Length: 9
        String: CLIENT_ID
        String Length: 36
        String: ecf2f66b-6757-4189-b11d-3b9b8d534614
        String Length: 28
        String: SCYLLA_LWT_ADD_METADATA_MARK
        String Length: 11
        String: -2147483648

Follow-up (phase 2)

  • Populate the full configuration report (connection / socket / policies / connection pool / query defaults / tls) per the schema.
  • Prerequisite before flipping the flag default on: confirm ScyllaDB tolerates unknown STARTUP keys and has no problematic client_options value-length cap.

Fixes DRIVER-832

🤖 Generated with Claude Code

…plumbing)

Stage 1 of driver configuration reporting: the mechanism to report a client's
effective configuration to ScyllaDB at connection time, so operators can inspect
driver settings (via system.clients.client_options) while investigating incidents.

Gated behind a new option, advanced.client-config-reporting.enabled, which
ships disabled — when off there is zero change on the wire. When enabled:

- SESSION_ID: a dedicated, driver-generated per-session UUID, sent on every
  connection (control and pool) so the server can group a session's
  connections. Independent of the user-settable CLIENT_ID.
- DRIVER_CONFIG: a compact JSON blob, sent only on the control connection.
  Stage 1 emits only {"version":1}; the full configuration report follows in
  stage 2.

Both entries are produced by a new DriverConfigReporter, invoked per connection
from ProtocolInitHandler and evaluated fresh (so toggling the flag at runtime
takes effect on new connections). Reporting is fail-safe: any failure while
building the report is swallowed and never breaks connection initialization.

The config option is registered consistently across DefaultDriverOption,
TypedDriverOption, OptionsMap.driverDefaults() and reference.conf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds the CLIENT_CONFIG_REPORTING_ENABLED driver option, defaulting to false. A lazily initialized reporter creates a stable session ID and optionally emits compact configuration JSON. Control connections set reportConfig(true), while pool connections do not. Protocol initialization adds the resulting values to STARTUP options, and failures are logged without interrupting connection setup. Tests cover configuration modes, connection scope, session identity, and failure handling.

Sequence Diagram(s)

sequenceDiagram
  participant ControlConnection
  participant ProtocolInitHandler
  participant DriverConfigReporter
  participant ScyllaDB
  ControlConnection->>ProtocolInitHandler: initialize channel with reportConfig(true)
  ProtocolInitHandler->>DriverConfigReporter: populateStartupOptions(options, true)
  DriverConfigReporter-->>ProtocolInitHandler: SESSION_ID and DRIVER_CONFIG
  ProtocolInitHandler->>ScyllaDB: send STARTUP options
Loading

Suggested labels: P1, area/Driver_-_java-driver-4.x

Suggested reviewers: dkropachev

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: client config reporting groundwork with SESSION_ID and DRIVER_CONFIG plumbing.
Description check ✅ Passed The description is directly related and accurately explains the feature, behavior, and implementation changes in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PMD (7.26.0)
core/src/main/java/com/datastax/oss/driver/internal/core/channel/ProtocolInitHandler.java

openjdk version "17.0.19" 2026-04-21 LTS
OpenJDK Runtime Environment Corretto-17.0.19.10.1 (build 17.0.19+10-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.19.10.1 (build 17.0.19+10-LTS, mixed mode, sharing)
/usr/local/bin/pmd: line 89: 22 Aborted java -version > /dev/null 2>&1
No java executable found in PATH


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java`:
- Around line 1178-1184: Update the enabled-flag documentation in
DefaultDriverOption and the matching reference.conf entry so it states that both
SESSION_ID and DRIVER_CONFIG are emitted only when reporting is enabled, while
preserving their differing connection scopes: SESSION_ID on every connection and
DRIVER_CONFIG on the control connection only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a34d18a8-2a95-4e3b-ab1e-3c1e44ca6f84

📥 Commits

Reviewing files that changed from the base of the PR and between 8750e68 and f3b31e2.

📒 Files selected for processing (14)
  • core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java
  • core/src/main/java/com/datastax/oss/driver/api/core/config/OptionsMap.java
  • core/src/main/java/com/datastax/oss/driver/api/core/config/TypedDriverOption.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/channel/DriverChannelOptions.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/channel/ProtocolInitHandler.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporter.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverContext.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/context/DriverConfigReporter.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/context/InternalDriverContext.java
  • core/src/main/java/com/datastax/oss/driver/internal/core/control/ControlConnection.java
  • core/src/main/resources/reference.conf
  • core/src/test/java/com/datastax/oss/driver/internal/core/channel/ChannelFactoryTestBase.java
  • core/src/test/java/com/datastax/oss/driver/internal/core/channel/ProtocolInitHandlerTest.java
  • core/src/test/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporterTest.java

Comment on lines +1178 to +1184
* Whether the driver reports its effective client configuration to ScyllaDB at connection time.
*
* <p>When {@code true}, the driver sends a compact JSON description of its configuration in the
* CQL {@code STARTUP} options under the {@code DRIVER_CONFIG} key (control connection only);
* ScyllaDB stores it in {@code system.clients.client_options} so operators can inspect driver
* settings while investigating incidents. Independently of this flag, a {@code SESSION_ID}
* startup option is sent on every connection so the server can group a session's connections.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the enabled-flag documentation. SESSION_ID is not independent of this flag: when reporting is disabled, the reporter emits neither startup option.

  • core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java#L1178-L1184: state that both SESSION_ID and DRIVER_CONFIG are sent only when enabled, with their differing connection scopes.
  • core/src/main/resources/reference.conf#L1209-L1221: make the same correction in the user-facing reference configuration.
📍 Affects 2 files
  • core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java#L1178-L1184 (this comment)
  • core/src/main/resources/reference.conf#L1209-L1221
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java`
around lines 1178 - 1184, Update the enabled-flag documentation in
DefaultDriverOption and the matching reference.conf entry so it states that both
SESSION_ID and DRIVER_CONFIG are emitted only when reporting is enabled, while
preserving their differing connection scopes: SESSION_ID on every connection and
DRIVER_CONFIG on the control connection only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant