@cloudbase/agent-observability 1.0.1-alpha.9
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/README.md +231 -0
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-NFEGQTCC.mjs.map +1 -0
- package/dist/chunk-ZGEMAYS4.mjs +716 -0
- package/dist/chunk-ZGEMAYS4.mjs.map +1 -0
- package/dist/esm-PGEDANAI.mjs +1030 -0
- package/dist/esm-PGEDANAI.mjs.map +1 -0
- package/dist/index.d.mts +728 -0
- package/dist/index.d.ts +728 -0
- package/dist/index.js +732 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +52 -0
- package/dist/index.mjs.map +1 -0
- package/dist/langchain.d.mts +108 -0
- package/dist/langchain.d.ts +108 -0
- package/dist/langchain.js +1237 -0
- package/dist/langchain.js.map +1 -0
- package/dist/langchain.mjs +535 -0
- package/dist/langchain.mjs.map +1 -0
- package/dist/server.d.mts +163 -0
- package/dist/server.d.ts +163 -0
- package/dist/server.js +1528 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +175 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +91 -0
- package/src/core/attributes.ts +233 -0
- package/src/core/constants.ts +75 -0
- package/src/core/spanWrapper.ts +417 -0
- package/src/core/tracerProvider.ts +136 -0
- package/src/index.ts +775 -0
- package/src/langchain/CallbackHandler.ts +893 -0
- package/src/langchain/index.ts +7 -0
- package/src/server/config.ts +160 -0
- package/src/server/index.ts +21 -0
- package/src/server/setup.ts +344 -0
- package/src/types.ts +254 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability configuration types for AG-Kit Server.
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified configuration interface for trace exporters:
|
|
5
|
+
* - Console: Development/debugging output
|
|
6
|
+
* - OTLP: Production export to Langfuse, Jaeger, etc.
|
|
7
|
+
* - Custom: User-defined setup logic
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Trace exporter type constants.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { ExporterType } from '@cloudbase/agent-observability/server';
|
|
18
|
+
*
|
|
19
|
+
* { type: ExporterType.Console }
|
|
20
|
+
* { type: ExporterType.OTLP }
|
|
21
|
+
* { type: ExporterType.Custom }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export const ExporterType = {
|
|
27
|
+
/** Console exporter - outputs traces to stdout */
|
|
28
|
+
Console: 'console',
|
|
29
|
+
/** OTLP exporter - sends traces to OTLP-compatible backend */
|
|
30
|
+
OTLP: 'otlp',
|
|
31
|
+
/** Custom exporter - user-defined setup logic */
|
|
32
|
+
Custom: 'custom',
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Trace exporter type literal values.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export type ExporterType = typeof ExporterType[keyof typeof ExporterType];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Batch processing configuration for span exporters.
|
|
44
|
+
*
|
|
45
|
+
* Used by BatchSpanProcessor to optimize performance:
|
|
46
|
+
* - Collects spans in memory and exports them in batches
|
|
47
|
+
* - Reduces I/O operations (console) or network requests (OTLP)
|
|
48
|
+
* - Recommended for production environments
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
export interface BatchConfig {
|
|
53
|
+
/** Maximum number of spans per export batch (default: 100) */
|
|
54
|
+
maxExportBatchSize?: number;
|
|
55
|
+
/** Maximum delay in milliseconds before exporting (default: 5000) */
|
|
56
|
+
scheduledDelayMillis?: number;
|
|
57
|
+
/** Maximum queue size (default: 2048) */
|
|
58
|
+
maxQueueSize?: number;
|
|
59
|
+
/** Export timeout in milliseconds (default: 30000) */
|
|
60
|
+
exportTimeoutMillis?: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Console trace exporter configuration.
|
|
65
|
+
*
|
|
66
|
+
* Outputs traces to stdout in JSON format using ConsoleSpanExporter.
|
|
67
|
+
* Useful for development and debugging.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* import { ExporterType } from '@cloudbase/agent-observability/server';
|
|
72
|
+
*
|
|
73
|
+
* { type: ExporterType.Console }
|
|
74
|
+
* { type: ExporterType.Console, batch: { maxExportBatchSize: 200 } }
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export interface ConsoleTraceConfig {
|
|
80
|
+
/** Discriminator for console exporter */
|
|
81
|
+
type: typeof ExporterType.Console;
|
|
82
|
+
/** Optional batch processing configuration */
|
|
83
|
+
batch?: BatchConfig;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* OTLP trace exporter configuration.
|
|
88
|
+
*
|
|
89
|
+
* Exports traces via OTLP protocol to any compatible backend:
|
|
90
|
+
* - Langfuse: https://cloud.langfuse.com/api/public/otlp/v1/traces
|
|
91
|
+
* - Jaeger: http://localhost:4318/v1/traces
|
|
92
|
+
* - OTel Collector: custom endpoint
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* import { ExporterType } from '@cloudbase/agent-observability/server';
|
|
97
|
+
*
|
|
98
|
+
* {
|
|
99
|
+
* type: ExporterType.OTLP,
|
|
100
|
+
* url: 'https://cloud.langfuse.com/api/public/otlp/v1/traces',
|
|
101
|
+
* headers: {
|
|
102
|
+
* 'Authorization': 'Basic ' + btoa('pk-lf-xxx:sk-lf-xxx')
|
|
103
|
+
* }
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
export interface OTLPTraceConfig {
|
|
110
|
+
/** Discriminator for OTLP exporter */
|
|
111
|
+
type: typeof ExporterType.OTLP;
|
|
112
|
+
/** OTLP endpoint URL (http/https) */
|
|
113
|
+
url: string;
|
|
114
|
+
/** Optional HTTP headers for authentication */
|
|
115
|
+
headers?: Record<string, string>;
|
|
116
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
117
|
+
timeout?: number;
|
|
118
|
+
/** Optional batch processing configuration */
|
|
119
|
+
batch?: BatchConfig;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Custom trace exporter configuration.
|
|
124
|
+
*
|
|
125
|
+
* Allows users to provide custom trace setup logic.
|
|
126
|
+
* Useful for integrations not covered by console/otlp.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* import { ExporterType } from '@cloudbase/agent-observability/server';
|
|
131
|
+
*
|
|
132
|
+
* {
|
|
133
|
+
* type: ExporterType.Custom,
|
|
134
|
+
* setup: async () => {
|
|
135
|
+
* const exporter = new MyCustomExporter();
|
|
136
|
+
* const provider = new BasicTracerProvider();
|
|
137
|
+
* provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
|
138
|
+
* provider.register();
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @public
|
|
144
|
+
*/
|
|
145
|
+
export interface CustomTraceConfig {
|
|
146
|
+
/** Discriminator for custom setup */
|
|
147
|
+
type: typeof ExporterType.Custom;
|
|
148
|
+
/** User-defined setup function */
|
|
149
|
+
setup: () => Promise<void> | void;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Union type of all supported trace exporter configurations.
|
|
154
|
+
*
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
export type ObservabilityConfig =
|
|
158
|
+
| ConsoleTraceConfig
|
|
159
|
+
| OTLPTraceConfig
|
|
160
|
+
| CustomTraceConfig;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server utilities for AG-Kit observability.
|
|
3
|
+
*
|
|
4
|
+
* Provides server-side observability features like AUTO_TRACES_STDOUT
|
|
5
|
+
* and unified trace exporter configuration.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Unified setup API
|
|
11
|
+
export {
|
|
12
|
+
setupObservability,
|
|
13
|
+
type ObservabilityConfig,
|
|
14
|
+
type ConsoleTraceConfig,
|
|
15
|
+
type OTLPTraceConfig,
|
|
16
|
+
type CustomTraceConfig,
|
|
17
|
+
type BatchConfig,
|
|
18
|
+
} from './setup.js';
|
|
19
|
+
|
|
20
|
+
// Exporter type constants
|
|
21
|
+
export { ExporterType } from './config.js';
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability setup implementation for AG-Kit Server.
|
|
3
|
+
*
|
|
4
|
+
* Merges configuration from environment variables and parameters,
|
|
5
|
+
* then applies each exporter configuration.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
BatchConfig,
|
|
12
|
+
ObservabilityConfig,
|
|
13
|
+
ConsoleTraceConfig,
|
|
14
|
+
OTLPTraceConfig,
|
|
15
|
+
CustomTraceConfig,
|
|
16
|
+
} from './config';
|
|
17
|
+
|
|
18
|
+
export type {
|
|
19
|
+
BatchConfig,
|
|
20
|
+
ObservabilityConfig,
|
|
21
|
+
ConsoleTraceConfig,
|
|
22
|
+
OTLPTraceConfig,
|
|
23
|
+
CustomTraceConfig,
|
|
24
|
+
} from './config';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Environment variable truthy values.
|
|
28
|
+
* Matches Python SDK implementation for consistency.
|
|
29
|
+
*/
|
|
30
|
+
const TRUTHY_ENV_VALUES = new Set(['true', '1', 'yes', 'on']);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Merged configuration result.
|
|
34
|
+
* Console config allows merge (param overrides env),
|
|
35
|
+
* while OTLP and custom configs are arrays (additive).
|
|
36
|
+
*/
|
|
37
|
+
interface MergedConfig {
|
|
38
|
+
console?: ConsoleTraceConfig | null;
|
|
39
|
+
otlp: OTLPTraceConfig[];
|
|
40
|
+
custom: CustomTraceConfig[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Default batch configuration.
|
|
45
|
+
*/
|
|
46
|
+
const DEFAULT_BATCH_CONFIG: Required<BatchConfig> = {
|
|
47
|
+
maxExportBatchSize: 100,
|
|
48
|
+
scheduledDelayMillis: 5000,
|
|
49
|
+
maxQueueSize: 2048,
|
|
50
|
+
exportTimeoutMillis: 30000,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Merge environment variable and parameter configurations.
|
|
55
|
+
*
|
|
56
|
+
* - AUTO_TRACES_STDOUT env adds a console config
|
|
57
|
+
* - Parameter configs override/extend env configs
|
|
58
|
+
*/
|
|
59
|
+
function mergeConfigs(paramConfigs: ObservabilityConfig[]): MergedConfig {
|
|
60
|
+
const result: MergedConfig = {
|
|
61
|
+
console: null,
|
|
62
|
+
otlp: [],
|
|
63
|
+
custom: [],
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// 1. Check AUTO_TRACES_STDOUT env
|
|
67
|
+
const autoTracesStdout = process.env.AUTO_TRACES_STDOUT?.toLowerCase() || '';
|
|
68
|
+
if (TRUTHY_ENV_VALUES.has(autoTracesStdout)) {
|
|
69
|
+
result.console = { type: 'console' };
|
|
70
|
+
console.debug(
|
|
71
|
+
`[Observability] AUTO_TRACES_STDOUT=${autoTracesStdout}, console exporter enabled`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 2. Process parameter configs
|
|
76
|
+
for (const config of paramConfigs) {
|
|
77
|
+
switch (config.type) {
|
|
78
|
+
case 'console':
|
|
79
|
+
// Parameter overrides env (merge batch config)
|
|
80
|
+
result.console = { ...result.console, ...config };
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case 'otlp':
|
|
84
|
+
result.otlp.push(config);
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
case 'custom':
|
|
88
|
+
result.custom.push(config);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Apply batch configuration with defaults.
|
|
98
|
+
*/
|
|
99
|
+
function resolveBatchConfig(batch?: BatchConfig): Required<BatchConfig> {
|
|
100
|
+
return { ...DEFAULT_BATCH_CONFIG, ...batch };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Safe wrapper for exporter setup functions.
|
|
105
|
+
* Ensures individual exporter failures don't crash the entire setup.
|
|
106
|
+
*/
|
|
107
|
+
async function safeSetup(
|
|
108
|
+
name: string,
|
|
109
|
+
setupFn: () => Promise<void>
|
|
110
|
+
): Promise<void> {
|
|
111
|
+
try {
|
|
112
|
+
await setupFn();
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.warn(
|
|
115
|
+
`[Observability] ${name} setup failed (non-fatal): ${
|
|
116
|
+
error instanceof Error ? error.message : String(error)
|
|
117
|
+
}`
|
|
118
|
+
);
|
|
119
|
+
// Don't rethrow - allow other exporters to continue
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Setup console exporter.
|
|
125
|
+
*/
|
|
126
|
+
async function setupConsoleExporter(config: ConsoleTraceConfig): Promise<void> {
|
|
127
|
+
const { trace } = await import('@opentelemetry/api');
|
|
128
|
+
const { resourceFromAttributes } = await import('@opentelemetry/resources');
|
|
129
|
+
const { NodeTracerProvider } = await import('@opentelemetry/sdk-trace-node');
|
|
130
|
+
const { ConsoleSpanExporter, BatchSpanProcessor } = await import(
|
|
131
|
+
'@opentelemetry/sdk-trace-base'
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const batchConfig = resolveBatchConfig(config.batch);
|
|
135
|
+
|
|
136
|
+
// Check if a real TracerProvider already exists
|
|
137
|
+
let provider = trace.getTracerProvider();
|
|
138
|
+
const isRealProvider = 'addSpanProcessor' in provider;
|
|
139
|
+
|
|
140
|
+
if (isRealProvider) {
|
|
141
|
+
// Add processor to existing provider
|
|
142
|
+
const exporter = new ConsoleSpanExporter();
|
|
143
|
+
const processor = new BatchSpanProcessor(exporter, batchConfig);
|
|
144
|
+
(provider as any).addSpanProcessor(processor);
|
|
145
|
+
|
|
146
|
+
console.info(
|
|
147
|
+
`[Observability] Console exporter configured (batch=${batchConfig.maxExportBatchSize}, ` +
|
|
148
|
+
`delay=${batchConfig.scheduledDelayMillis}ms)`
|
|
149
|
+
);
|
|
150
|
+
} else {
|
|
151
|
+
// Create new provider with console exporter
|
|
152
|
+
const resource = resourceFromAttributes({
|
|
153
|
+
'service.name': process.env.OTEL_SERVICE_NAME || 'ag-ui-server',
|
|
154
|
+
'service.version': '1.0.0',
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const exporter = new ConsoleSpanExporter();
|
|
158
|
+
const processor = new BatchSpanProcessor(exporter, batchConfig);
|
|
159
|
+
|
|
160
|
+
const tracerProvider = new NodeTracerProvider({
|
|
161
|
+
resource,
|
|
162
|
+
spanProcessors: [processor],
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
tracerProvider.register();
|
|
166
|
+
|
|
167
|
+
console.info(
|
|
168
|
+
`[Observability] Console exporter configured (batch=${batchConfig.maxExportBatchSize}, ` +
|
|
169
|
+
`delay=${batchConfig.scheduledDelayMillis}ms)`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Setup OTLP exporter.
|
|
176
|
+
*/
|
|
177
|
+
async function setupOTLPExporter(config: OTLPTraceConfig): Promise<void> {
|
|
178
|
+
const { trace } = await import('@opentelemetry/api');
|
|
179
|
+
const { resourceFromAttributes } = await import('@opentelemetry/resources');
|
|
180
|
+
const { NodeTracerProvider } = await import('@opentelemetry/sdk-trace-node');
|
|
181
|
+
const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');
|
|
182
|
+
const { BatchSpanProcessor } = await import('@opentelemetry/sdk-trace-base');
|
|
183
|
+
|
|
184
|
+
const batchConfig = resolveBatchConfig(config.batch);
|
|
185
|
+
|
|
186
|
+
// Check if a real TracerProvider already exists
|
|
187
|
+
let provider = trace.getTracerProvider();
|
|
188
|
+
const isRealProvider = 'addSpanProcessor' in provider;
|
|
189
|
+
|
|
190
|
+
if (isRealProvider) {
|
|
191
|
+
// Add processor to existing provider
|
|
192
|
+
const exporter = new OTLPTraceExporter({
|
|
193
|
+
url: config.url,
|
|
194
|
+
headers: config.headers,
|
|
195
|
+
timeoutMillis: config.timeout ?? 10000,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const processor = new BatchSpanProcessor(exporter, batchConfig);
|
|
199
|
+
(provider as any).addSpanProcessor(processor);
|
|
200
|
+
|
|
201
|
+
console.info(
|
|
202
|
+
`[Observability] OTLP exporter configured (url=${config.url}, ` +
|
|
203
|
+
`batch=${batchConfig.maxExportBatchSize}, delay=${batchConfig.scheduledDelayMillis}ms)`
|
|
204
|
+
);
|
|
205
|
+
} else {
|
|
206
|
+
// Create new provider with OTLP exporter
|
|
207
|
+
const resource = resourceFromAttributes({
|
|
208
|
+
'service.name': process.env.OTEL_SERVICE_NAME || 'ag-ui-server',
|
|
209
|
+
'service.version': '1.0.0',
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const exporter = new OTLPTraceExporter({
|
|
213
|
+
url: config.url,
|
|
214
|
+
headers: config.headers,
|
|
215
|
+
timeoutMillis: config.timeout ?? 10000,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const processor = new BatchSpanProcessor(exporter, batchConfig);
|
|
219
|
+
|
|
220
|
+
const tracerProvider = new NodeTracerProvider({
|
|
221
|
+
resource,
|
|
222
|
+
spanProcessors: [processor],
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
tracerProvider.register();
|
|
226
|
+
|
|
227
|
+
console.info(
|
|
228
|
+
`[Observability] OTLP exporter configured (url=${config.url}, ` +
|
|
229
|
+
`batch=${batchConfig.maxExportBatchSize}, delay=${batchConfig.scheduledDelayMillis}ms)`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Setup custom exporter.
|
|
236
|
+
*/
|
|
237
|
+
async function setupCustomExporter(config: CustomTraceConfig): Promise<void> {
|
|
238
|
+
await config.setup();
|
|
239
|
+
console.info(`[Observability] Custom exporter setup completed`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Setup observability from merged configuration.
|
|
244
|
+
*
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
async function applyMergedConfigs(merged: MergedConfig): Promise<void> {
|
|
248
|
+
const setupTasks: Promise<void>[] = [];
|
|
249
|
+
|
|
250
|
+
// Apply console (non-blocking)
|
|
251
|
+
if (merged.console) {
|
|
252
|
+
setupTasks.push(safeSetup('Console exporter', () => setupConsoleExporter(merged.console!)));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Apply otlp (non-blocking)
|
|
256
|
+
for (const otlp of merged.otlp) {
|
|
257
|
+
setupTasks.push(safeSetup(`OTLP exporter (${otlp.url})`, () => setupOTLPExporter(otlp)));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Apply custom (non-blocking)
|
|
261
|
+
for (const custom of merged.custom) {
|
|
262
|
+
setupTasks.push(safeSetup('Custom exporter', () => setupCustomExporter(custom)));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Wait for all exporters to complete (or fail gracefully)
|
|
266
|
+
await Promise.all(setupTasks);
|
|
267
|
+
|
|
268
|
+
if (merged.console || merged.otlp.length > 0 || merged.custom.length > 0) {
|
|
269
|
+
console.info(`[Observability] Setup completed`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Setup observability from configuration.
|
|
275
|
+
*
|
|
276
|
+
* Merges environment variable (AUTO_TRACES_STDOUT) with parameter configs,
|
|
277
|
+
* then applies each exporter configuration.
|
|
278
|
+
*
|
|
279
|
+
* Environment variables act as presets, parameter configs override or extend.
|
|
280
|
+
*
|
|
281
|
+
* Returns a promise that resolves when setup is complete. This allows callers
|
|
282
|
+
* to await initialization before proceeding, eliminating race conditions.
|
|
283
|
+
*
|
|
284
|
+
* The returned promise is cached - subsequent calls return the same promise
|
|
285
|
+
* to avoid duplicate initialization.
|
|
286
|
+
*
|
|
287
|
+
* @param configs - Observability configuration(s)
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```typescript
|
|
291
|
+
* // Console only (from env)
|
|
292
|
+
* await setupObservability();
|
|
293
|
+
*
|
|
294
|
+
* // Console + OTLP
|
|
295
|
+
* await setupObservability([
|
|
296
|
+
* { type: 'console' },
|
|
297
|
+
* { type: 'otlp', url: 'http://localhost:4318/v1/traces' }
|
|
298
|
+
* ]);
|
|
299
|
+
*
|
|
300
|
+
* // OTLP only
|
|
301
|
+
* await setupObservability({
|
|
302
|
+
* type: 'otlp',
|
|
303
|
+
* url: 'https://cloud.langfuse.com/api/public/otlp/v1/traces',
|
|
304
|
+
* headers: { 'Authorization': 'Basic xxx' }
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*
|
|
308
|
+
* @public
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
let setupPromise: Promise<void> | null = null;
|
|
312
|
+
|
|
313
|
+
export async function setupObservability(
|
|
314
|
+
configs?: ObservabilityConfig | ObservabilityConfig[]
|
|
315
|
+
): Promise<void> {
|
|
316
|
+
// Return cached promise if setup is in progress or completed
|
|
317
|
+
if (setupPromise) {
|
|
318
|
+
return setupPromise;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Create the setup promise
|
|
322
|
+
setupPromise = (async () => {
|
|
323
|
+
try {
|
|
324
|
+
// Normalize to array
|
|
325
|
+
const configsArray = configs
|
|
326
|
+
? Array.isArray(configs)
|
|
327
|
+
? configs
|
|
328
|
+
: [configs]
|
|
329
|
+
: [];
|
|
330
|
+
|
|
331
|
+
// Merge env and parameter configs
|
|
332
|
+
const merged = mergeConfigs(configsArray);
|
|
333
|
+
|
|
334
|
+
// Apply merged configs
|
|
335
|
+
await applyMergedConfigs(merged);
|
|
336
|
+
} catch (error) {
|
|
337
|
+
// Reset promise on error to allow retry
|
|
338
|
+
setupPromise = null;
|
|
339
|
+
throw error;
|
|
340
|
+
}
|
|
341
|
+
})();
|
|
342
|
+
|
|
343
|
+
return setupPromise;
|
|
344
|
+
}
|