@juspay/neurolink 9.23.0 → 9.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +10 -13
- package/dist/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/cli/commands/observability.d.ts +53 -0
- package/dist/cli/commands/observability.js +453 -0
- package/dist/cli/commands/telemetry.d.ts +63 -0
- package/dist/cli/commands/telemetry.js +689 -0
- package/dist/cli/factories/commandFactory.d.ts +34 -0
- package/dist/cli/factories/commandFactory.js +321 -116
- package/dist/cli/parser.js +6 -9
- package/dist/cli/utils/formatters.d.ts +13 -0
- package/dist/cli/utils/formatters.js +23 -0
- package/dist/constants/contextWindows.js +6 -0
- package/dist/constants/enums.d.ts +6 -0
- package/dist/constants/enums.js +8 -2
- package/dist/context/budgetChecker.js +75 -48
- package/dist/context/contextCompactor.js +135 -127
- package/dist/core/baseProvider.d.ts +5 -0
- package/dist/core/baseProvider.js +158 -102
- package/dist/core/conversationMemoryInitializer.js +7 -4
- package/dist/core/conversationMemoryManager.d.ts +2 -0
- package/dist/core/conversationMemoryManager.js +6 -2
- package/dist/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/core/modules/GenerationHandler.js +12 -12
- package/dist/evaluation/ragasEvaluator.js +39 -19
- package/dist/evaluation/scoring.js +46 -20
- package/dist/features/ppt/index.d.ts +1 -1
- package/dist/features/ppt/index.js +1 -1
- package/dist/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/features/ppt/slideGenerator.js +13 -0
- package/dist/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/features/ppt/slideRenderers.js +6 -4
- package/dist/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/features/ppt/slideTypeInference.js +75 -73
- package/dist/files/fileTools.d.ts +6 -6
- package/dist/index.d.ts +46 -12
- package/dist/index.js +79 -17
- package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/lib/constants/contextWindows.js +6 -0
- package/dist/lib/constants/enums.d.ts +6 -0
- package/dist/lib/constants/enums.js +8 -2
- package/dist/lib/context/budgetChecker.js +75 -48
- package/dist/lib/context/contextCompactor.js +135 -127
- package/dist/lib/core/baseProvider.d.ts +5 -0
- package/dist/lib/core/baseProvider.js +158 -102
- package/dist/lib/core/conversationMemoryInitializer.js +7 -4
- package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
- package/dist/lib/core/conversationMemoryManager.js +6 -2
- package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/lib/core/modules/GenerationHandler.js +12 -12
- package/dist/lib/evaluation/ragasEvaluator.js +39 -19
- package/dist/lib/evaluation/scoring.js +46 -20
- package/dist/lib/features/ppt/index.d.ts +1 -1
- package/dist/lib/features/ppt/index.js +1 -1
- package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/lib/features/ppt/slideGenerator.js +13 -0
- package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/lib/features/ppt/slideRenderers.js +6 -4
- package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/lib/features/ppt/slideTypeInference.js +75 -73
- package/dist/lib/files/fileTools.d.ts +6 -6
- package/dist/lib/index.d.ts +46 -12
- package/dist/lib/index.js +79 -17
- package/dist/lib/mcp/httpRateLimiter.js +39 -12
- package/dist/lib/mcp/httpRetryHandler.js +22 -1
- package/dist/lib/mcp/mcpClientFactory.js +13 -15
- package/dist/lib/memory/memoryRetrievalTools.js +22 -0
- package/dist/lib/neurolink.d.ts +64 -72
- package/dist/lib/neurolink.js +984 -566
- package/dist/lib/observability/exporterRegistry.d.ts +152 -0
- package/dist/lib/observability/exporterRegistry.js +414 -0
- package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/arizeExporter.js +139 -0
- package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/lib/observability/exporters/baseExporter.js +191 -0
- package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
- package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/lib/observability/exporters/datadogExporter.js +197 -0
- package/dist/lib/observability/exporters/index.d.ts +13 -0
- package/dist/lib/observability/exporters/index.js +14 -0
- package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/laminarExporter.js +303 -0
- package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/lib/observability/exporters/langfuseExporter.js +200 -0
- package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
- package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/lib/observability/exporters/otelExporter.js +165 -0
- package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/posthogExporter.js +288 -0
- package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/sentryExporter.js +166 -0
- package/dist/lib/observability/index.d.ts +25 -0
- package/dist/lib/observability/index.js +32 -0
- package/dist/lib/observability/metricsAggregator.d.ts +260 -0
- package/dist/lib/observability/metricsAggregator.js +553 -0
- package/dist/lib/observability/otelBridge.d.ts +49 -0
- package/dist/lib/observability/otelBridge.js +132 -0
- package/dist/lib/observability/retryPolicy.d.ts +192 -0
- package/dist/lib/observability/retryPolicy.js +384 -0
- package/dist/lib/observability/sampling/index.d.ts +4 -0
- package/dist/lib/observability/sampling/index.js +5 -0
- package/dist/lib/observability/sampling/samplers.d.ts +116 -0
- package/dist/lib/observability/sampling/samplers.js +217 -0
- package/dist/lib/observability/spanProcessor.d.ts +129 -0
- package/dist/lib/observability/spanProcessor.js +288 -0
- package/dist/lib/observability/tokenTracker.d.ts +156 -0
- package/dist/lib/observability/tokenTracker.js +414 -0
- package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
- package/dist/lib/observability/types/exporterTypes.js +6 -0
- package/dist/lib/observability/types/index.d.ts +6 -0
- package/dist/lib/observability/types/index.js +5 -0
- package/dist/lib/observability/types/spanTypes.d.ts +244 -0
- package/dist/lib/observability/types/spanTypes.js +93 -0
- package/dist/lib/observability/utils/index.d.ts +4 -0
- package/dist/lib/observability/utils/index.js +5 -0
- package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/lib/observability/utils/spanSerializer.js +287 -0
- package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
- package/dist/lib/providers/amazonSagemaker.js +3 -4
- package/dist/lib/providers/googleVertex.d.ts +7 -0
- package/dist/lib/providers/googleVertex.js +80 -2
- package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/lib/rag/ragIntegration.js +30 -0
- package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
- package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
- package/dist/lib/server/middleware/common.js +44 -12
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/lib/types/cli.d.ts +18 -2
- package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/lib/types/generateTypes.d.ts +2 -2
- package/dist/lib/types/modelTypes.d.ts +18 -18
- package/dist/lib/types/providers.d.ts +5 -0
- package/dist/lib/utils/pricing.js +25 -1
- package/dist/lib/utils/ttsProcessor.js +74 -59
- package/dist/lib/workflow/config.d.ts +36 -36
- package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
- package/dist/lib/workflow/core/judgeScorer.js +20 -2
- package/dist/lib/workflow/core/workflowRunner.js +34 -1
- package/dist/mcp/httpRateLimiter.js +39 -12
- package/dist/mcp/httpRetryHandler.js +22 -1
- package/dist/mcp/mcpClientFactory.js +13 -15
- package/dist/memory/memoryRetrievalTools.js +22 -0
- package/dist/neurolink.d.ts +64 -72
- package/dist/neurolink.js +984 -566
- package/dist/observability/FEATURE-STATUS.md +269 -0
- package/dist/observability/exporterRegistry.d.ts +152 -0
- package/dist/observability/exporterRegistry.js +413 -0
- package/dist/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/observability/exporters/arizeExporter.js +138 -0
- package/dist/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/observability/exporters/baseExporter.js +190 -0
- package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/observability/exporters/braintrustExporter.js +154 -0
- package/dist/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/observability/exporters/datadogExporter.js +196 -0
- package/dist/observability/exporters/index.d.ts +13 -0
- package/dist/observability/exporters/index.js +13 -0
- package/dist/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/observability/exporters/laminarExporter.js +302 -0
- package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/observability/exporters/langfuseExporter.js +199 -0
- package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/observability/exporters/langsmithExporter.js +123 -0
- package/dist/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/observability/exporters/otelExporter.js +164 -0
- package/dist/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/observability/exporters/posthogExporter.js +287 -0
- package/dist/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/observability/exporters/sentryExporter.js +165 -0
- package/dist/observability/index.d.ts +25 -0
- package/dist/observability/index.js +31 -0
- package/dist/observability/metricsAggregator.d.ts +260 -0
- package/dist/observability/metricsAggregator.js +552 -0
- package/dist/observability/otelBridge.d.ts +49 -0
- package/dist/observability/otelBridge.js +131 -0
- package/dist/observability/retryPolicy.d.ts +192 -0
- package/dist/observability/retryPolicy.js +383 -0
- package/dist/observability/sampling/index.d.ts +4 -0
- package/dist/observability/sampling/index.js +4 -0
- package/dist/observability/sampling/samplers.d.ts +116 -0
- package/dist/observability/sampling/samplers.js +216 -0
- package/dist/observability/spanProcessor.d.ts +129 -0
- package/dist/observability/spanProcessor.js +287 -0
- package/dist/observability/tokenTracker.d.ts +156 -0
- package/dist/observability/tokenTracker.js +413 -0
- package/dist/observability/types/exporterTypes.d.ts +250 -0
- package/dist/observability/types/exporterTypes.js +5 -0
- package/dist/observability/types/index.d.ts +6 -0
- package/dist/observability/types/index.js +4 -0
- package/dist/observability/types/spanTypes.d.ts +244 -0
- package/dist/observability/types/spanTypes.js +92 -0
- package/dist/observability/utils/index.d.ts +4 -0
- package/dist/observability/utils/index.js +4 -0
- package/dist/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/observability/utils/spanSerializer.js +286 -0
- package/dist/providers/amazonSagemaker.d.ts +5 -4
- package/dist/providers/amazonSagemaker.js +3 -4
- package/dist/providers/googleVertex.d.ts +7 -0
- package/dist/providers/googleVertex.js +80 -2
- package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/rag/ragIntegration.js +30 -0
- package/dist/rag/retrieval/hybridSearch.js +22 -0
- package/dist/server/abstract/baseServerAdapter.js +51 -19
- package/dist/server/middleware/common.js +44 -12
- package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/types/cli.d.ts +18 -2
- package/dist/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/types/generateTypes.d.ts +2 -2
- package/dist/types/providers.d.ts +5 -0
- package/dist/utils/pricing.js +25 -1
- package/dist/utils/ttsProcessor.js +74 -59
- package/dist/workflow/config.d.ts +52 -52
- package/dist/workflow/core/ensembleExecutor.js +10 -0
- package/dist/workflow/core/judgeScorer.js +20 -2
- package/dist/workflow/core/workflowRunner.js +34 -1
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exporter Registry
|
|
3
|
+
* Manages multiple observability exporters with circuit breaker protection
|
|
4
|
+
*/
|
|
5
|
+
import type { BaseExporter } from "./exporters/baseExporter.js";
|
|
6
|
+
import type { Sampler } from "./sampling/samplers.js";
|
|
7
|
+
import type { ExporterHealthStatus, ExportResult, SpanData } from "./types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Circuit breaker state for an exporter
|
|
10
|
+
*/
|
|
11
|
+
type CircuitBreakerState = {
|
|
12
|
+
failures: number;
|
|
13
|
+
lastFailure: number;
|
|
14
|
+
state: "closed" | "open" | "half-open";
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Circuit breaker configuration
|
|
18
|
+
*/
|
|
19
|
+
type CircuitBreakerConfig = {
|
|
20
|
+
/** Number of failures before opening the circuit */
|
|
21
|
+
failureThreshold: number;
|
|
22
|
+
/** Time in ms to wait before trying half-open state */
|
|
23
|
+
resetTimeout: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Registry for managing multiple observability exporters
|
|
27
|
+
* Includes circuit breaker protection to prevent cascading failures
|
|
28
|
+
*/
|
|
29
|
+
export declare class ExporterRegistry {
|
|
30
|
+
private exporters;
|
|
31
|
+
private defaultExporter;
|
|
32
|
+
private sampler;
|
|
33
|
+
private circuitBreakers;
|
|
34
|
+
private readonly circuitBreakerConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Register an exporter
|
|
37
|
+
*/
|
|
38
|
+
register(exporter: BaseExporter): void;
|
|
39
|
+
/**
|
|
40
|
+
* Unregister an exporter
|
|
41
|
+
*/
|
|
42
|
+
unregister(name: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Get an exporter by name
|
|
45
|
+
*/
|
|
46
|
+
get(name: string): BaseExporter | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Get all registered exporter names
|
|
49
|
+
*/
|
|
50
|
+
getNames(): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Get total exporter count
|
|
53
|
+
*/
|
|
54
|
+
getCount(): number;
|
|
55
|
+
/**
|
|
56
|
+
* Set the default exporter
|
|
57
|
+
*/
|
|
58
|
+
setDefault(name: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get the default exporter
|
|
61
|
+
*/
|
|
62
|
+
getDefault(): BaseExporter | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Set the sampler for the registry
|
|
65
|
+
*/
|
|
66
|
+
setSampler(sampler: Sampler): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get the current sampler
|
|
69
|
+
*/
|
|
70
|
+
getSampler(): Sampler;
|
|
71
|
+
/**
|
|
72
|
+
* Configure the circuit breaker settings
|
|
73
|
+
* @param config - Partial circuit breaker configuration
|
|
74
|
+
*/
|
|
75
|
+
configureCircuitBreaker(config: Partial<CircuitBreakerConfig>): void;
|
|
76
|
+
/**
|
|
77
|
+
* Check if circuit is open for an exporter
|
|
78
|
+
* @param exporterName - Name of the exporter
|
|
79
|
+
* @returns true if circuit is open (exporter should be skipped)
|
|
80
|
+
*/
|
|
81
|
+
private isCircuitOpen;
|
|
82
|
+
/**
|
|
83
|
+
* Record a failure for an exporter's circuit breaker
|
|
84
|
+
* @param exporterName - Name of the exporter
|
|
85
|
+
*/
|
|
86
|
+
private recordFailure;
|
|
87
|
+
/**
|
|
88
|
+
* Record a success for an exporter's circuit breaker
|
|
89
|
+
* Resets the circuit to closed state
|
|
90
|
+
* @param exporterName - Name of the exporter
|
|
91
|
+
*/
|
|
92
|
+
private recordSuccess;
|
|
93
|
+
/**
|
|
94
|
+
* Get circuit breaker status for an exporter
|
|
95
|
+
* @param exporterName - Name of the exporter
|
|
96
|
+
* @returns Circuit breaker state or undefined if not tracked
|
|
97
|
+
*/
|
|
98
|
+
getCircuitBreakerStatus(exporterName: string): CircuitBreakerState | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Reset circuit breaker for an exporter
|
|
101
|
+
* @param exporterName - Name of the exporter
|
|
102
|
+
*/
|
|
103
|
+
resetCircuitBreaker(exporterName: string): void;
|
|
104
|
+
/**
|
|
105
|
+
* Export span to all registered exporters
|
|
106
|
+
* Applies sampling and circuit breaker protection before export
|
|
107
|
+
*/
|
|
108
|
+
exportToAll(span: SpanData): Promise<Map<string, ExportResult>>;
|
|
109
|
+
/**
|
|
110
|
+
* Export span to a specific exporter
|
|
111
|
+
* Applies sampling and circuit breaker protection
|
|
112
|
+
*/
|
|
113
|
+
exportTo(name: string, span: SpanData): Promise<ExportResult | null>;
|
|
114
|
+
/**
|
|
115
|
+
* Initialize all exporters
|
|
116
|
+
*/
|
|
117
|
+
initializeAll(): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Shutdown all exporters
|
|
120
|
+
*/
|
|
121
|
+
shutdownAll(): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Flush all exporters
|
|
124
|
+
*/
|
|
125
|
+
flushAll(): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Get health status of all exporters
|
|
128
|
+
*/
|
|
129
|
+
healthCheckAll(): Promise<Map<string, ExporterHealthStatus>>;
|
|
130
|
+
/**
|
|
131
|
+
* Check if all exporters are healthy
|
|
132
|
+
*/
|
|
133
|
+
isHealthy(): Promise<boolean>;
|
|
134
|
+
/**
|
|
135
|
+
* Get total pending spans across all exporters
|
|
136
|
+
*/
|
|
137
|
+
getTotalPendingSpans(): number;
|
|
138
|
+
/**
|
|
139
|
+
* Clear all registered exporters and reset state
|
|
140
|
+
* (For testing and cleanup)
|
|
141
|
+
*/
|
|
142
|
+
clear(): void;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the global exporter registry instance
|
|
146
|
+
*/
|
|
147
|
+
export declare function getExporterRegistry(): ExporterRegistry;
|
|
148
|
+
/**
|
|
149
|
+
* Reset the global exporter registry (for testing)
|
|
150
|
+
*/
|
|
151
|
+
export declare function resetExporterRegistry(): void;
|
|
152
|
+
export {};
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exporter Registry
|
|
3
|
+
* Manages multiple observability exporters with circuit breaker protection
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { AlwaysSampler } from "./sampling/samplers.js";
|
|
7
|
+
/** Default timeout for exporter API calls (30 seconds) */
|
|
8
|
+
const DEFAULT_EXPORT_TIMEOUT_MS = 30_000;
|
|
9
|
+
/**
|
|
10
|
+
* Wrap a promise with a timeout. Rejects with a descriptive error if the
|
|
11
|
+
* promise does not settle within `timeoutMs` milliseconds.
|
|
12
|
+
*/
|
|
13
|
+
function withExportTimeout(promise, timeoutMs, label) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const timer = setTimeout(() => {
|
|
16
|
+
reject(new Error(`Export to '${label}' timed out after ${timeoutMs}ms`));
|
|
17
|
+
}, timeoutMs);
|
|
18
|
+
promise.then((v) => {
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
resolve(v);
|
|
21
|
+
}, (e) => {
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
reject(e);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Registry for managing multiple observability exporters
|
|
29
|
+
* Includes circuit breaker protection to prevent cascading failures
|
|
30
|
+
*/
|
|
31
|
+
export class ExporterRegistry {
|
|
32
|
+
exporters = new Map();
|
|
33
|
+
defaultExporter = null;
|
|
34
|
+
sampler = new AlwaysSampler();
|
|
35
|
+
circuitBreakers = new Map();
|
|
36
|
+
circuitBreakerConfig = {
|
|
37
|
+
failureThreshold: 5,
|
|
38
|
+
resetTimeout: 30000, // 30 seconds
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Register an exporter
|
|
42
|
+
*/
|
|
43
|
+
register(exporter) {
|
|
44
|
+
this.exporters.set(exporter.getName(), exporter);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Unregister an exporter
|
|
48
|
+
*/
|
|
49
|
+
unregister(name) {
|
|
50
|
+
return this.exporters.delete(name);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get an exporter by name
|
|
54
|
+
*/
|
|
55
|
+
get(name) {
|
|
56
|
+
return this.exporters.get(name);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get all registered exporter names
|
|
60
|
+
*/
|
|
61
|
+
getNames() {
|
|
62
|
+
return Array.from(this.exporters.keys());
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get total exporter count
|
|
66
|
+
*/
|
|
67
|
+
getCount() {
|
|
68
|
+
return this.exporters.size;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Set the default exporter
|
|
72
|
+
*/
|
|
73
|
+
setDefault(name) {
|
|
74
|
+
if (!this.exporters.has(name)) {
|
|
75
|
+
throw new Error(`Exporter '${name}' not registered`);
|
|
76
|
+
}
|
|
77
|
+
this.defaultExporter = name;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the default exporter
|
|
81
|
+
*/
|
|
82
|
+
getDefault() {
|
|
83
|
+
if (!this.defaultExporter) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return this.exporters.get(this.defaultExporter);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Set the sampler for the registry
|
|
90
|
+
*/
|
|
91
|
+
setSampler(sampler) {
|
|
92
|
+
this.sampler = sampler;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the current sampler
|
|
96
|
+
*/
|
|
97
|
+
getSampler() {
|
|
98
|
+
return this.sampler;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Configure the circuit breaker settings
|
|
102
|
+
* @param config - Partial circuit breaker configuration
|
|
103
|
+
*/
|
|
104
|
+
configureCircuitBreaker(config) {
|
|
105
|
+
Object.assign(this.circuitBreakerConfig, config);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if circuit is open for an exporter
|
|
109
|
+
* @param exporterName - Name of the exporter
|
|
110
|
+
* @returns true if circuit is open (exporter should be skipped)
|
|
111
|
+
*/
|
|
112
|
+
isCircuitOpen(exporterName) {
|
|
113
|
+
const breaker = this.circuitBreakers.get(exporterName);
|
|
114
|
+
if (!breaker) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (breaker.state === "open") {
|
|
118
|
+
// Check if we should try half-open
|
|
119
|
+
if (Date.now() - breaker.lastFailure >
|
|
120
|
+
this.circuitBreakerConfig.resetTimeout) {
|
|
121
|
+
breaker.state = "half-open";
|
|
122
|
+
logger.info(`[ExporterRegistry] Circuit half-open for ${exporterName}, attempting recovery`);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Record a failure for an exporter's circuit breaker
|
|
131
|
+
* @param exporterName - Name of the exporter
|
|
132
|
+
*/
|
|
133
|
+
recordFailure(exporterName) {
|
|
134
|
+
let breaker = this.circuitBreakers.get(exporterName);
|
|
135
|
+
if (!breaker) {
|
|
136
|
+
breaker = { failures: 0, lastFailure: 0, state: "closed" };
|
|
137
|
+
this.circuitBreakers.set(exporterName, breaker);
|
|
138
|
+
}
|
|
139
|
+
breaker.failures++;
|
|
140
|
+
breaker.lastFailure = Date.now();
|
|
141
|
+
if (breaker.failures >= this.circuitBreakerConfig.failureThreshold) {
|
|
142
|
+
breaker.state = "open";
|
|
143
|
+
logger.warn(`[ExporterRegistry] Circuit opened for ${exporterName} after ${breaker.failures} failures`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Record a success for an exporter's circuit breaker
|
|
148
|
+
* Resets the circuit to closed state
|
|
149
|
+
* @param exporterName - Name of the exporter
|
|
150
|
+
*/
|
|
151
|
+
recordSuccess(exporterName) {
|
|
152
|
+
const breaker = this.circuitBreakers.get(exporterName);
|
|
153
|
+
if (breaker) {
|
|
154
|
+
if (breaker.state === "half-open") {
|
|
155
|
+
logger.info(`[ExporterRegistry] Circuit closed for ${exporterName} after successful recovery`);
|
|
156
|
+
}
|
|
157
|
+
breaker.failures = 0;
|
|
158
|
+
breaker.state = "closed";
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get circuit breaker status for an exporter
|
|
163
|
+
* @param exporterName - Name of the exporter
|
|
164
|
+
* @returns Circuit breaker state or undefined if not tracked
|
|
165
|
+
*/
|
|
166
|
+
getCircuitBreakerStatus(exporterName) {
|
|
167
|
+
return this.circuitBreakers.get(exporterName);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Reset circuit breaker for an exporter
|
|
171
|
+
* @param exporterName - Name of the exporter
|
|
172
|
+
*/
|
|
173
|
+
resetCircuitBreaker(exporterName) {
|
|
174
|
+
this.circuitBreakers.delete(exporterName);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Export span to all registered exporters
|
|
178
|
+
* Applies sampling and circuit breaker protection before export
|
|
179
|
+
*/
|
|
180
|
+
async exportToAll(span) {
|
|
181
|
+
const results = new Map();
|
|
182
|
+
// Apply sampling
|
|
183
|
+
if (!this.sampler.shouldSample(span)) {
|
|
184
|
+
// Return empty results if not sampled
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
const exportPromises = Array.from(this.exporters.entries()).map(async ([name, exporter]) => {
|
|
188
|
+
// Check circuit breaker before attempting export
|
|
189
|
+
if (this.isCircuitOpen(name)) {
|
|
190
|
+
results.set(name, {
|
|
191
|
+
success: false,
|
|
192
|
+
exportedCount: 0,
|
|
193
|
+
failedCount: 1,
|
|
194
|
+
errors: [
|
|
195
|
+
{
|
|
196
|
+
spanId: span.spanId,
|
|
197
|
+
error: "Circuit breaker open - exporter temporarily disabled",
|
|
198
|
+
retryable: true,
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
durationMs: 0,
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (exporter.isInitialized()) {
|
|
206
|
+
try {
|
|
207
|
+
const result = await withExportTimeout(exporter.exportSpan(span), DEFAULT_EXPORT_TIMEOUT_MS, name);
|
|
208
|
+
results.set(name, result);
|
|
209
|
+
// Record success or failure based on result
|
|
210
|
+
if (result.success) {
|
|
211
|
+
this.recordSuccess(name);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
this.recordFailure(name);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
this.recordFailure(name);
|
|
219
|
+
results.set(name, {
|
|
220
|
+
success: false,
|
|
221
|
+
exportedCount: 0,
|
|
222
|
+
failedCount: 1,
|
|
223
|
+
errors: [
|
|
224
|
+
{
|
|
225
|
+
spanId: span.spanId,
|
|
226
|
+
error: error instanceof Error ? error.message : String(error),
|
|
227
|
+
retryable: true,
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
durationMs: 0,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
logger.debug(`[ExporterRegistry] Skipping uninitialized exporter '${name}' for span ${span.spanId}`);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
await Promise.all(exportPromises);
|
|
239
|
+
return results;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Export span to a specific exporter
|
|
243
|
+
* Applies sampling and circuit breaker protection
|
|
244
|
+
*/
|
|
245
|
+
async exportTo(name, span) {
|
|
246
|
+
const exporter = this.exporters.get(name);
|
|
247
|
+
if (!exporter) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
if (!exporter.isInitialized()) {
|
|
251
|
+
logger.debug(`[ExporterRegistry] Skipping uninitialized exporter '${name}' for span ${span.spanId}`);
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
// Check circuit breaker before attempting export
|
|
255
|
+
if (this.isCircuitOpen(name)) {
|
|
256
|
+
return {
|
|
257
|
+
success: false,
|
|
258
|
+
exportedCount: 0,
|
|
259
|
+
failedCount: 1,
|
|
260
|
+
errors: [
|
|
261
|
+
{
|
|
262
|
+
spanId: span.spanId,
|
|
263
|
+
error: "Circuit breaker open - exporter temporarily disabled",
|
|
264
|
+
retryable: true,
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
durationMs: 0,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// Apply sampling
|
|
271
|
+
if (!this.sampler.shouldSample(span)) {
|
|
272
|
+
return {
|
|
273
|
+
success: true,
|
|
274
|
+
exportedCount: 0,
|
|
275
|
+
failedCount: 0,
|
|
276
|
+
durationMs: 0,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
const result = await withExportTimeout(exporter.exportSpan(span), DEFAULT_EXPORT_TIMEOUT_MS, name);
|
|
281
|
+
if (result.success) {
|
|
282
|
+
this.recordSuccess(name);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
this.recordFailure(name);
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
this.recordFailure(name);
|
|
291
|
+
return {
|
|
292
|
+
success: false,
|
|
293
|
+
exportedCount: 0,
|
|
294
|
+
failedCount: 1,
|
|
295
|
+
errors: [
|
|
296
|
+
{
|
|
297
|
+
spanId: span.spanId,
|
|
298
|
+
error: error instanceof Error ? error.message : String(error),
|
|
299
|
+
retryable: true,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
durationMs: 0,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Initialize all exporters
|
|
308
|
+
*/
|
|
309
|
+
async initializeAll() {
|
|
310
|
+
const results = await Promise.allSettled(Array.from(this.exporters.entries()).map(([name, e]) => e.initialize().catch((err) => {
|
|
311
|
+
logger.error(`[ExporterRegistry] Failed to initialize exporter '${name}':`, err);
|
|
312
|
+
throw err;
|
|
313
|
+
})));
|
|
314
|
+
for (const result of results) {
|
|
315
|
+
if (result.status === "rejected") {
|
|
316
|
+
logger.warn(`[ExporterRegistry] One or more exporters failed to initialize`);
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Shutdown all exporters
|
|
323
|
+
*/
|
|
324
|
+
async shutdownAll() {
|
|
325
|
+
const results = await Promise.allSettled(Array.from(this.exporters.entries()).map(([name, e]) => e.shutdown().catch((err) => {
|
|
326
|
+
logger.error(`[ExporterRegistry] Failed to shutdown exporter '${name}':`, err);
|
|
327
|
+
throw err;
|
|
328
|
+
})));
|
|
329
|
+
for (const result of results) {
|
|
330
|
+
if (result.status === "rejected") {
|
|
331
|
+
logger.warn(`[ExporterRegistry] One or more exporters failed to shutdown`);
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Flush all exporters
|
|
338
|
+
*/
|
|
339
|
+
async flushAll() {
|
|
340
|
+
const results = await Promise.allSettled(Array.from(this.exporters.entries()).map(([name, e]) => e.flush().catch((err) => {
|
|
341
|
+
logger.error(`[ExporterRegistry] Failed to flush exporter '${name}':`, err);
|
|
342
|
+
throw err;
|
|
343
|
+
})));
|
|
344
|
+
for (const result of results) {
|
|
345
|
+
if (result.status === "rejected") {
|
|
346
|
+
logger.warn(`[ExporterRegistry] One or more exporters failed to flush`);
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get health status of all exporters
|
|
353
|
+
*/
|
|
354
|
+
async healthCheckAll() {
|
|
355
|
+
const results = new Map();
|
|
356
|
+
const healthPromises = Array.from(this.exporters.entries()).map(async ([name, exporter]) => {
|
|
357
|
+
const status = await exporter.healthCheck();
|
|
358
|
+
results.set(name, status);
|
|
359
|
+
});
|
|
360
|
+
await Promise.all(healthPromises);
|
|
361
|
+
return results;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if all exporters are healthy
|
|
365
|
+
*/
|
|
366
|
+
async isHealthy() {
|
|
367
|
+
const statuses = await this.healthCheckAll();
|
|
368
|
+
return Array.from(statuses.values()).every((s) => s.healthy);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get total pending spans across all exporters
|
|
372
|
+
*/
|
|
373
|
+
getTotalPendingSpans() {
|
|
374
|
+
let total = 0;
|
|
375
|
+
const exporterArray = Array.from(this.exporters.values());
|
|
376
|
+
for (const exporter of exporterArray) {
|
|
377
|
+
total += exporter.getPendingCount();
|
|
378
|
+
}
|
|
379
|
+
return total;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Clear all registered exporters and reset state
|
|
383
|
+
* (For testing and cleanup)
|
|
384
|
+
*/
|
|
385
|
+
clear() {
|
|
386
|
+
this.exporters.clear();
|
|
387
|
+
this.defaultExporter = null;
|
|
388
|
+
this.circuitBreakers.clear();
|
|
389
|
+
this.sampler = new AlwaysSampler();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Global exporter registry instance (singleton pattern from main)
|
|
394
|
+
*/
|
|
395
|
+
let globalRegistry = null;
|
|
396
|
+
/**
|
|
397
|
+
* Get the global exporter registry instance
|
|
398
|
+
*/
|
|
399
|
+
export function getExporterRegistry() {
|
|
400
|
+
if (!globalRegistry) {
|
|
401
|
+
globalRegistry = new ExporterRegistry();
|
|
402
|
+
}
|
|
403
|
+
return globalRegistry;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Reset the global exporter registry (for testing)
|
|
407
|
+
*/
|
|
408
|
+
export function resetExporterRegistry() {
|
|
409
|
+
if (globalRegistry) {
|
|
410
|
+
globalRegistry.clear();
|
|
411
|
+
}
|
|
412
|
+
globalRegistry = null;
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=exporterRegistry.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arize Exporter
|
|
3
|
+
* Exports spans to Arize ML monitoring platform
|
|
4
|
+
*/
|
|
5
|
+
import type { ArizeExporterConfig, ExporterHealthStatus, ExportResult, SpanData } from "../types/index.js";
|
|
6
|
+
import { BaseExporter } from "./baseExporter.js";
|
|
7
|
+
/**
|
|
8
|
+
* Arize exporter for ML monitoring and prediction logs
|
|
9
|
+
* Supports feature tracking and model performance monitoring
|
|
10
|
+
*/
|
|
11
|
+
export declare class ArizeExporter extends BaseExporter {
|
|
12
|
+
private readonly spaceKey;
|
|
13
|
+
private readonly apiKey;
|
|
14
|
+
private readonly modelId;
|
|
15
|
+
private readonly modelVersion;
|
|
16
|
+
private readonly endpoint;
|
|
17
|
+
constructor(config: ArizeExporterConfig);
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
exportSpan(span: SpanData): Promise<ExportResult>;
|
|
20
|
+
exportBatch(spans: SpanData[]): Promise<ExportResult>;
|
|
21
|
+
flush(): Promise<void>;
|
|
22
|
+
shutdown(): Promise<void>;
|
|
23
|
+
healthCheck(): Promise<ExporterHealthStatus>;
|
|
24
|
+
/**
|
|
25
|
+
* Verify connectivity to Arize API
|
|
26
|
+
*/
|
|
27
|
+
protected ping(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Convert span to Arize prediction log format
|
|
30
|
+
*/
|
|
31
|
+
private convertToArizePrediction;
|
|
32
|
+
}
|