UNPKG

syntropylog

Version:

An instance manager with observability for Node.js applications

172 lines 7.62 kB
/** * @file src/serialization/SerializationManager.ts * @description Intelligent serialization manager with auto-detection and adaptive timeouts */ import { SerializationComplexity, } from './types'; import { SerializationPipeline } from './SerializationPipeline'; import { SerializationStep } from './pipeline/SerializationStep'; import { SanitizationStep } from './pipeline/SanitizationStep'; import { TimeoutStep } from './pipeline/TimeoutStep'; export class SerializationManager { pipeline; serializationStep; sanitizationStep; timeoutStep; config; metrics; constructor(config = {}) { this.config = { timeoutMs: config.timeoutMs || 5000, enableMetrics: config.enableMetrics ?? true, sanitizeSensitiveData: config.sanitizeSensitiveData ?? true, sanitizationContext: { sensitiveFields: config.sanitizationContext?.sensitiveFields || [ 'password', 'token', 'secret', 'key', 'auth', 'credential', 'api_key', 'private_key', 'connection_string', 'wallet_location', ], redactPatterns: config.sanitizationContext?.redactPatterns || [ /password\s*=\s*['"][^'"]*['"]/gi, /user\s*=\s*['"][^'"]*['"]/gi, /token\s*=\s*['"][^'"]*['"]/gi, /secret\s*=\s*['"][^'"]*['"]/gi, ], maxStringLength: config.sanitizationContext?.maxStringLength || 300, enableDeepSanitization: config.sanitizationContext?.enableDeepSanitization ?? true, }, }; this.metrics = { totalSerializations: 0, successfulSerializations: 0, failedSerializations: 0, totalSerializationDuration: 0, totalOperationTimeout: 0, maxSerializationDuration: 0, minSerializationDuration: 0, complexityDistribution: { low: 0, medium: 0, high: 0 }, serializerDistribution: {}, timeoutStrategyDistribution: {}, }; // Inicializar pipeline this.pipeline = new SerializationPipeline(); // Crear pasos del pipeline this.serializationStep = new SerializationStep(); this.sanitizationStep = new SanitizationStep(); this.timeoutStep = new TimeoutStep(this.pipeline['timeoutStrategies']); // Configurar pipeline this.pipeline.addStep(this.serializationStep); this.pipeline.addStep(this.sanitizationStep); this.pipeline.addStep(this.timeoutStep); } register(serializer) { this.serializationStep.addSerializer(serializer); } async serialize(data, context = { depth: 0, maxDepth: 10, sensitiveFields: [], sanitize: true, }) { const startTime = Date.now(); // Crear contexto del pipeline const pipelineContext = { serializationContext: context, sanitizeSensitiveData: this.config.sanitizeSensitiveData, sanitizationContext: this.config.sanitizationContext, enableMetrics: this.config.enableMetrics, }; // Ejecutar pipeline const result = await this.pipeline.process(data, pipelineContext); // Actualizar métricas if (this.config.enableMetrics) { this.updateMetrics(result, Date.now() - startTime); } return result; } updateMetrics(result, _totalDuration) { this.metrics.totalSerializations++; if (result.success) { this.metrics.successfulSerializations++; // Métricas de serialización (deberían ser muy bajas) const serializationDuration = result.metadata.stepDurations?.serialization || 0; this.metrics.totalSerializationDuration += serializationDuration; this.metrics.maxSerializationDuration = Math.max(this.metrics.maxSerializationDuration, serializationDuration); this.metrics.minSerializationDuration = this.metrics.minSerializationDuration === 0 ? serializationDuration : Math.min(this.metrics.minSerializationDuration, serializationDuration); // Métricas de timeout de operación const operationTimeout = result.metadata.operationTimeout || 0; this.metrics.totalOperationTimeout += operationTimeout; // Distribución por complejidad const complexity = result.complexity || SerializationComplexity.SIMPLE; if (complexity === SerializationComplexity.SIMPLE) this.metrics.complexityDistribution.low++; else if (complexity === SerializationComplexity.COMPLEX) this.metrics.complexityDistribution.medium++; else if (complexity === SerializationComplexity.CRITICAL) this.metrics.complexityDistribution.high++; // Distribución por serializador const serializer = result.serializer || 'unknown'; this.metrics.serializerDistribution[serializer] = (this.metrics.serializerDistribution[serializer] || 0) + 1; // Distribución por estrategia de timeout const timeoutStrategy = result.metadata.timeoutStrategy || 'unknown'; this.metrics.timeoutStrategyDistribution[timeoutStrategy] = (this.metrics.timeoutStrategyDistribution[timeoutStrategy] || 0) + 1; } else { this.metrics.failedSerializations++; } } getMetrics() { return { totalSerializations: this.metrics.totalSerializations, successfulSerializations: this.metrics.successfulSerializations, failedSerializations: this.metrics.failedSerializations, averageSerializationDuration: this.metrics.totalSerializations > 0 ? this.metrics.totalSerializationDuration / this.metrics.totalSerializations : 0, averageOperationTimeout: this.metrics.successfulSerializations > 0 ? this.metrics.totalOperationTimeout / this.metrics.successfulSerializations : 0, maxSerializationDuration: this.metrics.maxSerializationDuration, minSerializationDuration: this.metrics.minSerializationDuration, complexityDistribution: { ...this.metrics.complexityDistribution }, serializerDistribution: { ...this.metrics.serializerDistribution }, timeoutStrategyDistribution: { ...this.metrics.timeoutStrategyDistribution, }, }; } resetMetrics() { this.metrics = { totalSerializations: 0, successfulSerializations: 0, failedSerializations: 0, totalSerializationDuration: 0, totalOperationTimeout: 0, maxSerializationDuration: 0, minSerializationDuration: 0, complexityDistribution: { low: 0, medium: 0, high: 0 }, serializerDistribution: {}, timeoutStrategyDistribution: {}, }; } getRegisteredSerializers() { return this.serializationStep.getRegisteredSerializers(); } getPipelineMetrics() { return this.pipeline.getMetrics(); } } //# sourceMappingURL=SerializationManager.js.map