()
| 251 | * Call this early in the application lifecycle |
| 252 | */ |
| 253 | export function initializePerfettoTracing(): void { |
| 254 | const envValue = process.env.CLAUDE_CODE_PERFETTO_TRACE |
| 255 | logForDebugging( |
| 256 | `[Perfetto] initializePerfettoTracing called, env value: ${envValue}`, |
| 257 | ) |
| 258 | |
| 259 | // Wrap in feature() for dead code elimination - entire block removed from external builds |
| 260 | if (feature('PERFETTO_TRACING')) { |
| 261 | if (!envValue || isEnvDefinedFalsy(envValue)) { |
| 262 | logForDebugging( |
| 263 | '[Perfetto] Tracing disabled (env var not set or disabled)', |
| 264 | ) |
| 265 | return |
| 266 | } |
| 267 | |
| 268 | isEnabled = true |
| 269 | startTimeMs = Date.now() |
| 270 | |
| 271 | // Determine trace file path |
| 272 | if (isEnvTruthy(envValue)) { |
| 273 | const tracesDir = join(getClaudeConfigHomeDir(), 'traces') |
| 274 | tracePath = join(tracesDir, `trace-${getSessionId()}.json`) |
| 275 | } else { |
| 276 | // Use the provided path |
| 277 | tracePath = envValue |
| 278 | } |
| 279 | |
| 280 | logForDebugging( |
| 281 | `[Perfetto] Tracing enabled, will write to: ${tracePath}, isEnabled=${isEnabled}`, |
| 282 | ) |
| 283 | |
| 284 | // Start periodic full-trace write if CLAUDE_CODE_PERFETTO_WRITE_INTERVAL_S is a positive integer |
| 285 | const intervalSec = parseInt( |
| 286 | process.env.CLAUDE_CODE_PERFETTO_WRITE_INTERVAL_S ?? '', |
| 287 | 10, |
| 288 | ) |
| 289 | if (intervalSec > 0) { |
| 290 | writeIntervalId = setInterval(() => { |
| 291 | void periodicWrite() |
| 292 | }, intervalSec * 1000) |
| 293 | // Don't let the interval keep the process alive on its own |
| 294 | if (writeIntervalId.unref) writeIntervalId.unref() |
| 295 | logForDebugging( |
| 296 | `[Perfetto] Periodic write enabled, interval: ${intervalSec}s`, |
| 297 | ) |
| 298 | } |
| 299 | |
| 300 | // Start stale span cleanup interval |
| 301 | staleSpanCleanupId = setInterval(() => { |
| 302 | evictStaleSpans() |
| 303 | evictOldestEvents() |
| 304 | }, STALE_SPAN_CLEANUP_INTERVAL_MS) |
| 305 | if (staleSpanCleanupId.unref) staleSpanCleanupId.unref() |
| 306 | |
| 307 | // Register cleanup to write final trace on exit |
| 308 | registerCleanup(async () => { |
| 309 | logForDebugging('[Perfetto] Cleanup callback invoked') |
| 310 | await writePerfettoTrace() |
no test coverage detected