@agentuity/server 0.0.5 → 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 -196
- 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/logger/internal.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { formatMessage } from './util';
|
|
2
|
-
|
|
3
|
-
const cyan = '\x1b[1;96m';
|
|
4
|
-
const reset = '\x1b[0m';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Log levels for internal SDK logging
|
|
8
|
-
*/
|
|
9
|
-
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Internal logger configuration
|
|
13
|
-
*/
|
|
14
|
-
interface InternalLoggerConfig {
|
|
15
|
-
level: LogLevel;
|
|
16
|
-
context?: Record<string, unknown>;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Simple internal logger that doesn't depend on other SDK modules
|
|
21
|
-
* This logger is only for SDK internal diagnostics and debugging
|
|
22
|
-
*/
|
|
23
|
-
class InternalLogger {
|
|
24
|
-
private config: InternalLoggerConfig;
|
|
25
|
-
|
|
26
|
-
constructor() {
|
|
27
|
-
this.config = this.loadConfig();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Load configuration from environment variables
|
|
32
|
-
*/
|
|
33
|
-
private loadConfig(): InternalLoggerConfig {
|
|
34
|
-
const envLevel = process.env.AGENTUITY_SDK_LOG_LEVEL?.toLowerCase();
|
|
35
|
-
|
|
36
|
-
// Validate log level
|
|
37
|
-
const validLevels: LogLevel[] = ['debug', 'info', 'warn', 'error', 'silent'];
|
|
38
|
-
const level = validLevels.includes(envLevel as LogLevel) ? (envLevel as LogLevel) : 'silent';
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
level,
|
|
42
|
-
context: {
|
|
43
|
-
'@agentuity/source': 'sdk-internal',
|
|
44
|
-
'@agentuity/timestamp': new Date().toISOString(),
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Check if a log level should be output based on current configuration
|
|
51
|
-
*/
|
|
52
|
-
private shouldLog(level: LogLevel): boolean {
|
|
53
|
-
if (this.config.level === 'silent') return false;
|
|
54
|
-
|
|
55
|
-
const levelPriority = {
|
|
56
|
-
debug: 0,
|
|
57
|
-
info: 1,
|
|
58
|
-
warn: 2,
|
|
59
|
-
error: 3,
|
|
60
|
-
silent: 4,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return levelPriority[level] >= levelPriority[this.config.level];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Format a log message with context
|
|
68
|
-
*/
|
|
69
|
-
private formatMessage(message: unknown, ...args: unknown[]): string {
|
|
70
|
-
const formattedMessage = formatMessage(false, this.config.context, message, args);
|
|
71
|
-
return `${cyan}[INTERNAL]${reset} ${formattedMessage}`;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Log a debug message
|
|
76
|
-
*/
|
|
77
|
-
debug(message: unknown, ...args: unknown[]): void {
|
|
78
|
-
if (this.shouldLog('debug')) {
|
|
79
|
-
console.debug(this.formatMessage(message, ...args));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Log an info message
|
|
85
|
-
*/
|
|
86
|
-
info(message: unknown, ...args: unknown[]): void {
|
|
87
|
-
if (this.shouldLog('info')) {
|
|
88
|
-
console.info(this.formatMessage(message, ...args));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Log a warning message
|
|
94
|
-
*/
|
|
95
|
-
warn(message: unknown, ...args: unknown[]): void {
|
|
96
|
-
if (this.shouldLog('warn')) {
|
|
97
|
-
console.warn(this.formatMessage(message, ...args));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Log an error message
|
|
103
|
-
*/
|
|
104
|
-
error(message: unknown, ...args: unknown[]): void {
|
|
105
|
-
if (this.shouldLog('error')) {
|
|
106
|
-
console.error(this.formatMessage(message, ...args));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Update configuration at runtime
|
|
112
|
-
*/
|
|
113
|
-
updateConfig(config: Partial<InternalLoggerConfig>): void {
|
|
114
|
-
this.config = { ...this.config, ...config };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get current configuration
|
|
119
|
-
*/
|
|
120
|
-
getConfig(): InternalLoggerConfig {
|
|
121
|
-
return { ...this.config };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Check if logging is enabled
|
|
126
|
-
*/
|
|
127
|
-
isEnabled(): boolean {
|
|
128
|
-
return this.config.level !== 'silent';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Create a child logger with additional context
|
|
133
|
-
*/
|
|
134
|
-
child(context: Record<string, unknown>): InternalLogger {
|
|
135
|
-
const childLogger = new InternalLogger();
|
|
136
|
-
childLogger.updateConfig({
|
|
137
|
-
...this.config,
|
|
138
|
-
context: {
|
|
139
|
-
...this.config.context,
|
|
140
|
-
...context,
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
return childLogger;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Singleton instance - not exported
|
|
148
|
-
const internalLogger = new InternalLogger();
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Internal logger for SDK use only
|
|
152
|
-
* This is NOT exported from the main SDK index
|
|
153
|
-
*/
|
|
154
|
-
export const internal = {
|
|
155
|
-
debug: (message: unknown, ...args: unknown[]) => internalLogger.debug(message, ...args),
|
|
156
|
-
info: (message: unknown, ...args: unknown[]) => internalLogger.info(message, ...args),
|
|
157
|
-
warn: (message: unknown, ...args: unknown[]) => internalLogger.warn(message, ...args),
|
|
158
|
-
error: (message: unknown, ...args: unknown[]) => internalLogger.error(message, ...args),
|
|
159
|
-
|
|
160
|
-
// Utility methods
|
|
161
|
-
updateConfig: (config: Partial<InternalLoggerConfig>) => internalLogger.updateConfig(config),
|
|
162
|
-
getConfig: () => internalLogger.getConfig(),
|
|
163
|
-
isEnabled: () => internalLogger.isEnabled(),
|
|
164
|
-
child: (context: Record<string, unknown>) => internalLogger.child(context),
|
|
165
|
-
};
|
package/src/logger/logger.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interface for logging functionality
|
|
3
|
-
*/
|
|
4
|
-
export interface Logger {
|
|
5
|
-
/**
|
|
6
|
-
* Log a debug message
|
|
7
|
-
*
|
|
8
|
-
* @param message - The message to log
|
|
9
|
-
* @param args - Additional arguments to log
|
|
10
|
-
*/
|
|
11
|
-
debug(message: unknown, ...args: unknown[]): void;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Log an info message
|
|
15
|
-
*
|
|
16
|
-
* @param message - The message to log
|
|
17
|
-
* @param args - Additional arguments to log
|
|
18
|
-
*/
|
|
19
|
-
info(message: unknown, ...args: unknown[]): void;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Log a warning message
|
|
23
|
-
*
|
|
24
|
-
* @param message - The message to log
|
|
25
|
-
* @param args - Additional arguments to log
|
|
26
|
-
*/
|
|
27
|
-
warn(message: unknown, ...args: unknown[]): void;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Log an error message
|
|
31
|
-
*
|
|
32
|
-
* @param message - The message to log
|
|
33
|
-
* @param args - Additional arguments to log
|
|
34
|
-
*/
|
|
35
|
-
error(message: unknown, ...args: unknown[]): void;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create a child logger with additional context
|
|
39
|
-
*
|
|
40
|
-
* @param opts - Additional context for the child logger
|
|
41
|
-
* @returns A new logger instance with the additional context
|
|
42
|
-
*/
|
|
43
|
-
child(opts: Record<string, unknown>): Logger;
|
|
44
|
-
}
|
package/src/logger/user.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import ConsoleLogger from './console';
|
|
2
|
-
import type { Logger } from './logger';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* User-facing logger instance
|
|
6
|
-
* This is the logger that SDK consumers should use
|
|
7
|
-
*/
|
|
8
|
-
export const logger: Logger = new ConsoleLogger(undefined, false);
|
|
9
|
-
|
|
10
|
-
// Re-export the Logger type for convenience
|
|
11
|
-
export type { Logger } from './logger';
|
package/src/logger/util.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { formatWithOptions, inspect } from 'node:util';
|
|
2
|
-
import { safeStringify } from '@agentuity/core';
|
|
3
|
-
|
|
4
|
-
export function buildContextString(context?: Record<string, unknown>): string {
|
|
5
|
-
if (context) {
|
|
6
|
-
const contextStr =
|
|
7
|
-
context && Object.keys(context).length > 0
|
|
8
|
-
? Object.entries(context)
|
|
9
|
-
.map(([key, value]) => {
|
|
10
|
-
try {
|
|
11
|
-
return `${key}=${typeof value === 'object' ? safeStringify(value) : value}`;
|
|
12
|
-
} catch {
|
|
13
|
-
return `${key}=[object Object]`;
|
|
14
|
-
}
|
|
15
|
-
})
|
|
16
|
-
.join(' ')
|
|
17
|
-
: '';
|
|
18
|
-
|
|
19
|
-
return contextStr;
|
|
20
|
-
}
|
|
21
|
-
return '';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Formats a log message with context
|
|
26
|
-
*
|
|
27
|
-
* @param message - The message to format
|
|
28
|
-
* @param args - Additional arguments for formatting
|
|
29
|
-
* @returns The formatted message with context
|
|
30
|
-
* @private
|
|
31
|
-
*/
|
|
32
|
-
export function formatMessage(
|
|
33
|
-
displayContext: boolean,
|
|
34
|
-
context: Record<string, unknown> | undefined,
|
|
35
|
-
message: unknown,
|
|
36
|
-
args: unknown[]
|
|
37
|
-
): string {
|
|
38
|
-
// Format the context string
|
|
39
|
-
const contextStr = displayContext ? buildContextString(context) : null;
|
|
40
|
-
|
|
41
|
-
// Format the message based on its type
|
|
42
|
-
let _message: string;
|
|
43
|
-
if (typeof message === 'string') {
|
|
44
|
-
_message = message;
|
|
45
|
-
} else if (typeof message === 'number' || typeof message === 'boolean') {
|
|
46
|
-
_message = String(message);
|
|
47
|
-
} else if (message === null) {
|
|
48
|
-
_message = 'null';
|
|
49
|
-
} else if (message === undefined) {
|
|
50
|
-
_message = 'undefined';
|
|
51
|
-
} else {
|
|
52
|
-
// Use inspect for objects for better formatting
|
|
53
|
-
_message = inspect(message, { depth: null, colors: false });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Format the message with args
|
|
57
|
-
let formattedMessage: string;
|
|
58
|
-
try {
|
|
59
|
-
// Only use format if we have arguments
|
|
60
|
-
if (args.length > 0) {
|
|
61
|
-
formattedMessage = formatWithOptions({ depth: null }, _message, ...args);
|
|
62
|
-
} else {
|
|
63
|
-
formattedMessage = _message;
|
|
64
|
-
}
|
|
65
|
-
} catch {
|
|
66
|
-
// If formatting fails, use a simple concatenation
|
|
67
|
-
formattedMessage = `${_message} ${args
|
|
68
|
-
.map((arg) => {
|
|
69
|
-
try {
|
|
70
|
-
return typeof arg === 'object' ? safeStringify(arg) : String(arg);
|
|
71
|
-
} catch {
|
|
72
|
-
return '[object Object]';
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
.join(' ')}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Combine message with context
|
|
79
|
-
return `${formattedMessage}${contextStr ? ` [${contextStr}]` : ''}`;
|
|
80
|
-
}
|
package/src/otel/config.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { createResource, createUserLoggerProvider, registerOtel } from './otel';
|
|
2
|
-
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
3
|
-
import { OtelLogger } from '../otel/logger';
|
|
4
|
-
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
5
|
-
import type { LoggerProvider } from '@opentelemetry/sdk-logs';
|
|
6
|
-
import type { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
7
|
-
import type { LogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
8
|
-
import type { OtelResponse, OtelConfig } from './otel';
|
|
9
|
-
import type { SpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
10
|
-
import * as runtimeConfig from '../_config';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Configuration for user provided OpenTelemetry
|
|
14
|
-
*/
|
|
15
|
-
export interface CustomizedOtelConfig {
|
|
16
|
-
endpoint: string;
|
|
17
|
-
// only supports http/json for now
|
|
18
|
-
// protocol: 'grpc' | 'http/protobuf' | 'http/json';
|
|
19
|
-
serviceName: string;
|
|
20
|
-
resourceAttributes: Record<string, string>;
|
|
21
|
-
headers: Record<string, string>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface OtelRegisterConfig {
|
|
25
|
-
processors?: SpanProcessor[];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function register(registerConfig: OtelRegisterConfig): OtelResponse {
|
|
29
|
-
const url = process.env.AGENTUITY_OTLP_URL ?? 'https://otel.agentuity.cloud';
|
|
30
|
-
const bearerToken = process.env.AGENTUITY_OTLP_BEARER_TOKEN;
|
|
31
|
-
const config: OtelConfig = {
|
|
32
|
-
spanProcessors: registerConfig.processors,
|
|
33
|
-
name: runtimeConfig.getAppName(),
|
|
34
|
-
version: runtimeConfig.getAppVersion(),
|
|
35
|
-
cliVersion: runtimeConfig.getCLIVersion(),
|
|
36
|
-
devmode: runtimeConfig.isDevMode(),
|
|
37
|
-
orgId: runtimeConfig.getOrganizationId(),
|
|
38
|
-
projectId: runtimeConfig.getProjectId(),
|
|
39
|
-
deploymentId: runtimeConfig.getDeploymentId(),
|
|
40
|
-
environment: runtimeConfig.getEnvironment(),
|
|
41
|
-
bearerToken,
|
|
42
|
-
url,
|
|
43
|
-
};
|
|
44
|
-
let userOtelConf: CustomizedOtelConfig | undefined;
|
|
45
|
-
if (process.env.AGENTUITY_USER_OTEL_CONF) {
|
|
46
|
-
try {
|
|
47
|
-
userOtelConf = JSON.parse(process.env.AGENTUITY_USER_OTEL_CONF);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.warn(
|
|
50
|
-
`[WARN] Failed to parse AGENTUITY_USER_OTEL_CONF: ${error instanceof Error ? error.message : String(error)}`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const otel = registerOtel(config);
|
|
56
|
-
let userLoggerProvider:
|
|
57
|
-
| {
|
|
58
|
-
provider: LoggerProvider;
|
|
59
|
-
exporter: OTLPLogExporter;
|
|
60
|
-
processor: LogRecordProcessor;
|
|
61
|
-
}
|
|
62
|
-
| undefined;
|
|
63
|
-
if (userOtelConf) {
|
|
64
|
-
const resource = resourceFromAttributes({
|
|
65
|
-
...createResource(config).attributes,
|
|
66
|
-
...userOtelConf.resourceAttributes,
|
|
67
|
-
[ATTR_SERVICE_NAME]: userOtelConf.serviceName,
|
|
68
|
-
});
|
|
69
|
-
userLoggerProvider = createUserLoggerProvider({
|
|
70
|
-
url: userOtelConf.endpoint,
|
|
71
|
-
headers: userOtelConf.headers,
|
|
72
|
-
resource,
|
|
73
|
-
});
|
|
74
|
-
if (otel.logger instanceof OtelLogger) {
|
|
75
|
-
otel.logger.addDelegate(userLoggerProvider.provider.getLogger('default'));
|
|
76
|
-
} else {
|
|
77
|
-
console.warn('[WARN] user OTEL logger not attached: logger does not support addDelegate');
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return otel;
|
|
81
|
-
}
|
package/src/otel/console.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { SeverityNumber } from '@opentelemetry/api-logs';
|
|
2
|
-
import { type ExportResult, ExportResultCode } from '@opentelemetry/core';
|
|
3
|
-
import type { LogRecordExporter, ReadableLogRecord } from '@opentelemetry/sdk-logs';
|
|
4
|
-
import ConsoleLogger from '../logger/console';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Console implementation of the LogRecordExporter interface
|
|
8
|
-
*/
|
|
9
|
-
export class ConsoleLogRecordExporter implements LogRecordExporter {
|
|
10
|
-
private readonly logger: ConsoleLogger;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Creates a new console log record exporter
|
|
14
|
-
*/
|
|
15
|
-
constructor() {
|
|
16
|
-
this.logger = new ConsoleLogger();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Exports log records to the console
|
|
21
|
-
*
|
|
22
|
-
* @param logs - The log records to export
|
|
23
|
-
* @param resultCallback - Callback function to report the export result
|
|
24
|
-
*/
|
|
25
|
-
export(logs: ReadableLogRecord[], resultCallback: (result: ExportResult) => void): void {
|
|
26
|
-
for (const log of logs) {
|
|
27
|
-
switch (log.severityNumber) {
|
|
28
|
-
case SeverityNumber.DEBUG:
|
|
29
|
-
this.logger.debug(log.body);
|
|
30
|
-
break;
|
|
31
|
-
case SeverityNumber.INFO:
|
|
32
|
-
this.logger.info(log.body);
|
|
33
|
-
break;
|
|
34
|
-
case SeverityNumber.WARN:
|
|
35
|
-
this.logger.warn(log.body);
|
|
36
|
-
break;
|
|
37
|
-
case SeverityNumber.ERROR:
|
|
38
|
-
this.logger.error(log.body);
|
|
39
|
-
break;
|
|
40
|
-
default:
|
|
41
|
-
this.logger.info(log.body);
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Shuts down the exporter
|
|
50
|
-
*
|
|
51
|
-
* @returns A promise that resolves when shutdown is complete
|
|
52
|
-
*/
|
|
53
|
-
shutdown(): Promise<void> {
|
|
54
|
-
return Promise.resolve();
|
|
55
|
-
}
|
|
56
|
-
}
|
package/src/otel/fetch.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { context, propagation, SpanStatusCode, trace } from '@opentelemetry/api';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Reference to the original fetch function before instrumentation
|
|
5
|
-
*/
|
|
6
|
-
export const __originalFetch = fetch; // save the original fetch before we patch it
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Instruments the global fetch function with OpenTelemetry tracing
|
|
10
|
-
*
|
|
11
|
-
* Replaces the global fetch with an instrumented version that creates spans
|
|
12
|
-
* for each HTTP request and propagates trace context in headers
|
|
13
|
-
*/
|
|
14
|
-
export function instrumentFetch() {
|
|
15
|
-
const patch = async (
|
|
16
|
-
input: string | Request | URL,
|
|
17
|
-
init: RequestInit | undefined
|
|
18
|
-
): Promise<Response> => {
|
|
19
|
-
const url =
|
|
20
|
-
typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
21
|
-
|
|
22
|
-
const method =
|
|
23
|
-
init?.method ||
|
|
24
|
-
(typeof input !== 'string' && !(input instanceof URL) ? input.method || 'GET' : 'GET');
|
|
25
|
-
|
|
26
|
-
// Get the active span if it exists
|
|
27
|
-
const activeSpan = trace.getActiveSpan();
|
|
28
|
-
|
|
29
|
-
// If there's no active span, just call the original fetch
|
|
30
|
-
if (!activeSpan) {
|
|
31
|
-
return __originalFetch(input, init);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get the current active context
|
|
35
|
-
const currentContext = context.active();
|
|
36
|
-
const _url = new URL(url);
|
|
37
|
-
|
|
38
|
-
// Create a child span using the current context
|
|
39
|
-
const childSpan = trace.getTracer('fetch').startSpan(
|
|
40
|
-
`HTTP ${method}`,
|
|
41
|
-
{
|
|
42
|
-
attributes: {
|
|
43
|
-
'http.url': url,
|
|
44
|
-
'http.path': _url.pathname,
|
|
45
|
-
'http.method': method,
|
|
46
|
-
host: _url.host,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
currentContext
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
// Add trace context to headers
|
|
54
|
-
// Add trace context to headers; preserve headers from Request input
|
|
55
|
-
const baseHeaders =
|
|
56
|
-
typeof input !== 'string' && !(input instanceof URL) && input instanceof Request
|
|
57
|
-
? input.headers
|
|
58
|
-
: undefined;
|
|
59
|
-
const headers = new Headers(baseHeaders ?? init?.headers ?? {});
|
|
60
|
-
const carrier: Record<string, string> = {};
|
|
61
|
-
|
|
62
|
-
// Create a new context with the child span
|
|
63
|
-
const newContext = trace.setSpan(currentContext, childSpan);
|
|
64
|
-
|
|
65
|
-
// Use the new context for propagation
|
|
66
|
-
propagation.inject(newContext, carrier);
|
|
67
|
-
|
|
68
|
-
// Copy the carrier properties to headers
|
|
69
|
-
for (const [key, value] of Object.entries(carrier)) {
|
|
70
|
-
headers.set(key, value);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Create new init object with updated headers
|
|
74
|
-
const newInit = {
|
|
75
|
-
...init,
|
|
76
|
-
headers,
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const response = await __originalFetch(input, newInit);
|
|
80
|
-
|
|
81
|
-
// Add response attributes to span
|
|
82
|
-
childSpan.setAttributes({
|
|
83
|
-
'http.status_code': response.status,
|
|
84
|
-
'http.user_agent': response.headers.get('user-agent') || '',
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
if (!response.ok) {
|
|
88
|
-
childSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
89
|
-
} else {
|
|
90
|
-
childSpan.setStatus({ code: SpanStatusCode.OK });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return response;
|
|
94
|
-
} catch (error) {
|
|
95
|
-
childSpan.recordException(error as Error);
|
|
96
|
-
childSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
97
|
-
throw error;
|
|
98
|
-
} finally {
|
|
99
|
-
childSpan.end();
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
globalThis.fetch = patch as typeof fetch;
|
|
103
|
-
}
|
package/src/otel/http.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { context, propagation } from '@opentelemetry/api';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Injects trace context into response headers using the OpenTelemetry propagation API
|
|
5
|
-
*
|
|
6
|
-
* @param headers - Optional existing headers to include
|
|
7
|
-
* @returns A record of headers with trace context injected
|
|
8
|
-
*/
|
|
9
|
-
export function injectTraceContextToHeaders(
|
|
10
|
-
headers: Record<string, string> | Headers = {}
|
|
11
|
-
): Record<string, string> {
|
|
12
|
-
let _headers: Record<string, string>;
|
|
13
|
-
if (headers instanceof Headers) {
|
|
14
|
-
_headers = {};
|
|
15
|
-
headers.forEach((v, k) => (_headers[k] = v));
|
|
16
|
-
} else {
|
|
17
|
-
_headers = { ...headers };
|
|
18
|
-
}
|
|
19
|
-
// Create a carrier object for the headers
|
|
20
|
-
const carrier: Record<string, string> = { ..._headers } as Record<string, string>;
|
|
21
|
-
|
|
22
|
-
// Get the current context
|
|
23
|
-
const currentContext = context.active();
|
|
24
|
-
|
|
25
|
-
// Inject trace context into the carrier
|
|
26
|
-
propagation.inject(currentContext, carrier);
|
|
27
|
-
|
|
28
|
-
return carrier;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Extracts trace context from Bun Request headers
|
|
33
|
-
*
|
|
34
|
-
* @param req - The Bun Request object
|
|
35
|
-
* @returns The context with trace information
|
|
36
|
-
*/
|
|
37
|
-
export function extractTraceContextFromRequest(
|
|
38
|
-
req: Request
|
|
39
|
-
): ReturnType<typeof propagation.extract> {
|
|
40
|
-
// Create a carrier object from the headers
|
|
41
|
-
const carrier: Record<string, string> = {};
|
|
42
|
-
|
|
43
|
-
// Convert headers to the format expected by the propagator
|
|
44
|
-
req.headers.forEach((value, key) => {
|
|
45
|
-
carrier[key.toLowerCase()] = value;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Extract the context using the global propagator
|
|
49
|
-
const activeContext = context.active();
|
|
50
|
-
return propagation.extract(activeContext, carrier);
|
|
51
|
-
}
|