201 lines
4.2 KiB
TypeScript
201 lines
4.2 KiB
TypeScript
/**
|
|
* 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<T = any>(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<T = any>(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 };
|