@agentuity/runtime 0.0.51 → 0.0.52

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.
Files changed (104) hide show
  1. package/dist/_config.js +99 -0
  2. package/dist/_config.js.map +1 -0
  3. package/dist/_context.js +82 -0
  4. package/dist/_context.js.map +1 -0
  5. package/dist/_idle.js +24 -0
  6. package/dist/_idle.js.map +1 -0
  7. package/dist/_server.js +489 -0
  8. package/dist/_server.js.map +1 -0
  9. package/dist/_services.js +258 -0
  10. package/dist/_services.js.map +1 -0
  11. package/dist/_tokens.js +98 -0
  12. package/dist/_tokens.js.map +1 -0
  13. package/dist/_util.js +54 -0
  14. package/dist/_util.js.map +1 -0
  15. package/dist/_waituntil.js +87 -0
  16. package/dist/_waituntil.js.map +1 -0
  17. package/dist/agent.js +507 -0
  18. package/dist/agent.js.map +1 -0
  19. package/dist/app.d.ts +6 -1
  20. package/dist/app.d.ts.map +1 -1
  21. package/dist/app.js +72 -0
  22. package/dist/app.js.map +1 -0
  23. package/dist/eval.js +2 -0
  24. package/dist/eval.js.map +1 -0
  25. package/dist/index.js +11 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/io/email.js +154 -0
  28. package/dist/io/email.js.map +1 -0
  29. package/dist/logger/console.js +274 -0
  30. package/dist/logger/console.js.map +1 -0
  31. package/dist/logger/index.js +3 -0
  32. package/dist/logger/index.js.map +1 -0
  33. package/dist/logger/internal.js +133 -0
  34. package/dist/logger/internal.js.map +1 -0
  35. package/dist/logger/logger.js +2 -0
  36. package/dist/logger/logger.js.map +1 -0
  37. package/dist/logger/user.js +7 -0
  38. package/dist/logger/user.js.map +1 -0
  39. package/dist/logger/util.js +77 -0
  40. package/dist/logger/util.js.map +1 -0
  41. package/dist/otel/config.js +23 -0
  42. package/dist/otel/config.js.map +1 -0
  43. package/dist/otel/console.js +52 -0
  44. package/dist/otel/console.js.map +1 -0
  45. package/dist/otel/exporters/index.js +4 -0
  46. package/dist/otel/exporters/index.js.map +1 -0
  47. package/dist/otel/exporters/jsonl-log-exporter.js +103 -0
  48. package/dist/otel/exporters/jsonl-log-exporter.js.map +1 -0
  49. package/dist/otel/exporters/jsonl-metric-exporter.js +104 -0
  50. package/dist/otel/exporters/jsonl-metric-exporter.js.map +1 -0
  51. package/dist/otel/exporters/jsonl-trace-exporter.js +111 -0
  52. package/dist/otel/exporters/jsonl-trace-exporter.js.map +1 -0
  53. package/dist/otel/fetch.js +81 -0
  54. package/dist/otel/fetch.js.map +1 -0
  55. package/dist/otel/http.js +44 -0
  56. package/dist/otel/http.js.map +1 -0
  57. package/dist/otel/logger.js +278 -0
  58. package/dist/otel/logger.js.map +1 -0
  59. package/dist/otel/otel.js +233 -0
  60. package/dist/otel/otel.js.map +1 -0
  61. package/dist/router.js +350 -0
  62. package/dist/router.js.map +1 -0
  63. package/dist/services/evalrun/composite.js +26 -0
  64. package/dist/services/evalrun/composite.js.map +1 -0
  65. package/dist/services/evalrun/http.js +74 -0
  66. package/dist/services/evalrun/http.js.map +1 -0
  67. package/dist/services/evalrun/index.js +5 -0
  68. package/dist/services/evalrun/index.js.map +1 -0
  69. package/dist/services/evalrun/json.js +38 -0
  70. package/dist/services/evalrun/json.js.map +1 -0
  71. package/dist/services/evalrun/local.js +22 -0
  72. package/dist/services/evalrun/local.js.map +1 -0
  73. package/dist/services/local/_db.js +144 -0
  74. package/dist/services/local/_db.js.map +1 -0
  75. package/dist/services/local/_router.js +60 -0
  76. package/dist/services/local/_router.js.map +1 -0
  77. package/dist/services/local/_util.js +42 -0
  78. package/dist/services/local/_util.js.map +1 -0
  79. package/dist/services/local/index.js +8 -0
  80. package/dist/services/local/index.js.map +1 -0
  81. package/dist/services/local/keyvalue.js +114 -0
  82. package/dist/services/local/keyvalue.js.map +1 -0
  83. package/dist/services/local/objectstore.js +117 -0
  84. package/dist/services/local/objectstore.js.map +1 -0
  85. package/dist/services/local/stream.js +218 -0
  86. package/dist/services/local/stream.js.map +1 -0
  87. package/dist/services/local/vector.js +183 -0
  88. package/dist/services/local/vector.js.map +1 -0
  89. package/dist/services/session/composite.js +26 -0
  90. package/dist/services/session/composite.js.map +1 -0
  91. package/dist/services/session/http.js +42 -0
  92. package/dist/services/session/http.js.map +1 -0
  93. package/dist/services/session/index.js +5 -0
  94. package/dist/services/session/index.js.map +1 -0
  95. package/dist/services/session/json.js +35 -0
  96. package/dist/services/session/json.js.map +1 -0
  97. package/dist/services/session/local.js +22 -0
  98. package/dist/services/session/local.js.map +1 -0
  99. package/dist/session.js +199 -0
  100. package/dist/session.js.map +1 -0
  101. package/dist/workbench.js +38 -0
  102. package/dist/workbench.js.map +1 -0
  103. package/package.json +5 -5
  104. package/src/app.ts +6 -1
@@ -0,0 +1,77 @@
1
+ import { formatWithOptions, inspect } from 'node:util';
2
+ import { safeStringify } from '@agentuity/core';
3
+ export function buildContextString(context) {
4
+ if (context) {
5
+ const contextStr = context && Object.keys(context).length > 0
6
+ ? Object.entries(context)
7
+ .map(([key, value]) => {
8
+ try {
9
+ return `${key}=${typeof value === 'object' ? safeStringify(value) : value}`;
10
+ }
11
+ catch {
12
+ return `${key}=[object Object]`;
13
+ }
14
+ })
15
+ .join(' ')
16
+ : '';
17
+ return contextStr;
18
+ }
19
+ return '';
20
+ }
21
+ /**
22
+ * Formats a log message with context
23
+ *
24
+ * @param message - The message to format
25
+ * @param args - Additional arguments for formatting
26
+ * @returns The formatted message with context
27
+ * @private
28
+ */
29
+ export function formatMessage(displayContext, context, message, args) {
30
+ // Format the context string
31
+ const contextStr = displayContext ? buildContextString(context) : null;
32
+ // Format the message based on its type
33
+ let _message;
34
+ if (typeof message === 'string') {
35
+ _message = message;
36
+ }
37
+ else if (typeof message === 'number' || typeof message === 'boolean') {
38
+ _message = String(message);
39
+ }
40
+ else if (message === null) {
41
+ _message = 'null';
42
+ }
43
+ else if (message === undefined) {
44
+ _message = 'undefined';
45
+ }
46
+ else {
47
+ // Use inspect for objects for better formatting
48
+ _message = inspect(message, { depth: null, colors: false });
49
+ }
50
+ // Format the message with args
51
+ let formattedMessage;
52
+ try {
53
+ // Only use format if we have arguments
54
+ if (args.length > 0) {
55
+ formattedMessage = formatWithOptions({ depth: null }, _message, ...args);
56
+ }
57
+ else {
58
+ formattedMessage = _message;
59
+ }
60
+ }
61
+ catch {
62
+ // If formatting fails, use a simple concatenation
63
+ formattedMessage = `${_message} ${args
64
+ .map((arg) => {
65
+ try {
66
+ return typeof arg === 'object' ? safeStringify(arg) : String(arg);
67
+ }
68
+ catch {
69
+ return '[object Object]';
70
+ }
71
+ })
72
+ .join(' ')}`;
73
+ }
74
+ // Combine message with context
75
+ return `${formattedMessage}${contextStr ? ` [${contextStr}]` : ''}`;
76
+ }
77
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/logger/util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import * as runtimeConfig from '../_config';
2
+ import { registerOtel } from './otel';
3
+ export function register(registerConfig) {
4
+ const url = process.env.AGENTUITY_OTLP_URL ?? 'https://otel.agentuity.cloud';
5
+ const bearerToken = process.env.AGENTUITY_OTLP_BEARER_TOKEN;
6
+ const config = {
7
+ spanProcessors: registerConfig.processors,
8
+ name: runtimeConfig.getAppName(),
9
+ version: runtimeConfig.getAppVersion(),
10
+ cliVersion: runtimeConfig.getCLIVersion(),
11
+ devmode: runtimeConfig.isDevMode(),
12
+ orgId: runtimeConfig.getOrganizationId(),
13
+ projectId: runtimeConfig.getProjectId(),
14
+ deploymentId: runtimeConfig.getDeploymentId(),
15
+ environment: runtimeConfig.getEnvironment(),
16
+ logLevel: registerConfig.logLevel,
17
+ jsonlBasePath: process.env.AGENTUITY_CLOUD_EXPORT_DIR,
18
+ bearerToken,
19
+ url,
20
+ };
21
+ return registerOtel(config);
22
+ }
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/otel/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAmBtC,MAAM,UAAU,QAAQ,CAAC,cAAkC;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,8BAA8B,CAAC;IAC7E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IAC5D,MAAM,MAAM,GAAe;QAC1B,cAAc,EAAE,cAAc,CAAC,UAAU;QACzC,IAAI,EAAE,aAAa,CAAC,UAAU,EAAE;QAChC,OAAO,EAAE,aAAa,CAAC,aAAa,EAAE;QACtC,UAAU,EAAE,aAAa,CAAC,aAAa,EAAE;QACzC,OAAO,EAAE,aAAa,CAAC,SAAS,EAAE;QAClC,KAAK,EAAE,aAAa,CAAC,iBAAiB,EAAE;QACxC,SAAS,EAAE,aAAa,CAAC,YAAY,EAAE;QACvC,YAAY,EAAE,aAAa,CAAC,eAAe,EAAE;QAC7C,WAAW,EAAE,aAAa,CAAC,cAAc,EAAE;QAC3C,QAAQ,EAAE,cAAc,CAAC,QAAQ;QACjC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;QACrD,WAAW;QACX,GAAG;KACH,CAAC;IAEF,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { SeverityNumber } from '@opentelemetry/api-logs';
2
+ import { ExportResultCode } from '@opentelemetry/core';
3
+ import { createLogger } from '@agentuity/server';
4
+ /**
5
+ * Console implementation of the LogRecordExporter interface
6
+ */
7
+ export class ConsoleLogRecordExporter {
8
+ logger;
9
+ /**
10
+ * Creates a new console log record exporter
11
+ */
12
+ constructor(logLevel) {
13
+ this.logger = createLogger(logLevel, false, process.env.COLOR_SCHEME ?? 'dark');
14
+ }
15
+ /**
16
+ * Exports log records to the console
17
+ *
18
+ * @param logs - The log records to export
19
+ * @param resultCallback - Callback function to report the export result
20
+ */
21
+ export(logs, resultCallback) {
22
+ for (const log of logs) {
23
+ switch (log.severityNumber) {
24
+ case SeverityNumber.DEBUG:
25
+ this.logger.debug(log.body);
26
+ break;
27
+ case SeverityNumber.INFO:
28
+ this.logger.info(log.body);
29
+ break;
30
+ case SeverityNumber.WARN:
31
+ this.logger.warn(log.body);
32
+ break;
33
+ case SeverityNumber.ERROR:
34
+ this.logger.error(log.body);
35
+ break;
36
+ default:
37
+ this.logger.info(log.body);
38
+ break;
39
+ }
40
+ }
41
+ resultCallback({ code: ExportResultCode.SUCCESS });
42
+ }
43
+ /**
44
+ * Shuts down the exporter
45
+ *
46
+ * @returns A promise that resolves when shutdown is complete
47
+ */
48
+ shutdown() {
49
+ return Promise.resolve();
50
+ }
51
+ }
52
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/otel/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAqB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAoB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGnE;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACnB,MAAM,CAAS;IAEhC;;OAEG;IACH,YAAY,QAAkB;QAC7B,IAAI,CAAC,MAAM,GAAG,YAAY,CACzB,QAAQ,EACR,KAAK,EACJ,OAAO,CAAC,GAAG,CAAC,YAA4B,IAAI,MAAM,CACnD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,IAAyB,EAAE,cAA8C;QAC/E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,QAAQ,GAAG,CAAC,cAAc,EAAE,CAAC;gBAC5B,KAAK,cAAc,CAAC,KAAK;oBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC5B,MAAM;gBACP,KAAK,cAAc,CAAC,IAAI;oBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM;gBACP,KAAK,cAAc,CAAC,IAAI;oBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM;gBACP,KAAK,cAAc,CAAC,KAAK;oBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC5B,MAAM;gBACP;oBACC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM;YACR,CAAC;QACF,CAAC;QACD,cAAc,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACP,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;CACD"}
@@ -0,0 +1,4 @@
1
+ export { JSONLLogExporter } from './jsonl-log-exporter';
2
+ export { JSONLTraceExporter } from './jsonl-trace-exporter';
3
+ export { JSONLMetricExporter } from './jsonl-metric-exporter';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/otel/exporters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import { existsSync, appendFileSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ /**
6
+ * JSONL implementation of the LogRecordExporter interface
7
+ * Writes logs to a timestamped JSONL file
8
+ */
9
+ export class JSONLLogExporter {
10
+ currentFile = null;
11
+ basePath;
12
+ filePrefix;
13
+ /**
14
+ * Creates a new JSONL log record exporter
15
+ * @param basePath - Directory to store the JSONL files
16
+ */
17
+ constructor(basePath) {
18
+ this.basePath = basePath;
19
+ this.filePrefix = 'otel-log';
20
+ this.ensureDirectory();
21
+ }
22
+ ensureDirectory() {
23
+ if (!existsSync(this.basePath)) {
24
+ mkdirSync(this.basePath, { recursive: true });
25
+ }
26
+ }
27
+ getOrCreateFile() {
28
+ // If current file exists, use it
29
+ if (this.currentFile && existsSync(this.currentFile)) {
30
+ return this.currentFile;
31
+ }
32
+ this.currentFile = join(this.basePath, `${this.filePrefix}-${Date.now()}.${randomUUID()}.jsonl`);
33
+ return this.currentFile;
34
+ }
35
+ /**
36
+ * Exports log records to a JSONL file
37
+ *
38
+ * @param logs - The log records to export
39
+ * @param resultCallback - Callback function to report the export result
40
+ */
41
+ export(logs, resultCallback) {
42
+ try {
43
+ if (logs.length === 0) {
44
+ resultCallback({ code: ExportResultCode.SUCCESS });
45
+ return;
46
+ }
47
+ const file = this.getOrCreateFile();
48
+ const lines = [];
49
+ for (const log of logs) {
50
+ const record = {
51
+ timestamp: log.hrTime,
52
+ observedTimestamp: log.hrTimeObserved,
53
+ severityNumber: log.severityNumber,
54
+ severityText: log.severityText,
55
+ body: log.body,
56
+ attributes: log.attributes,
57
+ resource: log.resource.attributes,
58
+ instrumentationScope: log.instrumentationScope,
59
+ spanContext: log.spanContext,
60
+ };
61
+ lines.push(JSON.stringify(record));
62
+ }
63
+ const payload = `${lines.join('\n')}\n`;
64
+ try {
65
+ appendFileSync(file, payload, 'utf-8');
66
+ }
67
+ catch (err) {
68
+ // File may have been deleted, reset and retry once
69
+ const code = err.code;
70
+ if (code === 'ENOENT') {
71
+ this.currentFile = null;
72
+ const newFile = this.getOrCreateFile();
73
+ appendFileSync(newFile, payload, 'utf-8');
74
+ }
75
+ else {
76
+ throw err;
77
+ }
78
+ }
79
+ resultCallback({ code: ExportResultCode.SUCCESS });
80
+ }
81
+ catch (error) {
82
+ resultCallback({
83
+ code: ExportResultCode.FAILED,
84
+ error: error instanceof Error ? error : new Error(String(error)),
85
+ });
86
+ }
87
+ }
88
+ /**
89
+ * Shuts down the exporter
90
+ *
91
+ * @returns A promise that resolves when shutdown is complete
92
+ */
93
+ async shutdown() {
94
+ this.currentFile = null;
95
+ }
96
+ /**
97
+ * Forces a flush of any pending data
98
+ */
99
+ async forceFlush() {
100
+ // No-op for file-based exporter as writes are synchronous
101
+ }
102
+ }
103
+ //# sourceMappingURL=jsonl-log-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-log-exporter.js","sourceRoot":"","sources":["../../../src/otel/exporters/jsonl-log-exporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import { AggregationTemporality, } from '@opentelemetry/sdk-metrics';
3
+ import { existsSync, appendFileSync, mkdirSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { randomUUID } from 'node:crypto';
6
+ /**
7
+ * JSONL implementation of the PushMetricExporter interface
8
+ * Writes metrics to a timestamped JSONL file
9
+ */
10
+ export class JSONLMetricExporter {
11
+ currentFile = null;
12
+ basePath;
13
+ filePrefix;
14
+ /**
15
+ * Creates a new JSONL metric exporter
16
+ * @param basePath - Directory to store the JSONL files
17
+ */
18
+ constructor(basePath) {
19
+ this.basePath = basePath;
20
+ this.filePrefix = 'otel-metric';
21
+ this.ensureDirectory();
22
+ }
23
+ ensureDirectory() {
24
+ if (!existsSync(this.basePath)) {
25
+ mkdirSync(this.basePath, { recursive: true });
26
+ }
27
+ }
28
+ getOrCreateFile() {
29
+ // If current file exists, use it
30
+ if (this.currentFile && existsSync(this.currentFile)) {
31
+ return this.currentFile;
32
+ }
33
+ this.currentFile = join(this.basePath, `${this.filePrefix}-${Date.now()}.${randomUUID()}.jsonl`);
34
+ return this.currentFile;
35
+ }
36
+ /**
37
+ * Exports metrics to a JSONL file
38
+ *
39
+ * @param metrics - The resource metrics to export
40
+ * @param resultCallback - Callback function to report the export result
41
+ */
42
+ export(metrics, resultCallback) {
43
+ try {
44
+ const file = this.getOrCreateFile();
45
+ const record = {
46
+ resource: metrics.resource.attributes,
47
+ scopeMetrics: metrics.scopeMetrics.map((sm) => ({
48
+ scope: sm.scope,
49
+ metrics: sm.metrics.map((m) => ({
50
+ descriptor: m.descriptor,
51
+ dataPointType: m.dataPointType,
52
+ dataPoints: m.dataPoints,
53
+ aggregationTemporality: m.aggregationTemporality,
54
+ })),
55
+ })),
56
+ };
57
+ const line = JSON.stringify(record) + '\n';
58
+ try {
59
+ appendFileSync(file, line, 'utf-8');
60
+ }
61
+ catch (err) {
62
+ // File may have been deleted, reset and retry once
63
+ const code = err.code;
64
+ if (code === 'ENOENT') {
65
+ this.currentFile = null;
66
+ const newFile = this.getOrCreateFile();
67
+ appendFileSync(newFile, line, 'utf-8');
68
+ }
69
+ else {
70
+ throw err;
71
+ }
72
+ }
73
+ resultCallback({ code: ExportResultCode.SUCCESS });
74
+ }
75
+ catch (error) {
76
+ resultCallback({
77
+ code: ExportResultCode.FAILED,
78
+ error: error instanceof Error ? error : new Error(String(error)),
79
+ });
80
+ }
81
+ }
82
+ /**
83
+ * Shuts down the exporter
84
+ *
85
+ * @returns A promise that resolves when shutdown is complete
86
+ */
87
+ async shutdown() {
88
+ this.currentFile = null;
89
+ }
90
+ /**
91
+ * Forces a flush of any pending data
92
+ */
93
+ async forceFlush() {
94
+ // No-op for file-based exporter as writes are synchronous
95
+ }
96
+ /**
97
+ * Selects the aggregation temporality for the given instrument type
98
+ */
99
+ selectAggregationTemporality(_instrumentType) {
100
+ // Default to cumulative temporality
101
+ return AggregationTemporality.CUMULATIVE;
102
+ }
103
+ }
104
+ //# sourceMappingURL=jsonl-metric-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-metric-exporter.js","sourceRoot":"","sources":["../../../src/otel/exporters/jsonl-metric-exporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import { existsSync, appendFileSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ /**
6
+ * JSONL implementation of the SpanExporter interface
7
+ * Writes traces to a timestamped JSONL file
8
+ */
9
+ export class JSONLTraceExporter {
10
+ currentFile = null;
11
+ basePath;
12
+ filePrefix;
13
+ /**
14
+ * Creates a new JSONL trace exporter
15
+ * @param basePath - Directory to store the JSONL files
16
+ */
17
+ constructor(basePath) {
18
+ this.basePath = basePath;
19
+ this.filePrefix = 'otel-trace';
20
+ this.ensureDirectory();
21
+ }
22
+ ensureDirectory() {
23
+ if (!existsSync(this.basePath)) {
24
+ mkdirSync(this.basePath, { recursive: true });
25
+ }
26
+ }
27
+ getOrCreateFile() {
28
+ // If current file exists, use it
29
+ if (this.currentFile && existsSync(this.currentFile)) {
30
+ return this.currentFile;
31
+ }
32
+ this.currentFile = join(this.basePath, `${this.filePrefix}-${Date.now()}.${randomUUID()}.jsonl`);
33
+ return this.currentFile;
34
+ }
35
+ /**
36
+ * Exports spans to a JSONL file
37
+ *
38
+ * @param spans - The spans to export
39
+ * @param resultCallback - Callback function to report the export result
40
+ */
41
+ export(spans, resultCallback) {
42
+ try {
43
+ if (spans.length === 0) {
44
+ resultCallback({ code: ExportResultCode.SUCCESS });
45
+ return;
46
+ }
47
+ const file = this.getOrCreateFile();
48
+ const lines = [];
49
+ for (const span of spans) {
50
+ const record = {
51
+ traceId: span.spanContext().traceId,
52
+ spanId: span.spanContext().spanId,
53
+ traceState: span.spanContext().traceState?.serialize(),
54
+ name: span.name,
55
+ kind: span.kind,
56
+ startTime: span.startTime,
57
+ endTime: span.endTime,
58
+ attributes: span.attributes,
59
+ status: span.status,
60
+ events: span.events,
61
+ links: span.links,
62
+ resource: span.resource.attributes,
63
+ droppedAttributesCount: span.droppedAttributesCount,
64
+ droppedEventsCount: span.droppedEventsCount,
65
+ droppedLinksCount: span.droppedLinksCount,
66
+ duration: span.duration,
67
+ ended: span.ended,
68
+ };
69
+ lines.push(JSON.stringify(record));
70
+ }
71
+ const payload = `${lines.join('\n')}\n`;
72
+ try {
73
+ appendFileSync(file, payload, 'utf-8');
74
+ }
75
+ catch (err) {
76
+ // File may have been deleted, reset and retry once
77
+ const code = err.code;
78
+ if (code === 'ENOENT') {
79
+ this.currentFile = null;
80
+ const newFile = this.getOrCreateFile();
81
+ appendFileSync(newFile, payload, 'utf-8');
82
+ }
83
+ else {
84
+ throw err;
85
+ }
86
+ }
87
+ resultCallback({ code: ExportResultCode.SUCCESS });
88
+ }
89
+ catch (error) {
90
+ resultCallback({
91
+ code: ExportResultCode.FAILED,
92
+ error: error instanceof Error ? error : new Error(String(error)),
93
+ });
94
+ }
95
+ }
96
+ /**
97
+ * Shuts down the exporter
98
+ *
99
+ * @returns A promise that resolves when shutdown is complete
100
+ */
101
+ async shutdown() {
102
+ this.currentFile = null;
103
+ }
104
+ /**
105
+ * Forces a flush of any pending data
106
+ */
107
+ async forceFlush() {
108
+ // No-op for file-based exporter as writes are synchronous
109
+ }
110
+ }
111
+ //# sourceMappingURL=jsonl-trace-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-trace-exporter.js","sourceRoot":"","sources":["../../../src/otel/exporters/jsonl-trace-exporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { context, propagation, SpanStatusCode, trace } from '@opentelemetry/api';
2
+ /**
3
+ * Reference to the original fetch function before instrumentation
4
+ */
5
+ export const __originalFetch = fetch; // save the original fetch before we patch it
6
+ /**
7
+ * Instruments the global fetch function with OpenTelemetry tracing
8
+ *
9
+ * Replaces the global fetch with an instrumented version that creates spans
10
+ * for each HTTP request and propagates trace context in headers
11
+ */
12
+ export function instrumentFetch() {
13
+ const patch = async (input, init) => {
14
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
15
+ const method = init?.method ||
16
+ (typeof input !== 'string' && !(input instanceof URL) ? input.method || 'GET' : 'GET');
17
+ // Get the active span if it exists
18
+ const activeSpan = trace.getActiveSpan();
19
+ // If there's no active span, just call the original fetch
20
+ if (!activeSpan) {
21
+ return __originalFetch(input, init);
22
+ }
23
+ // Get the current active context
24
+ const currentContext = context.active();
25
+ const _url = new URL(url);
26
+ // Create a child span using the current context
27
+ const childSpan = trace.getTracer('fetch').startSpan(`HTTP ${method}`, {
28
+ attributes: {
29
+ 'http.url': url,
30
+ 'http.path': _url.pathname,
31
+ 'http.method': method,
32
+ host: _url.host,
33
+ },
34
+ }, currentContext);
35
+ try {
36
+ // Add trace context to headers
37
+ // Add trace context to headers; preserve headers from Request input
38
+ const baseHeaders = typeof input !== 'string' && !(input instanceof URL) && input instanceof Request
39
+ ? input.headers
40
+ : undefined;
41
+ const headers = new Headers(baseHeaders ?? init?.headers ?? {});
42
+ const carrier = {};
43
+ // Create a new context with the child span
44
+ const newContext = trace.setSpan(currentContext, childSpan);
45
+ // Use the new context for propagation
46
+ propagation.inject(newContext, carrier);
47
+ // Copy the carrier properties to headers
48
+ for (const [key, value] of Object.entries(carrier)) {
49
+ headers.set(key, value);
50
+ }
51
+ // Create new init object with updated headers
52
+ const newInit = {
53
+ ...init,
54
+ headers,
55
+ };
56
+ const response = await __originalFetch(input, newInit);
57
+ // Add response attributes to span
58
+ childSpan.setAttributes({
59
+ 'http.status_code': response.status,
60
+ 'http.user_agent': response.headers.get('user-agent') || '',
61
+ });
62
+ if (!response.ok) {
63
+ childSpan.setStatus({ code: SpanStatusCode.ERROR });
64
+ }
65
+ else {
66
+ childSpan.setStatus({ code: SpanStatusCode.OK });
67
+ }
68
+ return response;
69
+ }
70
+ catch (error) {
71
+ childSpan.recordException(error);
72
+ childSpan.setStatus({ code: SpanStatusCode.ERROR });
73
+ throw error;
74
+ }
75
+ finally {
76
+ childSpan.end();
77
+ }
78
+ };
79
+ globalThis.fetch = patch;
80
+ }
81
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/otel/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { context, propagation } from '@opentelemetry/api';
2
+ /**
3
+ * Injects trace context into response headers using the OpenTelemetry propagation API
4
+ *
5
+ * @param headers - Optional existing headers to include
6
+ * @returns A record of headers with trace context injected
7
+ */
8
+ export function injectTraceContextToHeaders(headers = {}) {
9
+ let _headers;
10
+ if (headers instanceof Headers) {
11
+ _headers = {};
12
+ headers.forEach((v, k) => {
13
+ _headers[k] = v;
14
+ });
15
+ }
16
+ else {
17
+ _headers = { ...headers };
18
+ }
19
+ // Create a carrier object for the headers
20
+ const carrier = { ..._headers };
21
+ // Get the current context
22
+ const currentContext = context.active();
23
+ // Inject trace context into the carrier
24
+ propagation.inject(currentContext, carrier);
25
+ return carrier;
26
+ }
27
+ /**
28
+ * Extracts trace context from Bun Request headers
29
+ *
30
+ * @param req - The Bun Request object
31
+ * @returns The context with trace information
32
+ */
33
+ export function extractTraceContextFromRequest(req) {
34
+ // Create a carrier object from the headers
35
+ const carrier = {};
36
+ // Convert headers to the format expected by the propagator
37
+ req.headers.forEach((value, key) => {
38
+ carrier[key.toLowerCase()] = value;
39
+ });
40
+ // Extract the context using the global propagator
41
+ const activeContext = context.active();
42
+ return propagation.extract(activeContext, carrier);
43
+ }
44
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/otel/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAC1C,UAA4C,EAAE;IAE9C,IAAI,QAAgC,CAAC;IACrC,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;QAChC,QAAQ,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACxB,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACJ,CAAC;SAAM,CAAC;QACP,QAAQ,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,0CAA0C;IAC1C,MAAM,OAAO,GAA2B,EAAE,GAAG,QAAQ,EAA4B,CAAC;IAElF,0BAA0B;IAC1B,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAExC,wCAAwC;IACxC,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC7C,GAAY;IAEZ,2CAA2C;IAC3C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,2DAA2D;IAC3D,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACvC,OAAO,WAAW,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC"}