@ahmedhegazee/nestjs-telescope
Version:
Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling
241 lines (240 loc) • 6.82 kB
TypeScript
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { TelescopeService } from '../../core/services/telescope.service';
import { CacheWatcherConfig } from './cache-watcher.config';
import { Observable } from 'rxjs';
import Redis from 'ioredis';
export interface CacheContext {
id: string;
timestamp: Date;
operation: CacheOperation;
key: string;
keyPattern?: string;
value?: any;
ttl?: number;
hit: boolean;
startTime: Date;
endTime?: Date;
duration?: number;
performance?: {
executionTime?: number;
memoryUsage?: number;
networkLatency?: number;
cpuUsage?: number;
};
cacheInstance?: string;
cacheType?: string;
size?: number;
connectionId?: string;
host?: string;
port?: number;
database?: number;
result?: any;
error?: any;
traceId?: string;
requestId?: string;
userId?: string;
sessionId?: string;
redisCommand?: string;
redisArgs?: any[];
}
export declare enum CacheOperation {
GET = "get",
SET = "set",
DEL = "del",
EXISTS = "exists",
EXPIRE = "expire",
TTL = "ttl",
INCR = "incr",
DECR = "decr",
PUSH = "push",
POP = "pop",
FLUSH = "flush",
FLUSHALL = "flushall",
KEYS = "keys",
SCAN = "scan",
MGET = "mget",
MSET = "mset",
HGET = "hget",
HSET = "hset",
HDEL = "hdel",
SADD = "sadd",
SREM = "srem",
ZADD = "zadd",
ZREM = "zrem",
PUBLISH = "publish",
SUBSCRIBE = "subscribe",
UNSUBSCRIBE = "unsubscribe",
OTHER = "other"
}
export interface CacheMetrics {
totalOperations: number;
hitCount: number;
missCount: number;
errorCount: number;
evictionCount: number;
averageResponseTime: number;
slowOperations: number;
operationsPerSecond: number;
hitRate: number;
missRate: number;
errorRate: number;
operationsByType: Record<string, number>;
operationsByResult: Record<string, number>;
topKeyPatterns: Array<{
pattern: string;
count: number;
hitRate: number;
avgResponseTime: number;
}>;
slowOperationsByType: Record<string, number>;
totalMemoryUsage: number;
averageValueSize: number;
keyCount: number;
activeConnections: number;
connectionPool: {
total: number;
active: number;
idle: number;
waiting: number;
};
redisInfo?: {
version: string;
uptime: number;
memory: {
used: number;
peak: number;
fragmentation: number;
};
stats: {
commands: number;
connections: number;
keyspaceHits: number;
keyspaceMisses: number;
};
clients: {
connected: number;
blocked: number;
tracking: number;
};
};
healthScore: number;
healthStatus: 'healthy' | 'warning' | 'critical';
trends: {
lastHour: CacheTrendData;
lastDay: CacheTrendData;
lastWeek: CacheTrendData;
};
}
export interface CacheTrendData {
totalOperations: number;
hitCount: number;
missCount: number;
errorCount: number;
averageResponseTime: number;
hitRate: number;
change: number;
changePercent: number;
peak: number;
}
export interface CacheAlert {
id: string;
type: 'hit_rate' | 'miss_rate' | 'slow_operations' | 'error_rate' | 'memory_usage' | 'connection_limit';
severity: 'low' | 'medium' | 'high' | 'critical';
message: string;
timestamp: Date;
data: any;
acknowledged: boolean;
resolvedAt?: Date;
cacheInstance?: string;
}
export interface CacheHealth {
instance: string;
status: 'healthy' | 'warning' | 'critical';
score: number;
issues: string[];
recommendations: string[];
metrics: {
hitRate: number;
errorRate: number;
avgResponseTime: number;
memoryUsage: number;
connectionCount: number;
};
}
export declare class CacheWatcherService implements OnModuleInit, OnModuleDestroy {
private readonly telescopeService;
private redisClientInstances?;
private readonly logger;
private readonly config;
private readonly destroy$;
private readonly metricsSubject;
private readonly alertsSubject;
private readonly cacheContextSubject;
private cacheHistory;
private currentMetrics;
private alertHistory;
private keyPatterns;
private responseTimes;
private activeOperations;
private redisClients;
private redisInfo;
private connectionPools;
constructor(telescopeService: TelescopeService, cacheWatcherConfig: CacheWatcherConfig, redisClientInstances?: Map<string, Redis>);
onModuleInit(): Promise<void>;
onModuleDestroy(): void;
private initializeMetrics;
private initializeTrendData;
trackCacheOperation(context: CacheContext): void;
private shouldExcludeOperation;
private matchesPattern;
private sanitizeContext;
private sanitizeKey;
private sanitizeValue;
private addToHistory;
private updateMetrics;
private trackKeyPattern;
private extractKeyPattern;
private calculateAverage;
private updateRates;
private updateTopKeyPatterns;
private updateHealthScore;
private createTelescopeEntry;
private generateTags;
private checkAlerts;
private createAlert;
private correlateCache;
private startPeriodicProcessing;
private updateTrends;
private calculateTrend;
private cleanupOldData;
getMetrics(): CacheMetrics;
getMetricsStream(): Observable<CacheMetrics>;
getAlertsStream(): Observable<CacheAlert>;
getCacheStream(): Observable<CacheContext>;
getRecentOperations(limit?: number): CacheContext[];
getOperationsByType(operation: CacheOperation, limit?: number): CacheContext[];
getOperationsByKeyPattern(pattern: string, limit?: number): CacheContext[];
getCacheHealth(instance?: string): CacheHealth | CacheHealth[];
private calculateCacheHealth;
acknowledgeAlert(alertId: string): boolean;
getConfig(): CacheWatcherConfig;
private setupRedisIntegration;
private discoverRedisInstances;
private setupRedisMonitoring;
private setupRedisCommandMonitoring;
private mapRedisCommandToOperation;
private parseRedisInfo;
private startRedisMonitoring;
private updateRedisInfo;
private updateRedisMetrics;
private checkRedisAlerts;
private cleanupRedisConnections;
getRedisInfo(instanceName?: string): any;
getRedisHealth(): Array<{
instance: string;
status: string;
info: any;
}>;
private calculateRedisHealth;
getKeyspaceInfo(instanceName?: string): Promise<any>;
}