feat(csharp): implement telemetry context models (StatementTelemetryContext, TelemetrySessionContext)#301
Conversation
There was a problem hiding this comment.
Pull request overview
Implements C# telemetry context models to support the V3 “direct object” telemetry approach, adds unit tests for the new contexts, and updates telemetry JSON formatting/exporter behavior plus related documentation.
Changes:
- Added
TelemetrySessionContext(per-connection) andStatementTelemetryContext(per-statement) models, with proto-building viaBuildTelemetryLog(). - Added unit tests covering construction/defaults and
BuildTelemetryLog()output scenarios. - Updated proto JSON conversion to emit snake_case field names and hardened telemetry exporter endpoint URL building.
Reviewed changes
Copilot reviewed 9 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| csharp/src/Telemetry/TelemetrySessionContext.cs | Introduces session-level telemetry context + placeholder ITelemetryClient. |
| csharp/src/Telemetry/StatementTelemetryContext.cs | Introduces statement-level telemetry context + proto log construction. |
| csharp/src/Telemetry/ProtoJsonConverter.cs | Switches proto JSON formatting to preserve proto field names (snake_case). |
| csharp/src/Telemetry/DatabricksTelemetryExporter.cs | Ensures host has an http/https scheme when building endpoint URL. |
| csharp/test/Unit/Telemetry/TelemetrySessionContextTests.cs | Adds unit tests for session context construction/defaults. |
| csharp/test/Unit/Telemetry/StatementTelemetryContextTests.cs | Adds unit tests for statement context lifecycle + proto building. |
| csharp/doc/telemetry-design.md | Updates design doc to V3 direct-object telemetry approach and related requirements. |
| csharp/doc/telemetry-sprint-plan-2026-03-05.md | Adds/updates sprint plan documentation for telemetry work. |
| csharp/doc/sprint-plan-telemetry-completion-2026-03-03.md | Adds/updates earlier sprint plan documentation. |
| csharp/CODING_GUIDELINES.md | Adds C# coding/testing guidelines. |
| .gitignore | Ignores generated_task_specs.json. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | Proto Field | Validation | | ||
| |-------------|------------| | ||
| | `error_name` | Non-empty, contains exception type name | | ||
| | `stack_trace` | Non-empty, contains error message | |
There was a problem hiding this comment.
The DriverErrorInfo table says stack_trace should be non-empty and contain the error message, but the proto comment describes stack_trace as Databricks-owned stack info, and the current implementation intentionally sets it to empty for privacy. Please align this doc section with the actual schema/behavior (and consider documenting whether client error messages are intentionally excluded).
| | `stack_trace` | Non-empty, contains error message | | |
| | `stack_trace` | Optional; currently empty for privacy; reserved for Databricks-owned stack info (client error messages are not included) | |
| - Test files: `<ClassName>Test.cs` | ||
| - Test class: `<ClassName>Test` | ||
| - Test methods: Descriptive names explaining the scenario |
There was a problem hiding this comment.
The guideline here states test files/classes should be named <ClassName>Test, but the existing test suite uses multiple patterns (e.g., *Tests.cs, *UnitTests.cs). To avoid confusion, consider rewording this as a recommendation or updating it to match the predominant convention used in this repo.
| - Test files: `<ClassName>Test.cs` | |
| - Test class: `<ClassName>Test` | |
| - Test methods: Descriptive names explaining the scenario | |
| - Prefer naming test files after the class under test, for example: `<ClassName>Tests.cs` or `<ClassName>Test.cs`. | |
| - Prefer naming test classes after the class under test, for example: `<ClassName>Tests` or `<ClassName>Test`. | |
| - When adding tests to existing areas, follow the predominant naming convention in that project or directory (e.g., `*Tests.cs`, `*UnitTests.cs`) to keep things consistent. | |
| - Test methods: Use descriptive names that clearly explain the scenario and expected behavior. |
| /// <remarks> | ||
| /// This class holds frozen session-level data that does not change for the lifetime of a connection. | ||
| /// All properties have private setters to ensure immutability after construction. | ||
| /// Use the constructor or object initializer to set values. | ||
| /// </remarks> |
There was a problem hiding this comment.
The remarks say the session context is immutable with private setters / init-only semantics, but the properties in this type are declared with public setters. Either make the properties init-only/private-set (and adjust construction accordingly) or update the remarks to match the actual mutability.
| // Add chunk details if present | ||
| if (TotalChunksPresent.HasValue || TotalChunksIterated.HasValue) |
There was a problem hiding this comment.
ChunkDetails is only included when TotalChunksPresent or TotalChunksIterated is set, but other chunk-related fields (InitialChunkLatencyMs/SlowestChunkLatencyMs/SumChunksDownloadTimeMs) can be set independently via public setters and would be dropped from the emitted proto. Consider expanding the condition to include any chunk-detail field, or make chunk fields private-set and require SetChunkDetails() so the invariants are enforced.
| // Add chunk details if present | |
| if (TotalChunksPresent.HasValue || TotalChunksIterated.HasValue) | |
| // Add chunk details if any chunk-related metric is present | |
| if (TotalChunksPresent.HasValue | |
| || TotalChunksIterated.HasValue | |
| || InitialChunkLatencyMs.HasValue | |
| || SlowestChunkLatencyMs.HasValue | |
| || SumChunksDownloadTimeMs.HasValue) |
| Thread.Sleep(10); // Small delay to ensure stopwatch is running | ||
|
|
||
| // Assert | ||
| Assert.NotNull(context.ExecuteStopwatch); | ||
| Assert.True(context.ExecuteStopwatch.IsRunning); | ||
| Assert.True(context.ExecuteStopwatch.ElapsedMilliseconds > 0); |
There was a problem hiding this comment.
These unit tests rely on Thread.Sleep with very small delays to assert Stopwatch timing, which can be flaky under CI load/clock granularity. Prefer a deterministic approach (e.g., assert ordering without requiring >0ms, use SpinWait with a bounded timeout, or abstract time/stopwatch so tests can control elapsed time).
| Thread.Sleep(10); // Small delay to ensure stopwatch is running | |
| // Assert | |
| Assert.NotNull(context.ExecuteStopwatch); | |
| Assert.True(context.ExecuteStopwatch.IsRunning); | |
| Assert.True(context.ExecuteStopwatch.ElapsedMilliseconds > 0); | |
| // Assert | |
| Assert.NotNull(context.ExecuteStopwatch); | |
| Assert.True(context.ExecuteStopwatch.IsRunning); |
## 🥞 Stacked PR Use this [link](https://github.com/adbc-drivers/databricks/pull/286/files) to review incremental changes. - [**stack/add-design-plan**](#286) [[Files changed](https://github.com/adbc-drivers/databricks/pull/286/files)] - [stack/itr5-pr-telemetry-models](#301) [[Files changed](https://github.com/adbc-drivers/databricks/pull/301/files/5ad8bcbf56dd6d6d57d8138f33108f80c36eb42e..aa902284c764d97c256d41f2ab8da169b1068b52)] - [stack/itr5-pr-telemetry-client-impl](#305) [[Files changed](https://github.com/adbc-drivers/databricks/pull/305/files/aa902284c764d97c256d41f2ab8da169b1068b52..7ee3e3f38747c8538acccc305a77c9d9e4d96a0b)] - [stack/itr5-pr-e2e-tests](#308) [[Files changed](https://github.com/adbc-drivers/databricks/pull/308/files/7ee3e3f38747c8538acccc305a77c9d9e4d96a0b..06e6163ad49d2079216f7808234e0ffdd8300975)] --------- ## What's Changed Please fill in a description of the changes here. **This contains breaking changes.** <!-- Remove this line if there are no breaking changes. --> Closes #NNN. --------- Co-authored-by: Jade Wang <jade.wang+data@databricks.com>
…sk ID: task-1.2-statement-telemetry-context
GetEndpointUrl now ensures the host has a scheme prefix before constructing the telemetry endpoint URL. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use JsonFormatter with PreserveProtoFieldNames(true) instead of JsonFormatter.Default to produce snake_case field names (session_id, system_configuration, etc.) matching the JDBC driver and proto schema. Default produces camelCase (sessionId) which is incorrect. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file was accidentally committed and should not be tracked. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aa90228 to
7e6c6cd
Compare
samikshya-db
left a comment
There was a problem hiding this comment.
This has been verified to match with https://github.com/databricks-eng/universe/blob/master/proto/logs/frontend/oss-sql-driver-telemetry/sql_driver_telemetry.proto right?
yes |
|
🚀 Integration tests triggered! View workflow run |
🥞 Stacked PR
Use this link to review incremental changes.
What's Changed
Please fill in a description of the changes here.
This contains breaking changes.
Closes #NNN.