@agentuity/server 0.0.4 → 0.0.6
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/AGENTS.md +29 -96
- package/README.md +31 -198
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/package.json +11 -32
- package/dist/_config.d.ts +0 -61
- package/dist/_config.d.ts.map +0 -1
- package/dist/_context.d.ts +0 -33
- package/dist/_context.d.ts.map +0 -1
- package/dist/_idle.d.ts +0 -7
- package/dist/_idle.d.ts.map +0 -1
- package/dist/_server.d.ts +0 -17
- package/dist/_server.d.ts.map +0 -1
- package/dist/_services.d.ts +0 -2
- package/dist/_services.d.ts.map +0 -1
- package/dist/_util.d.ts +0 -16
- package/dist/_util.d.ts.map +0 -1
- package/dist/_waituntil.d.ts +0 -20
- package/dist/_waituntil.d.ts.map +0 -1
- package/dist/agent.d.ts +0 -88
- package/dist/agent.d.ts.map +0 -1
- package/dist/app.d.ts +0 -24
- package/dist/app.d.ts.map +0 -1
- package/dist/logger/console.d.ts +0 -50
- package/dist/logger/console.d.ts.map +0 -1
- package/dist/logger/index.d.ts +0 -4
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/logger/internal.d.ts +0 -79
- package/dist/logger/internal.d.ts.map +0 -1
- package/dist/logger/logger.d.ts +0 -41
- package/dist/logger/logger.d.ts.map +0 -1
- package/dist/logger/user.d.ts +0 -8
- package/dist/logger/user.d.ts.map +0 -1
- package/dist/logger/util.d.ts +0 -11
- package/dist/logger/util.d.ts.map +0 -1
- package/dist/otel/config.d.ts +0 -17
- package/dist/otel/config.d.ts.map +0 -1
- package/dist/otel/console.d.ts +0 -26
- package/dist/otel/console.d.ts.map +0 -1
- package/dist/otel/fetch.d.ts +0 -12
- package/dist/otel/fetch.d.ts.map +0 -1
- package/dist/otel/http.d.ts +0 -16
- package/dist/otel/http.d.ts.map +0 -1
- package/dist/otel/logger.d.ts +0 -36
- package/dist/otel/logger.d.ts.map +0 -1
- package/dist/otel/otel.d.ts +0 -58
- package/dist/otel/otel.d.ts.map +0 -1
- package/dist/router.d.ts +0 -37
- package/dist/router.d.ts.map +0 -1
- package/src/_config.ts +0 -101
- package/src/_context.ts +0 -88
- package/src/_idle.ts +0 -26
- package/src/_server.ts +0 -278
- package/src/_services.ts +0 -175
- package/src/_util.ts +0 -63
- package/src/_waituntil.ts +0 -246
- package/src/agent.ts +0 -287
- package/src/app.ts +0 -31
- package/src/index.ts +0 -5
- package/src/logger/console.ts +0 -111
- package/src/logger/index.ts +0 -3
- package/src/logger/internal.ts +0 -165
- package/src/logger/logger.ts +0 -44
- package/src/logger/user.ts +0 -11
- package/src/logger/util.ts +0 -80
- package/src/otel/config.ts +0 -81
- package/src/otel/console.ts +0 -56
- package/src/otel/fetch.ts +0 -103
- package/src/otel/http.ts +0 -51
- package/src/otel/logger.ts +0 -238
- package/src/otel/otel.ts +0 -317
- package/src/router.ts +0 -303
package/src/otel/logger.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { format } from 'node:util';
|
|
2
|
-
import { safeStringify } from '@agentuity/core';
|
|
3
|
-
import * as LogsAPI from '@opentelemetry/api-logs';
|
|
4
|
-
import type { Logger } from '../logger';
|
|
5
|
-
import ConsoleLogger from '../logger/console';
|
|
6
|
-
import { getAgentContext } from '../_context';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Reference to the original console object before patching
|
|
10
|
-
*/
|
|
11
|
-
export const __originalConsole = Object.create(console); // save the original console before we patch it
|
|
12
|
-
|
|
13
|
-
export class OtelLogger implements Logger {
|
|
14
|
-
private readonly delegates: LogsAPI.Logger[];
|
|
15
|
-
private readonly context: Record<string, unknown> | undefined;
|
|
16
|
-
private readonly logger: ConsoleLogger | undefined;
|
|
17
|
-
|
|
18
|
-
constructor(
|
|
19
|
-
useConsole: boolean,
|
|
20
|
-
delegates: LogsAPI.Logger | LogsAPI.Logger[],
|
|
21
|
-
context?: Record<string, unknown> | undefined
|
|
22
|
-
) {
|
|
23
|
-
this.delegates = Array.isArray(delegates) ? delegates : [delegates];
|
|
24
|
-
this.context = context;
|
|
25
|
-
this.logger = useConsole ? new ConsoleLogger(context, false) : undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
addDelegate(delegate: LogsAPI.Logger) {
|
|
29
|
-
this.delegates.push(delegate);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private formatMessage(message: unknown) {
|
|
33
|
-
if (typeof message === 'string') {
|
|
34
|
-
return message;
|
|
35
|
-
}
|
|
36
|
-
try {
|
|
37
|
-
return safeStringify(message);
|
|
38
|
-
} catch {
|
|
39
|
-
// Handle circular references or other unknown stringification errors
|
|
40
|
-
return String(message);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private getAttributes(): Record<string, unknown> | undefined {
|
|
45
|
-
try {
|
|
46
|
-
const actx = getAgentContext();
|
|
47
|
-
const current = actx.current?.metadata;
|
|
48
|
-
if (current) {
|
|
49
|
-
const result: Record<string, unknown> = {
|
|
50
|
-
...(this.context ?? {}),
|
|
51
|
-
};
|
|
52
|
-
for (const [key, value] of Object.entries(current)) {
|
|
53
|
-
if (value !== null && value !== undefined) {
|
|
54
|
-
result[`@agentuity/${key}`] = value as unknown;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
} catch {
|
|
60
|
-
/* fall through */
|
|
61
|
-
}
|
|
62
|
-
return this.context;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private emitToAll(severityNumber: LogsAPI.SeverityNumber, severityText: string, body: string) {
|
|
66
|
-
const attributes = this.getAttributes();
|
|
67
|
-
|
|
68
|
-
this.delegates.forEach((delegate) => {
|
|
69
|
-
try {
|
|
70
|
-
delegate.emit({
|
|
71
|
-
severityNumber,
|
|
72
|
-
severityText,
|
|
73
|
-
body,
|
|
74
|
-
attributes: attributes as LogsAPI.LogRecord['attributes'],
|
|
75
|
-
});
|
|
76
|
-
} catch (error) {
|
|
77
|
-
// Log error to console if available, but don't fail the entire operation
|
|
78
|
-
this.logger?.error('Failed to emit log to OTLP instance:', error);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
debug(message: string, ...args: unknown[]) {
|
|
84
|
-
this.logger?.debug(message, ...args);
|
|
85
|
-
let body: string;
|
|
86
|
-
try {
|
|
87
|
-
body = format(this.formatMessage(message), ...args);
|
|
88
|
-
} catch {
|
|
89
|
-
// Fallback if format causes recursion
|
|
90
|
-
body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
|
|
91
|
-
}
|
|
92
|
-
this.emitToAll(LogsAPI.SeverityNumber.DEBUG, 'DEBUG', body);
|
|
93
|
-
}
|
|
94
|
-
info(message: string, ...args: unknown[]) {
|
|
95
|
-
this.logger?.info(message, ...args);
|
|
96
|
-
let body: string;
|
|
97
|
-
try {
|
|
98
|
-
body = format(this.formatMessage(message), ...args);
|
|
99
|
-
} catch {
|
|
100
|
-
// Fallback if format causes recursion
|
|
101
|
-
body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
|
|
102
|
-
}
|
|
103
|
-
this.emitToAll(LogsAPI.SeverityNumber.INFO, 'INFO', body);
|
|
104
|
-
}
|
|
105
|
-
warn(message: string, ...args: unknown[]) {
|
|
106
|
-
this.logger?.warn(message, ...args);
|
|
107
|
-
let body: string;
|
|
108
|
-
try {
|
|
109
|
-
body = format(this.formatMessage(message), ...args);
|
|
110
|
-
} catch {
|
|
111
|
-
// Fallback if format causes recursion
|
|
112
|
-
body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
|
|
113
|
-
}
|
|
114
|
-
this.emitToAll(LogsAPI.SeverityNumber.WARN, 'WARN', body);
|
|
115
|
-
}
|
|
116
|
-
error(message: string, ...args: unknown[]) {
|
|
117
|
-
this.logger?.error(message, ...args);
|
|
118
|
-
let body: string;
|
|
119
|
-
try {
|
|
120
|
-
body = format(this.formatMessage(message), ...args);
|
|
121
|
-
} catch {
|
|
122
|
-
// Fallback if format causes recursion
|
|
123
|
-
body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
|
|
124
|
-
}
|
|
125
|
-
this.emitToAll(LogsAPI.SeverityNumber.ERROR, 'ERROR', body);
|
|
126
|
-
}
|
|
127
|
-
child(opts: Record<string, unknown>) {
|
|
128
|
-
return new OtelLogger(!!this.logger, this.delegates, {
|
|
129
|
-
...(this.context ?? {}),
|
|
130
|
-
...opts,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Creates a logger that integrates with OpenTelemetry
|
|
137
|
-
*
|
|
138
|
-
* @param useConsole - Whether to also log to the console
|
|
139
|
-
* @param context - Additional context to include with log records
|
|
140
|
-
* @returns A logger instance
|
|
141
|
-
*/
|
|
142
|
-
export function createLogger(useConsole: boolean, context?: Record<string, unknown>): Logger {
|
|
143
|
-
const delegate = LogsAPI.logs.getLogger('default', undefined, {
|
|
144
|
-
scopeAttributes: context as LogsAPI.LoggerOptions['scopeAttributes'],
|
|
145
|
-
});
|
|
146
|
-
return new OtelLogger(useConsole, [delegate], context);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Patches the global console object to integrate with OpenTelemetry logging
|
|
151
|
-
*
|
|
152
|
-
* @param attributes - Attributes to include with all console log records
|
|
153
|
-
*/
|
|
154
|
-
export function patchConsole(enabled: boolean, attributes: Record<string, unknown>) {
|
|
155
|
-
if (!enabled) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const _patch = { ...__originalConsole };
|
|
159
|
-
const delegate = createLogger(true, attributes);
|
|
160
|
-
|
|
161
|
-
// Patch individual console methods instead of reassigning the whole object
|
|
162
|
-
_patch.log = (...args: unknown[]) => {
|
|
163
|
-
delegate.info(args[0] as string, ...args.slice(1));
|
|
164
|
-
};
|
|
165
|
-
_patch.error = (...args: unknown[]) => {
|
|
166
|
-
delegate.error(args[0] as string, ...args.slice(1));
|
|
167
|
-
};
|
|
168
|
-
_patch.warn = (...args: unknown[]) => {
|
|
169
|
-
delegate.warn(args[0] as string, ...args.slice(1));
|
|
170
|
-
};
|
|
171
|
-
_patch.debug = (...args: unknown[]) => {
|
|
172
|
-
delegate.debug(args[0] as string, ...args.slice(1));
|
|
173
|
-
};
|
|
174
|
-
_patch.info = (...args: unknown[]) => {
|
|
175
|
-
delegate.info(args[0] as string, ...args.slice(1));
|
|
176
|
-
};
|
|
177
|
-
_patch.dir = (...args: unknown[]) => {
|
|
178
|
-
let msg = '';
|
|
179
|
-
if (args.length === 1) {
|
|
180
|
-
msg = format(args[0]);
|
|
181
|
-
} else if (args.length >= 2) {
|
|
182
|
-
msg = format(args[0], args[1]);
|
|
183
|
-
} else {
|
|
184
|
-
msg = safeStringify(args);
|
|
185
|
-
}
|
|
186
|
-
delegate.debug(msg);
|
|
187
|
-
};
|
|
188
|
-
_patch.dirxml = (...args: unknown[]) => {
|
|
189
|
-
delegate.debug('dirxml:', ...args);
|
|
190
|
-
};
|
|
191
|
-
_patch.table = (...args: unknown[]) => {
|
|
192
|
-
delegate.debug('table:', ...args);
|
|
193
|
-
};
|
|
194
|
-
_patch.trace = (...args: unknown[]) => {
|
|
195
|
-
delegate.debug(args[0] as string, ...args.slice(1));
|
|
196
|
-
};
|
|
197
|
-
_patch.group = (...args: unknown[]) => {
|
|
198
|
-
delegate.debug('group:', ...args);
|
|
199
|
-
};
|
|
200
|
-
_patch.groupCollapsed = (...args: unknown[]) => {
|
|
201
|
-
delegate.debug('groupCollapsed:', ...args);
|
|
202
|
-
};
|
|
203
|
-
_patch.groupEnd = () => {
|
|
204
|
-
delegate.debug('groupEnd');
|
|
205
|
-
};
|
|
206
|
-
_patch.clear = () => {
|
|
207
|
-
/* no-op */
|
|
208
|
-
};
|
|
209
|
-
_patch.count = (...args: unknown[]) => {
|
|
210
|
-
delegate.debug('count:', ...args);
|
|
211
|
-
};
|
|
212
|
-
_patch.countReset = (...args: unknown[]) => {
|
|
213
|
-
delegate.debug('countReset:', ...args);
|
|
214
|
-
};
|
|
215
|
-
_patch.assert = (condition?: boolean, ...args: unknown[]) => {
|
|
216
|
-
if (!condition) {
|
|
217
|
-
delegate.error('assertion failed:', ...args);
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
_patch.time = (...args: unknown[]) => {
|
|
221
|
-
delegate.debug('time:', ...args);
|
|
222
|
-
};
|
|
223
|
-
_patch.timeLog = (...args: unknown[]) => {
|
|
224
|
-
delegate.debug('timeLog:', ...args);
|
|
225
|
-
};
|
|
226
|
-
_patch.timeEnd = (...args: unknown[]) => {
|
|
227
|
-
delegate.debug('timeEnd:', ...args);
|
|
228
|
-
};
|
|
229
|
-
_patch.profile = (...args: unknown[]) => {
|
|
230
|
-
delegate.debug('profile:', ...args);
|
|
231
|
-
};
|
|
232
|
-
_patch.profileEnd = (...args: unknown[]) => {
|
|
233
|
-
delegate.debug('profileEnd:', ...args);
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// eslint-disable-next-line no-global-assign
|
|
237
|
-
console = globalThis.console = _patch;
|
|
238
|
-
}
|
package/src/otel/otel.ts
DELETED
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
import type { SpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
2
|
-
import opentelemetry, { type Meter, metrics, propagation, type Tracer } from '@opentelemetry/api';
|
|
3
|
-
import * as LogsAPI from '@opentelemetry/api-logs';
|
|
4
|
-
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
5
|
-
import {
|
|
6
|
-
CompositePropagator,
|
|
7
|
-
W3CBaggagePropagator,
|
|
8
|
-
W3CTraceContextPropagator,
|
|
9
|
-
} from '@opentelemetry/core';
|
|
10
|
-
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
11
|
-
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
|
12
|
-
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
13
|
-
import { HostMetrics } from '@opentelemetry/host-metrics';
|
|
14
|
-
import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base';
|
|
15
|
-
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
16
|
-
import type { Resource } from '@opentelemetry/resources';
|
|
17
|
-
import {
|
|
18
|
-
BatchLogRecordProcessor,
|
|
19
|
-
LoggerProvider,
|
|
20
|
-
type LogRecordProcessor,
|
|
21
|
-
SimpleLogRecordProcessor,
|
|
22
|
-
} from '@opentelemetry/sdk-logs';
|
|
23
|
-
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
|
24
|
-
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
25
|
-
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
|
|
26
|
-
import { initialize } from '@traceloop/node-server-sdk';
|
|
27
|
-
import type { Logger } from '../logger';
|
|
28
|
-
import { ConsoleLogRecordExporter } from './console';
|
|
29
|
-
import { instrumentFetch } from './fetch';
|
|
30
|
-
import { createLogger, patchConsole } from './logger';
|
|
31
|
-
import { getSDKVersion } from '../_config';
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Configuration for OpenTelemetry initialization
|
|
35
|
-
*/
|
|
36
|
-
export interface OtelConfig {
|
|
37
|
-
url?: string;
|
|
38
|
-
name: string;
|
|
39
|
-
version: string;
|
|
40
|
-
bearerToken?: string;
|
|
41
|
-
orgId?: string;
|
|
42
|
-
projectId?: string;
|
|
43
|
-
deploymentId?: string;
|
|
44
|
-
environment?: string;
|
|
45
|
-
cliVersion?: string;
|
|
46
|
-
devmode?: boolean;
|
|
47
|
-
spanProcessors?: Array<SpanProcessor>;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Response from OpenTelemetry initialization
|
|
52
|
-
*/
|
|
53
|
-
export interface OtelResponse {
|
|
54
|
-
tracer: Tracer;
|
|
55
|
-
meter: Meter;
|
|
56
|
-
logger: Logger;
|
|
57
|
-
shutdown: () => Promise<void>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const devmodeExportInterval = 1_000; // 1 second
|
|
61
|
-
const productionExportInterval = 10_000; // 10 seconds
|
|
62
|
-
|
|
63
|
-
export const createResource = (config: OtelConfig): Resource => {
|
|
64
|
-
const { name, version, orgId, projectId, deploymentId, environment, devmode, cliVersion } =
|
|
65
|
-
config;
|
|
66
|
-
|
|
67
|
-
const sdkVersion = getSDKVersion();
|
|
68
|
-
|
|
69
|
-
return resourceFromAttributes({
|
|
70
|
-
[ATTR_SERVICE_NAME]: name,
|
|
71
|
-
[ATTR_SERVICE_VERSION]: version,
|
|
72
|
-
'@agentuity/orgId': orgId ?? 'unknown',
|
|
73
|
-
'@agentuity/projectId': projectId ?? 'unknown',
|
|
74
|
-
'@agentuity/deploymentId': deploymentId ?? 'unknown',
|
|
75
|
-
'@agentuity/env': environment,
|
|
76
|
-
'@agentuity/devmode': devmode,
|
|
77
|
-
'@agentuity/sdkVersion': sdkVersion ?? 'unknown',
|
|
78
|
-
'@agentuity/cliVersion': cliVersion ?? 'unknown',
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export const createAgentuityLoggerProvider = ({
|
|
83
|
-
url,
|
|
84
|
-
headers,
|
|
85
|
-
resource,
|
|
86
|
-
}: {
|
|
87
|
-
url?: string;
|
|
88
|
-
headers?: Record<string, string>;
|
|
89
|
-
resource: Resource;
|
|
90
|
-
}) => {
|
|
91
|
-
let processor: LogRecordProcessor;
|
|
92
|
-
let exporter: OTLPLogExporter | undefined;
|
|
93
|
-
|
|
94
|
-
if (url) {
|
|
95
|
-
exporter = new OTLPLogExporter({
|
|
96
|
-
url: `${url}/v1/logs`,
|
|
97
|
-
headers,
|
|
98
|
-
compression: CompressionAlgorithm.GZIP,
|
|
99
|
-
timeoutMillis: 10_000,
|
|
100
|
-
});
|
|
101
|
-
processor = new BatchLogRecordProcessor(exporter);
|
|
102
|
-
} else {
|
|
103
|
-
processor = new SimpleLogRecordProcessor(new ConsoleLogRecordExporter());
|
|
104
|
-
}
|
|
105
|
-
const provider = new LoggerProvider({
|
|
106
|
-
resource,
|
|
107
|
-
processors: [processor],
|
|
108
|
-
});
|
|
109
|
-
LogsAPI.logs.setGlobalLoggerProvider(provider);
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
processor,
|
|
113
|
-
provider,
|
|
114
|
-
exporter,
|
|
115
|
-
};
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export const createUserLoggerProvider = ({
|
|
119
|
-
url,
|
|
120
|
-
headers,
|
|
121
|
-
resource,
|
|
122
|
-
}: {
|
|
123
|
-
url: string;
|
|
124
|
-
headers?: Record<string, string>;
|
|
125
|
-
resource: Resource;
|
|
126
|
-
}) => {
|
|
127
|
-
const exporter = new OTLPLogExporter({
|
|
128
|
-
url: `${url}/v1/logs`,
|
|
129
|
-
headers,
|
|
130
|
-
compression: CompressionAlgorithm.GZIP,
|
|
131
|
-
timeoutMillis: 10_000,
|
|
132
|
-
});
|
|
133
|
-
const processor = new BatchLogRecordProcessor(exporter);
|
|
134
|
-
const provider = new LoggerProvider({
|
|
135
|
-
resource,
|
|
136
|
-
processors: [processor],
|
|
137
|
-
});
|
|
138
|
-
return {
|
|
139
|
-
provider,
|
|
140
|
-
exporter,
|
|
141
|
-
processor,
|
|
142
|
-
};
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Registers and initializes OpenTelemetry with the specified configuration
|
|
147
|
-
*
|
|
148
|
-
* @param config - The configuration for OpenTelemetry
|
|
149
|
-
* @returns An object containing the tracer, logger, and shutdown function
|
|
150
|
-
*/
|
|
151
|
-
export function registerOtel(config: OtelConfig): OtelResponse {
|
|
152
|
-
const {
|
|
153
|
-
url,
|
|
154
|
-
name,
|
|
155
|
-
version,
|
|
156
|
-
bearerToken,
|
|
157
|
-
environment = 'development',
|
|
158
|
-
orgId,
|
|
159
|
-
projectId,
|
|
160
|
-
deploymentId,
|
|
161
|
-
devmode = false,
|
|
162
|
-
} = config;
|
|
163
|
-
|
|
164
|
-
let headers: Record<string, string> | undefined;
|
|
165
|
-
|
|
166
|
-
if (bearerToken) {
|
|
167
|
-
headers = {};
|
|
168
|
-
headers.Authorization = `Bearer ${bearerToken}`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const resource = createResource(config);
|
|
172
|
-
const loggerProvider = createAgentuityLoggerProvider({
|
|
173
|
-
url,
|
|
174
|
-
headers,
|
|
175
|
-
resource,
|
|
176
|
-
});
|
|
177
|
-
const attrs = {
|
|
178
|
-
'@agentuity/orgId': orgId ?? 'unknown',
|
|
179
|
-
'@agentuity/projectId': projectId ?? 'unknown',
|
|
180
|
-
'@agentuity/deploymentId': deploymentId ?? 'unknown',
|
|
181
|
-
'@agentuity/env': environment,
|
|
182
|
-
'@agentuity/devmode': devmode,
|
|
183
|
-
'@agentuity/language': 'javascript',
|
|
184
|
-
};
|
|
185
|
-
const logger = createLogger(!!url, attrs);
|
|
186
|
-
|
|
187
|
-
// must do this after we have created the logger
|
|
188
|
-
patchConsole(!!url, attrs);
|
|
189
|
-
|
|
190
|
-
const traceExporter = url
|
|
191
|
-
? new OTLPTraceExporter({
|
|
192
|
-
url: `${url}/v1/traces`,
|
|
193
|
-
headers,
|
|
194
|
-
keepAlive: true,
|
|
195
|
-
})
|
|
196
|
-
: undefined;
|
|
197
|
-
|
|
198
|
-
const metricExporter = url
|
|
199
|
-
? new OTLPMetricExporter({
|
|
200
|
-
url: `${url}/v1/metrics`,
|
|
201
|
-
headers,
|
|
202
|
-
keepAlive: true,
|
|
203
|
-
})
|
|
204
|
-
: undefined;
|
|
205
|
-
|
|
206
|
-
// Create a separate metric reader for the NodeSDK
|
|
207
|
-
const sdkMetricReader =
|
|
208
|
-
url && metricExporter
|
|
209
|
-
? new PeriodicExportingMetricReader({
|
|
210
|
-
exporter: metricExporter,
|
|
211
|
-
exportTimeoutMillis: devmode ? devmodeExportInterval : productionExportInterval,
|
|
212
|
-
exportIntervalMillis: devmode ? devmodeExportInterval : productionExportInterval,
|
|
213
|
-
})
|
|
214
|
-
: undefined;
|
|
215
|
-
|
|
216
|
-
// Create a separate metric reader for the MeterProvider
|
|
217
|
-
const hostMetricReader =
|
|
218
|
-
url && metricExporter
|
|
219
|
-
? new PeriodicExportingMetricReader({
|
|
220
|
-
exporter: metricExporter,
|
|
221
|
-
exportTimeoutMillis: devmode ? devmodeExportInterval : productionExportInterval,
|
|
222
|
-
exportIntervalMillis: devmode ? devmodeExportInterval : productionExportInterval,
|
|
223
|
-
})
|
|
224
|
-
: undefined;
|
|
225
|
-
|
|
226
|
-
const meterProvider = hostMetricReader
|
|
227
|
-
? new MeterProvider({
|
|
228
|
-
resource,
|
|
229
|
-
readers: [hostMetricReader],
|
|
230
|
-
})
|
|
231
|
-
: undefined;
|
|
232
|
-
|
|
233
|
-
if (meterProvider) {
|
|
234
|
-
metrics.setGlobalMeterProvider(meterProvider);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const hostMetrics = meterProvider ? new HostMetrics({ meterProvider }) : undefined;
|
|
238
|
-
|
|
239
|
-
let running = false;
|
|
240
|
-
let instrumentationSDK: NodeSDK | undefined;
|
|
241
|
-
|
|
242
|
-
if (url) {
|
|
243
|
-
const propagator = new CompositePropagator({
|
|
244
|
-
propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()],
|
|
245
|
-
});
|
|
246
|
-
propagation.setGlobalPropagator(propagator);
|
|
247
|
-
|
|
248
|
-
instrumentFetch();
|
|
249
|
-
instrumentationSDK = new NodeSDK({
|
|
250
|
-
logRecordProcessor: loggerProvider.processor,
|
|
251
|
-
traceExporter,
|
|
252
|
-
metricReader: sdkMetricReader,
|
|
253
|
-
instrumentations: [getNodeAutoInstrumentations()],
|
|
254
|
-
resource,
|
|
255
|
-
textMapPropagator: propagator,
|
|
256
|
-
spanProcessors: config.spanProcessors,
|
|
257
|
-
});
|
|
258
|
-
instrumentationSDK.start();
|
|
259
|
-
hostMetrics?.start();
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
const projectName = config.projectId || '';
|
|
263
|
-
const orgName = config.orgId || '';
|
|
264
|
-
const appName = `${orgName}:${projectName}`;
|
|
265
|
-
|
|
266
|
-
const traceloopHeaders: Record<string, string> = {};
|
|
267
|
-
if (bearerToken) {
|
|
268
|
-
traceloopHeaders.Authorization = `Bearer ${bearerToken}`;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
initialize({
|
|
272
|
-
appName,
|
|
273
|
-
baseUrl: url,
|
|
274
|
-
headers: traceloopHeaders,
|
|
275
|
-
disableBatch: devmode,
|
|
276
|
-
logLevel: 'error',
|
|
277
|
-
tracingEnabled: false, // Disable traceloop's own tracing (equivalent to Python's telemetryEnabled: false)
|
|
278
|
-
// Note: JavaScript SDK doesn't support resourceAttributes like Python
|
|
279
|
-
});
|
|
280
|
-
logger.debug(`Telemetry initialized with app_name: ${appName}`);
|
|
281
|
-
logger.info('Telemetry configured successfully');
|
|
282
|
-
} catch (error) {
|
|
283
|
-
logger.warn('Telemetry not available, skipping automatic instrumentation', {
|
|
284
|
-
error: error instanceof Error ? error.message : String(error),
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
running = true;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const tracer = opentelemetry.trace.getTracer(name, version);
|
|
291
|
-
const meter = metrics.getMeter(name, version);
|
|
292
|
-
|
|
293
|
-
const shutdown = async () => {
|
|
294
|
-
if (running) {
|
|
295
|
-
running = false;
|
|
296
|
-
logger.debug('shutting down OpenTelemetry');
|
|
297
|
-
await loggerProvider.provider
|
|
298
|
-
.forceFlush()
|
|
299
|
-
.catch((e) => logger.warn('error in forceFlush of otel provider. %s', e));
|
|
300
|
-
await loggerProvider.exporter
|
|
301
|
-
?.shutdown()
|
|
302
|
-
.catch((e) => !devmode && logger.warn('error in shutdown of otel exporter. %s', e));
|
|
303
|
-
await instrumentationSDK
|
|
304
|
-
?.shutdown()
|
|
305
|
-
.catch(
|
|
306
|
-
(e) => !devmode && logger.warn('error in shutdown of otel instrumentation. %s', e)
|
|
307
|
-
);
|
|
308
|
-
logger.debug('shut down OpenTelemetry');
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
if (url) {
|
|
313
|
-
logger.debug('connected to Agentuity Agent Cloud');
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return { tracer, meter, logger, shutdown };
|
|
317
|
-
}
|