Skip to content

Commit e04674f

Browse files
committed
telemetry: emit socket_timeout in seconds to match receiver proto
The driver tracks socketTimeout in milliseconds, but the receiver proto field socket_timeout is defined in seconds. Convert ms -> s at export so a 15-minute timeout reports as 900s instead of 900000s. Adds regression tests covering the default value and sub-second rounding. Co-authored-by: Isaac
1 parent d3c3363 commit e04674f

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

lib/telemetry/DatabricksTelemetryExporter.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,13 @@ export default class DatabricksTelemetryExporter {
417417
use_proxy: metric.driverConfig.useProxy,
418418
enable_arrow: metric.driverConfig.arrowEnabled,
419419
enable_direct_results: metric.driverConfig.directResultsEnabled,
420-
socket_timeout: metric.driverConfig.socketTimeout,
420+
// The proto `socket_timeout` field is defined in seconds, but the driver
421+
// tracks socketTimeout in milliseconds — convert so the receiver records
422+
// the correct unit (e.g. 900000ms -> 900s) instead of treating ms as seconds.
423+
socket_timeout:
424+
typeof metric.driverConfig.socketTimeout === 'number'
425+
? Math.round(metric.driverConfig.socketTimeout / 1000)
426+
: metric.driverConfig.socketTimeout,
421427
enable_metric_view_metadata: metric.driverConfig.enableMetricViewMetadata,
422428
};
423429
}

tests/unit/telemetry/DatabricksTelemetryExporter.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,51 @@ describe('DatabricksTelemetryExporter', () => {
162162
});
163163
});
164164

165+
describe('export() - driver_connection_params', () => {
166+
// The driver tracks socketTimeout in milliseconds, but the receiver proto
167+
// defines `socket_timeout` in seconds. Lock in the ms -> s conversion so a
168+
// 15-minute (900000ms) timeout is reported as 900s, not 900000s.
169+
function getConnectionParams(sendRequestStub: sinon.SinonStub): any {
170+
const init = sendRequestStub.firstCall.args[1] as { body: string };
171+
const body = JSON.parse(init.body);
172+
const log = JSON.parse(body.protoLogs[0]);
173+
return log.entry.sql_driver_log.driver_connection_params;
174+
}
175+
176+
function makeConnectionMetric(socketTimeout: number): TelemetryMetric {
177+
return makeMetric({
178+
metricType: 'connection',
179+
driverConfig: {
180+
driverName: 'nodejs-sql-driver',
181+
driverVersion: '1.14.0',
182+
socketTimeout,
183+
} as any,
184+
});
185+
}
186+
187+
it('converts socketTimeout from milliseconds to seconds', async () => {
188+
const context = new ClientContextStub({ telemetryAuthenticatedExport: true } as any);
189+
const registry = new CircuitBreakerRegistry(context);
190+
const exporter = new DatabricksTelemetryExporter(context, 'host.example.com', registry, fakeAuthProvider);
191+
const sendRequestStub = sinon.stub(exporter as any, 'sendRequest').returns(makeOkResponse());
192+
193+
await exporter.export([makeConnectionMetric(900000)]);
194+
195+
expect(getConnectionParams(sendRequestStub).socket_timeout).to.equal(900);
196+
});
197+
198+
it('rounds sub-second socketTimeout values', async () => {
199+
const context = new ClientContextStub({ telemetryAuthenticatedExport: true } as any);
200+
const registry = new CircuitBreakerRegistry(context);
201+
const exporter = new DatabricksTelemetryExporter(context, 'host.example.com', registry, fakeAuthProvider);
202+
const sendRequestStub = sinon.stub(exporter as any, 'sendRequest').returns(makeOkResponse());
203+
204+
await exporter.export([makeConnectionMetric(1500)]);
205+
206+
expect(getConnectionParams(sendRequestStub).socket_timeout).to.equal(2);
207+
});
208+
});
209+
165210
describe('export() - retry logic', () => {
166211
it('should retry on retryable HTTP errors (503)', async () => {
167212
const context = new ClientContextStub({ telemetryMaxRetries: 2 } as any);

0 commit comments

Comments
 (0)