/** * Example: QueryCache Telemetry Integration * * Shows how to integrate OpenTelemetry observability into QueryCache. */ import { recordCacheAccess, recordMetric } from '../src/observability'; class QueryCacheWithTelemetry { /** * Example: Cache get with telemetry */ get(key: string): T | undefined { const entry = this.cache.get(key); // Record cache hit/miss recordCacheAccess(key, entry !== undefined); if (!entry) { return undefined; } // Check expiration const now = Date.now(); if (now - entry.timestamp > entry.ttl) { this.cache.delete(key); // Record expired entry as miss recordCacheAccess(key, false); // Record expiration metric recordMetric('operation', { operationType: 'cache_expiration', tableName: 'cache', }); return undefined; } // Update statistics entry.hits++; // Record hit with metadata recordMetric('cache_hit', { key }); return entry.value as T; } /** * Example: Cache set with telemetry */ set(key: string, value: T, ttl: number = 300000): void { const size = this.estimateSize(value); // Check if we need to evict if (this.cache.size >= this.maxSize) { this.evictLRU(); // Record eviction recordMetric('operation', { operationType: 'cache_eviction', tableName: 'cache', }); } // Store entry this.cache.set(key, { value, key, timestamp: Date.now(), ttl, size, hits: 0, }); // Record cache write recordMetric('operation', { operationType: 'cache_write', tableName: 'cache', resultSize: size, }); } /** * Example: Cache invalidation with telemetry */ invalidateCategory(category: string): number { let count = 0; const keysToDelete: string[] = []; for (const [key] of this.cache) { if (key.startsWith(`${category}:`)) { keysToDelete.push(key); } } for (const key of keysToDelete) { this.cache.delete(key); count++; } // Record invalidation recordMetric('operation', { operationType: 'cache_invalidation', tableName: 'cache', resultSize: count, }); return count; } /** * Example: Cache statistics with telemetry */ getStatistics(): any { const stats = { hits: this.hits, misses: this.misses, hitRate: 0, size: this.cache.size, capacity: this.maxSize, evictions: this.evictions, memoryUsed: 0, entriesByCategory: {}, }; // Calculate hit rate const total = stats.hits + stats.misses; stats.hitRate = total > 0 ? (stats.hits / total) * 100 : 0; // Record statistics as metrics recordMetric('operation', { operationType: 'cache_stats_request', tableName: 'cache', }); return stats; } /** * Example: Prune expired entries with telemetry */ pruneExpired(): number { const now = Date.now(); const keysToDelete: string[] = []; for (const [key, entry] of this.cache) { if (now - entry.timestamp > entry.ttl) { keysToDelete.push(key); } } for (const key of keysToDelete) { this.cache.delete(key); } // Record pruning recordMetric('operation', { operationType: 'cache_prune', tableName: 'cache', resultSize: keysToDelete.length, }); return keysToDelete.length; } // Placeholder methods and properties private cache = new Map(); private maxSize = 1000; private hits = 0; private misses = 0; private evictions = 0; private estimateSize(value: any): number { return 100; } private evictLRU(): void {} } /** * Integration Summary for QueryCache: * * 1. Record metrics in: * - get() - cache hits/misses * - set() - cache writes * - invalidateCategory() - invalidations * - pruneExpired() - expiration cleanup * - evictLRU() - evictions * * 2. Use recordCacheAccess() for: * - All cache access operations * - Expired entry detection * * 3. Custom metrics for: * - Cache hit rate * - Memory usage * - Eviction frequency * - Entries by category */ export { QueryCacheWithTelemetry };