/** * Copyright (c) 2025 Databricks Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import IClientContext, { ClientConfig } from '../contracts/IClientContext'; import IDBSQLLogger from '../contracts/IDBSQLLogger'; import IConnectionProvider from '../connection/contracts/IConnectionProvider'; import IThriftClient from '../contracts/IThriftClient'; import IDriver from '../contracts/IDriver'; import IAuthentication from '../connection/contracts/IAuthentication'; import { CircuitBreakerState } from './CircuitBreaker'; import DatabricksTelemetryExporter from './DatabricksTelemetryExporter'; import MetricsAggregator from './MetricsAggregator'; import FeatureFlagCache from './FeatureFlagCache'; /** * Per-host telemetry resource owner. Held by `TelemetryClientProvider` * (process-wide singleton) and shared across every `DBSQLClient` that * connects to the same host. * * Owns the host-scoped triad — `MetricsAggregator`, `DatabricksTelemetryExporter`, * `CircuitBreakerRegistry`, `FeatureFlagCache` — and implements `IClientContext` * itself so those owned components have a stable context that outlives any * single `DBSQLClient`. The first registered `DBSQLClient`'s logger and config * are snapshotted; subsequent registrants donate their connection providers * and auth providers, and the `TelemetryClient` falls through them in * registration order when the current head closes. * * Why share at host granularity: * - Circuit-breaker state for `host` is correct only if all clients hitting * the same endpoint share counters (5 failures means 5 actual failures, not * 5×N for N independent `DBSQLClient` instances). * - Feature-flag cache has a per-host TTL; deduping the GET prevents * thundering-herd on cold cache. * - Metric batches mix events from every active client to the same host — * one HTTP POST per `flushIntervalMs` instead of N. */ declare class TelemetryClient implements IClientContext { readonly host: string; private closed; private readonly logger; private readonly config; private readonly circuitBreakerRegistry; private readonly featureFlagCache; private readonly exporter; private readonly aggregator; private contexts; constructor(initialContext: IClientContext, host: string); /** * Add another `DBSQLClient`'s context to the pool. Tracked in registration * order; `getConnectionProvider()` / `getAuthProvider()` walk the list and * use the first entry that's still usable. */ registerContext(context: IClientContext): void; private warnOnConfigDivergence; /** * Remove a `DBSQLClient`'s context from the pool. Called by * `TelemetryClientProvider.releaseClient` before refcount decrement so the * exporter doesn't keep trying to use a closed context. * * Uses the cached snapshot pair (`context`, `authProvider`) from register * time, not a fresh `context.getAuthProvider?.()` call. If the underlying * client's auth provider was rotated, a fresh call would not match the * original reference and the stale entry would leak. */ unregisterContext(context: IClientContext): void; getConfig(): ClientConfig; getLogger(): IDBSQLLogger; getConnectionProvider(): Promise; getClient(): Promise; getDriver(): Promise; /** * Walk `contexts` and return the first call site that succeeds. Contexts * that throw on the same accessor for `MAX_CONSECUTIVE_CTX_FAILURES` calls * in a row are pruned from the pool — otherwise a registrant whose * underlying `DBSQLClient` is closed or has revoked auth would stay in the * list forever and be retried on every export. * * Pruning is keyed by the `accessor` function identity so a context with a * working `getConnectionProvider` but broken `getDriver` isn't dropped from * the working accessor's path. */ private tryFallthrough; getAuthProvider(): IAuthentication | undefined; getTelemetryEmitter(): undefined; getTelemetryAggregator(): MetricsAggregator; getExporter(): DatabricksTelemetryExporter; getAggregator(): MetricsAggregator; getFeatureFlagCache(): FeatureFlagCache; /** * Operator-visible snapshot of telemetry state for this host. Synchronous, * never throws — intended for health-check endpoints, shutdown banners, * and operator dashboards. */ getTelemetryStats(): { host: string; pendingMetricsCount: number; inFlightStatements: number; droppedMetrics: number; evictedStatements: number; circuitBreakerState: CircuitBreakerState; }; getHost(): string; isClosed(): boolean; /** * Drain pending metrics and tear down owned resources. Called by * `TelemetryClientProvider.releaseClient` when refCount hits zero. */ close(): Promise; } export default TelemetryClient;