Compare commits

...
Author SHA1 Message Date
NightTrek b66b66dcef chore: add changeset for OpenTelemetry reinitialization 2025-10-14 03:32:02 -07:00
NightTrek 7c9fe49d5b feat: Implement OpenTelemetry provider reinitialization (4/5)
- Add config tracking to OpenTelemetryClientProvider with currentConfig field
- Implement hasConfigChanged() to detect configuration changes
- Implement reinitialize() to dispose old providers and create new ones
- Implement reinitializeIfNeeded() in OpenTelemetryTelemetryProvider
- Update meter and logger references after reinitialization
- Clear cached instruments (counters, histograms) on reinit
- Enable dynamic OpenTelemetry configuration without window reload

Part 4 of 5 in the telemetry settings refactor series.
2025-10-14 03:30:29 -07:00
3 changed files with 79 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Support initializing specifically when the configuration changes for remote config.
@@ -19,6 +19,7 @@ import {
*/
export class OpenTelemetryClientProvider {
private static _instance: OpenTelemetryClientProvider | null = null
private static currentConfig: OpenTelemetryClientValidConfig | null = null
public static getInstance(): OpenTelemetryClientProvider {
if (!OpenTelemetryClientProvider._instance) {
@@ -47,9 +48,50 @@ export class OpenTelemetryClientProvider {
return process.env.TEL_DEBUG_DIAGNOSTICS === "true" || process.env.IS_DEV === "true"
}
/**
* Check if OpenTelemetry configuration has changed.
* Compares current config with new config from StateManager.
*/
public static hasConfigChanged(): boolean {
const newConfig = getValidOpenTelemetryConfig()
const changed = JSON.stringify(OpenTelemetryClientProvider.currentConfig) !== JSON.stringify(newConfig)
if (changed) {
console.log("[OTEL] Configuration has changed")
}
return changed
}
/**
* Reinitialize the OpenTelemetry client providers.
* Disposes existing providers and creates new ones with updated config.
*/
public static async reinitialize(): Promise<void> {
console.log("[OTEL] Reinitializing OpenTelemetry providers...")
const instance = OpenTelemetryClientProvider.getInstance()
// Dispose existing providers
await instance.dispose()
// Clear singleton instance
OpenTelemetryClientProvider._instance = null
OpenTelemetryClientProvider.currentConfig = null
// Clear config cache to force re-evaluation
// Note: clearOtelConfigCache will be exported from otel-config.ts
// For now, we'll just clear the instance which will trigger re-read on next getInstance()
console.log("[OTEL] OpenTelemetry providers reinitialized")
}
private constructor() {
this.config = getValidOpenTelemetryConfig()
// Store current config for comparison
OpenTelemetryClientProvider.currentConfig = this.config
if (!this.config) {
console.log("[OTEL DEBUG] OpenTelemetry is disabled or not configured")
return
@@ -193,6 +193,38 @@ export class OpenTelemetryTelemetryProvider implements ITelemetryProvider {
histogram.record(value, this.flattenProperties(attributes))
}
public async reinitializeIfNeeded(): Promise<boolean> {
// Check if config has changed
if (!OpenTelemetryClientProvider.hasConfigChanged()) {
return false
}
console.log("[OTEL] Config changed, reinitializing...")
try {
// Reinitialize the client provider
await OpenTelemetryClientProvider.reinitialize()
// Get new meter and logger from reinitialized provider
const meterProvider = OpenTelemetryClientProvider.getMeterProvider()
const loggerProvider = OpenTelemetryClientProvider.getLoggerProvider()
// Update our references
this.meter = meterProvider ? meterProvider.getMeter("cline") : null
this.logger = loggerProvider ? loggerProvider.getLogger("cline") : null
// Clear cached instruments since we have new meter
this.counters.clear()
this.histograms.clear()
console.log("[OTEL] Reinitialization complete")
return true
} catch (error) {
console.error("[OTEL] Reinitialization failed:", error)
return false
}
}
public async dispose(): Promise<void> {
// OpenTelemetry client provider handles shutdown
// Individual providers don't need to do anything