@autter/runtime-node 1.3.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -17
- package/dist/chunk-3TJHUCZ6.js +1680 -0
- package/dist/chunk-GI47WGRR.cjs +779 -0
- package/dist/chunk-L6SRL65J.cjs +202 -0
- package/dist/chunk-L7HWKMCZ.js +779 -0
- package/dist/chunk-P4VRTFAV.cjs +1680 -0
- package/dist/chunk-ZS4WQJQR.js +202 -0
- package/dist/cli.cjs +40 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +40 -0
- package/dist/index.cjs +1286 -747
- package/dist/index.d.cts +443 -27
- package/dist/index.d.ts +443 -27
- package/dist/index.js +1112 -543
- package/dist/sinks-RFV76lF1.d.cts +313 -0
- package/dist/sinks-RFV76lF1.d.ts +313 -0
- package/dist/testing.cjs +121 -0
- package/dist/testing.d.cts +57 -0
- package/dist/testing.d.ts +57 -0
- package/dist/testing.js +121 -0
- package/package.json +16 -5
|
@@ -0,0 +1,1680 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkGI47WGRRcjs = require('./chunk-GI47WGRR.cjs');
|
|
5
|
+
|
|
6
|
+
// ../runtime-core/dist/index.js
|
|
7
|
+
var SENSITIVE_KEY_PATTERNS = [
|
|
8
|
+
/e-?mail/,
|
|
9
|
+
/pass(word|wd|phrase)|^pass$|(^|[._-])pwd$/,
|
|
10
|
+
/token/,
|
|
11
|
+
/secret/,
|
|
12
|
+
/credential/,
|
|
13
|
+
/(api|access|secret|private|consumer|client|signing|encryption)-?[_.]?key/,
|
|
14
|
+
/authori[sz]ation|^auth(-|_|$)|bearer/,
|
|
15
|
+
/cookie/,
|
|
16
|
+
/(^|[._-])session$|^(j|php)?sess(ion)?id$|^sid$|connect\.sid/,
|
|
17
|
+
/phone|msisdn/,
|
|
18
|
+
/(^|[^a-z])ssn($|[^a-z])|social[-_ ]?security/,
|
|
19
|
+
/cvv|cvc|(^|[^a-z])card([-_. ]?(number|num|no))?$/,
|
|
20
|
+
/credit[-_.]?card/,
|
|
21
|
+
/connection[-_.]?string|(^|[._-])dsn$/,
|
|
22
|
+
/recovery[-_.]?code|\botp\b|magic[-_.]?link/
|
|
23
|
+
];
|
|
24
|
+
var PRIVATE_KEY_BLOCK_RE = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g;
|
|
25
|
+
var PREFIXED_SECRET_RE = /\b(?:sk-[A-Za-z0-9_-]{20,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{10,}|whsec_[A-Za-z0-9]{10,}|gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|xox[abposr]-[A-Za-z0-9-]{10,}|AIza[A-Za-z0-9_-]{30,}|(?:AKIA|ASIA)[0-9A-Z]{16}|npm_[A-Za-z0-9]{36}|autter_(?:rt|pat)_[A-Za-z0-9_-]{10,}|SG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,})/g;
|
|
26
|
+
var JWT_RE = /(?<![A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g;
|
|
27
|
+
var AUTH_SCHEME_RE = /\b(?:bearer\s+[A-Za-z0-9._~+/=-]{10,}|basic\s+(?=[A-Za-z0-9+/]*[0-9+/=])[A-Za-z0-9+/]{8,}={0,2})/gi;
|
|
28
|
+
var HEADER_VALUE_RE = /((?:^|[^\w-])(?:proxy-)?(?:authorization|(?:set-)?cookie)["']?\s*[:=]\s*["']?)[^"'\r\n]+/gim;
|
|
29
|
+
var SECRET_ASSIGNMENT_RE = /(password|passwd|pwd|passphrase|secret|token|api[_-]?key|apikey|access[_-]?key|private[_-]?key|credential|signature|session[_-]?id|sessionid|ssn)(["']?\s*[:=]\s*)("[^"\r\n]*"|'[^'\r\n]*'|[^\s"'&,;)}\]\[<>]+)/gi;
|
|
30
|
+
var URL_CREDENTIALS_RE = /\b([a-z][a-z0-9+.-]{0,31}:\/\/)(?:[^\s/:@"'<>]*:[^\s/"'<>]*|[^\s/:@"'<>]{16,})@/gi;
|
|
31
|
+
var CARD_RE = /\b(?:4\d{3}|5[1-5]\d{2}|2[2-7]\d{2}|3[47]\d{2}|6(?:011|5\d{2}))(?:[ -]?\d){9,15}\b/g;
|
|
32
|
+
var EMAIL_VALUE_RE = /[A-Z0-9._%+-]{1,64}@[A-Z0-9.-]{1,253}\.[A-Z]{2,63}/gi;
|
|
33
|
+
function luhnValid(candidate) {
|
|
34
|
+
const digits = candidate.replace(/\D/g, "");
|
|
35
|
+
if (digits.length < 13 || digits.length > 19) return false;
|
|
36
|
+
let sum = 0;
|
|
37
|
+
for (let i = 0; i < digits.length; i++) {
|
|
38
|
+
let d = digits.charCodeAt(digits.length - 1 - i) - 48;
|
|
39
|
+
if (i % 2 === 1) {
|
|
40
|
+
d *= 2;
|
|
41
|
+
if (d > 9) d -= 9;
|
|
42
|
+
}
|
|
43
|
+
sum += d;
|
|
44
|
+
}
|
|
45
|
+
return sum % 10 === 0;
|
|
46
|
+
}
|
|
47
|
+
function toCaseInsensitive(pattern) {
|
|
48
|
+
if (typeof pattern === "string")
|
|
49
|
+
return new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i");
|
|
50
|
+
const flags = pattern.flags.replace(/[gyi]/g, "");
|
|
51
|
+
return new RegExp(pattern.source, `${flags}i`);
|
|
52
|
+
}
|
|
53
|
+
function toGlobal(pattern) {
|
|
54
|
+
if (typeof pattern === "string") return new RegExp(pattern, "gi");
|
|
55
|
+
return new RegExp(pattern.source, `${pattern.flags.replace(/[gy]/g, "")}g`);
|
|
56
|
+
}
|
|
57
|
+
function compile(options) {
|
|
58
|
+
const keyPatterns = [...SENSITIVE_KEY_PATTERNS];
|
|
59
|
+
const extraValuePatterns = [];
|
|
60
|
+
for (const p of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.additionalKeyPatterns]), () => ( []))) {
|
|
61
|
+
keyPatterns.push(toCaseInsensitive(p));
|
|
62
|
+
}
|
|
63
|
+
for (const p of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.additionalValuePatterns]), () => ( []))) {
|
|
64
|
+
const re = toGlobal(p);
|
|
65
|
+
if (!extraValuePatterns.some((existing) => existing.source === re.source)) {
|
|
66
|
+
extraValuePatterns.push(re);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
keyPatterns,
|
|
71
|
+
extraValuePatterns,
|
|
72
|
+
mask: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.mask]), () => ( "[redacted]")),
|
|
73
|
+
scrubEmailValues: _optionalChain([options, 'optionalAccess', _4 => _4.scrubEmailValues]) !== false,
|
|
74
|
+
scrubCardNumbers: _optionalChain([options, 'optionalAccess', _5 => _5.scrubCardNumbers]) !== false
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
var MAX_SCRUB_CHARS = 64 * 1024;
|
|
78
|
+
function redactString(value, r) {
|
|
79
|
+
const mask = r.mask;
|
|
80
|
+
let out = value.length > MAX_SCRUB_CHARS ? value.slice(0, MAX_SCRUB_CHARS) : value;
|
|
81
|
+
out = out.replace(PRIVATE_KEY_BLOCK_RE, mask).replace(PREFIXED_SECRET_RE, mask).replace(JWT_RE, mask).replace(AUTH_SCHEME_RE, mask).replace(HEADER_VALUE_RE, (_m, head) => head + mask).replace(
|
|
82
|
+
SECRET_ASSIGNMENT_RE,
|
|
83
|
+
(_m, key, sep, val) => key + sep + (val[0] === '"' || val[0] === "'" ? val[0] + mask + val[0] : mask)
|
|
84
|
+
).replace(URL_CREDENTIALS_RE, (_m, scheme) => `${scheme}${mask}@`);
|
|
85
|
+
if (r.scrubCardNumbers) {
|
|
86
|
+
out = out.replace(CARD_RE, (m) => luhnValid(m) ? mask : m);
|
|
87
|
+
}
|
|
88
|
+
if (r.scrubEmailValues) {
|
|
89
|
+
out = out.replace(EMAIL_VALUE_RE, mask);
|
|
90
|
+
}
|
|
91
|
+
for (const re of r.extraValuePatterns) {
|
|
92
|
+
re.lastIndex = 0;
|
|
93
|
+
out = out.replace(re, mask);
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
var MAX_REDACTION_DEPTH = 64;
|
|
98
|
+
var MAX_REDACTION_WORK = 1e4;
|
|
99
|
+
var MAX_COLLECTION_ENTRIES = 1e3;
|
|
100
|
+
function canTraverse(depth, state) {
|
|
101
|
+
if (depth > MAX_REDACTION_DEPTH || state.remainingWork <= 0) return false;
|
|
102
|
+
state.remainingWork -= 1;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
function redactValue(value, r, state, depth) {
|
|
106
|
+
if (typeof value === "string") return redactString(value, r);
|
|
107
|
+
let isArray = false;
|
|
108
|
+
try {
|
|
109
|
+
isArray = Array.isArray(value);
|
|
110
|
+
} catch (e2) {
|
|
111
|
+
return r.mask;
|
|
112
|
+
}
|
|
113
|
+
if (isArray) {
|
|
114
|
+
return redactArray(value, r, state, depth);
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === "object" && value !== null) {
|
|
117
|
+
return redactObject(value, r, state, depth);
|
|
118
|
+
}
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
function redactArray(value, r, state, depth) {
|
|
122
|
+
const existing = state.ancestors.get(value);
|
|
123
|
+
if (existing) return r.mask;
|
|
124
|
+
if (!canTraverse(depth, state)) return r.mask;
|
|
125
|
+
const out = [];
|
|
126
|
+
state.ancestors.set(value, out);
|
|
127
|
+
let length;
|
|
128
|
+
try {
|
|
129
|
+
length = value.length;
|
|
130
|
+
} catch (e3) {
|
|
131
|
+
state.ancestors.delete(value);
|
|
132
|
+
return r.mask;
|
|
133
|
+
}
|
|
134
|
+
const limit = Math.min(length, MAX_COLLECTION_ENTRIES);
|
|
135
|
+
for (let i = 0; i < limit; i += 1) {
|
|
136
|
+
let item;
|
|
137
|
+
try {
|
|
138
|
+
item = value[i];
|
|
139
|
+
} catch (e4) {
|
|
140
|
+
out.push(r.mask);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
out.push(redactValue(item, r, state, depth + 1));
|
|
144
|
+
}
|
|
145
|
+
if (length > limit) {
|
|
146
|
+
out.push(r.mask);
|
|
147
|
+
}
|
|
148
|
+
state.ancestors.delete(value);
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
function redactObject(value, r, state, depth) {
|
|
152
|
+
const existing = state.ancestors.get(value);
|
|
153
|
+
if (existing) return r.mask;
|
|
154
|
+
if (!canTraverse(depth, state)) return r.mask;
|
|
155
|
+
const out = {};
|
|
156
|
+
state.ancestors.set(value, out);
|
|
157
|
+
let count = 0;
|
|
158
|
+
let truncated = false;
|
|
159
|
+
try {
|
|
160
|
+
for (const key in value) {
|
|
161
|
+
if (!Object.prototype.propertyIsEnumerable.call(
|
|
162
|
+
value,
|
|
163
|
+
key
|
|
164
|
+
)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (count >= MAX_COLLECTION_ENTRIES) {
|
|
168
|
+
truncated = true;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
let nestedValue;
|
|
172
|
+
try {
|
|
173
|
+
nestedValue = value[key];
|
|
174
|
+
} catch (e5) {
|
|
175
|
+
out[key] = r.mask;
|
|
176
|
+
count += 1;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
count += 1;
|
|
180
|
+
out[key] = isSensitiveKey(key, nestedValue, r) ? r.mask : redactValue(
|
|
181
|
+
nestedValue,
|
|
182
|
+
r,
|
|
183
|
+
state,
|
|
184
|
+
depth + 1
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
} catch (e6) {
|
|
188
|
+
truncated = true;
|
|
189
|
+
}
|
|
190
|
+
if (truncated) {
|
|
191
|
+
out.__redaction_truncated__ = r.mask;
|
|
192
|
+
}
|
|
193
|
+
state.ancestors.delete(value);
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
var USAGE_TOKEN_KEYS = /* @__PURE__ */ new Set([
|
|
197
|
+
"input_tokens",
|
|
198
|
+
"output_tokens",
|
|
199
|
+
"prompt_tokens",
|
|
200
|
+
"completion_tokens",
|
|
201
|
+
"total_tokens",
|
|
202
|
+
"token_count",
|
|
203
|
+
"cache_read_tokens",
|
|
204
|
+
"cache_creation_tokens",
|
|
205
|
+
"cache_read_input_tokens",
|
|
206
|
+
"cache_creation_input_tokens",
|
|
207
|
+
"cached_tokens",
|
|
208
|
+
"reasoning_tokens",
|
|
209
|
+
"gen_ai.usage.input_tokens",
|
|
210
|
+
"gen_ai.usage.output_tokens",
|
|
211
|
+
"gen_ai.usage.prompt_tokens",
|
|
212
|
+
"gen_ai.usage.completion_tokens",
|
|
213
|
+
"gen_ai.usage.total_tokens",
|
|
214
|
+
"gen_ai.usage.token_count"
|
|
215
|
+
]);
|
|
216
|
+
function isSensitiveKey(key, value, r) {
|
|
217
|
+
const lowered = key.toLowerCase();
|
|
218
|
+
if (USAGE_TOKEN_KEYS.has(lowered)) {
|
|
219
|
+
return !(typeof value === "number" && Number.isFinite(value) && value >= 0);
|
|
220
|
+
}
|
|
221
|
+
return r.keyPatterns.some((re) => re.test(lowered));
|
|
222
|
+
}
|
|
223
|
+
function redactAttributes(attributes, options) {
|
|
224
|
+
const r = compile(options);
|
|
225
|
+
return redactWith(attributes, r);
|
|
226
|
+
}
|
|
227
|
+
function redactWith(attributes, r) {
|
|
228
|
+
const out = {};
|
|
229
|
+
if (!attributes) return out;
|
|
230
|
+
const state = {
|
|
231
|
+
ancestors: /* @__PURE__ */ new WeakMap(),
|
|
232
|
+
remainingWork: MAX_REDACTION_WORK
|
|
233
|
+
};
|
|
234
|
+
let count = 0;
|
|
235
|
+
let truncated = false;
|
|
236
|
+
try {
|
|
237
|
+
for (const key in attributes) {
|
|
238
|
+
if (!Object.prototype.propertyIsEnumerable.call(
|
|
239
|
+
attributes,
|
|
240
|
+
key
|
|
241
|
+
)) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (count >= MAX_COLLECTION_ENTRIES || state.remainingWork <= 0) {
|
|
245
|
+
truncated = true;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
let value;
|
|
249
|
+
try {
|
|
250
|
+
value = attributes[key];
|
|
251
|
+
} catch (e7) {
|
|
252
|
+
out[key] = r.mask;
|
|
253
|
+
count += 1;
|
|
254
|
+
state.remainingWork -= 1;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
count += 1;
|
|
258
|
+
state.remainingWork -= 1;
|
|
259
|
+
if (value === void 0) continue;
|
|
260
|
+
out[key] = isSensitiveKey(key, value, r) ? r.mask : redactValue(value, r, state, 0);
|
|
261
|
+
}
|
|
262
|
+
} catch (e8) {
|
|
263
|
+
truncated = true;
|
|
264
|
+
}
|
|
265
|
+
if (truncated) {
|
|
266
|
+
out.__redaction_truncated__ = r.mask;
|
|
267
|
+
}
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
function redactText(text, options) {
|
|
271
|
+
return typeof text === "string" ? redactString(text, compile(options)) : text;
|
|
272
|
+
}
|
|
273
|
+
function makeRedactor(options) {
|
|
274
|
+
if (options === false) {
|
|
275
|
+
const passthrough = ((attributes) => ({
|
|
276
|
+
..._nullishCoalesce(attributes, () => ( {}))
|
|
277
|
+
}));
|
|
278
|
+
passthrough.text = (value) => value;
|
|
279
|
+
passthrough.exported = (attributes) => attributes;
|
|
280
|
+
passthrough.enabled = false;
|
|
281
|
+
return passthrough;
|
|
282
|
+
}
|
|
283
|
+
const r = compile(options === true ? void 0 : options);
|
|
284
|
+
const redactor = ((attributes) => redactWith(attributes, r));
|
|
285
|
+
redactor.text = (value) => typeof value === "string" ? redactString(value, r) : value;
|
|
286
|
+
redactor.exported = (attributes) => {
|
|
287
|
+
const out = {};
|
|
288
|
+
for (const key of Object.keys(attributes)) {
|
|
289
|
+
const value = attributes[key];
|
|
290
|
+
if (typeof value === "string") {
|
|
291
|
+
out[key] = r.keyPatterns.some((re) => re.test(key.toLowerCase())) ? r.mask : redactString(value, r);
|
|
292
|
+
} else if (Array.isArray(value)) {
|
|
293
|
+
const sensitive = r.keyPatterns.some((re) => re.test(key.toLowerCase()));
|
|
294
|
+
out[key] = value.map(
|
|
295
|
+
(item) => typeof item === "string" ? sensitive ? r.mask : redactString(item, r) : item
|
|
296
|
+
);
|
|
297
|
+
} else {
|
|
298
|
+
out[key] = value;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return out;
|
|
302
|
+
};
|
|
303
|
+
redactor.enabled = true;
|
|
304
|
+
return redactor;
|
|
305
|
+
}
|
|
306
|
+
var LEVEL_SEVERITY = {
|
|
307
|
+
debug: 5,
|
|
308
|
+
info: 9,
|
|
309
|
+
warning: 13,
|
|
310
|
+
error: 17
|
|
311
|
+
};
|
|
312
|
+
function stripUrlQueries(value) {
|
|
313
|
+
return value.replace(/https?:\/\/[^\s]*/gi, (url) => {
|
|
314
|
+
const rest = url.slice(url.indexOf("://") + 3);
|
|
315
|
+
const cut = rest.search(/[?#]/);
|
|
316
|
+
return cut <= 0 ? url : url.slice(0, url.length - rest.length + cut);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function maxLevel(a, b) {
|
|
320
|
+
return LEVEL_SEVERITY[b] > LEVEL_SEVERITY[a] ? b : a;
|
|
321
|
+
}
|
|
322
|
+
var RESERVED_KEY = /^autter\.(?:operation|event|request|error)\.|^autter\.(?:parent_trace_id|capture\.mode)$/;
|
|
323
|
+
function priority(key) {
|
|
324
|
+
if (key === "autter.operation.logs") return -1;
|
|
325
|
+
if (/^autter\.(?:operation|event|request)\.|^autter\.parent_trace_id$/.test(key))
|
|
326
|
+
return 2;
|
|
327
|
+
if (/^(?:exception|autter\.error)\./.test(key)) return 1;
|
|
328
|
+
return 0;
|
|
329
|
+
}
|
|
330
|
+
function boundContext(attributes = {}, redact2) {
|
|
331
|
+
const redacted = redact2 ? redact2(attributes) : redactAttributes(attributes);
|
|
332
|
+
let budget = 512;
|
|
333
|
+
let characters = 16384;
|
|
334
|
+
let truncated = false;
|
|
335
|
+
const visit = (input, depth) => {
|
|
336
|
+
if (--budget < 0 || depth > 6) {
|
|
337
|
+
truncated = true;
|
|
338
|
+
return "[truncated]";
|
|
339
|
+
}
|
|
340
|
+
if (typeof input === "string") {
|
|
341
|
+
const text = stripUrlQueries(input);
|
|
342
|
+
const kept = text.slice(0, Math.max(0, characters));
|
|
343
|
+
truncated ||= kept.length < text.length;
|
|
344
|
+
characters -= kept.length;
|
|
345
|
+
return kept;
|
|
346
|
+
}
|
|
347
|
+
if (typeof input === "number")
|
|
348
|
+
return Number.isFinite(input) ? input : void 0;
|
|
349
|
+
if (typeof input === "boolean" || input === null) return input;
|
|
350
|
+
if (Array.isArray(input)) {
|
|
351
|
+
truncated ||= input.length > 64;
|
|
352
|
+
return input.slice(0, 64).map((item) => visit(item, depth + 1));
|
|
353
|
+
}
|
|
354
|
+
if (input && typeof input === "object") {
|
|
355
|
+
const entries = Object.entries(input);
|
|
356
|
+
if (depth === 0) entries.sort(([a], [b]) => priority(b) - priority(a));
|
|
357
|
+
truncated ||= entries.length > 100;
|
|
358
|
+
return Object.fromEntries(
|
|
359
|
+
entries.slice(0, 100).filter(([key]) => !/^(?:__proto__|constructor|prototype)$/.test(key)).map(([key, item]) => [key.slice(0, 200), visit(item, depth + 1)])
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return void 0;
|
|
363
|
+
};
|
|
364
|
+
const result = visit(redacted, 0);
|
|
365
|
+
if (truncated) result["autter.context.truncated"] = true;
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
function userContext(attributes = {}, redact2) {
|
|
369
|
+
return Object.fromEntries(
|
|
370
|
+
Object.entries(boundContext(attributes, redact2)).filter(
|
|
371
|
+
([key]) => !RESERVED_KEY.test(key)
|
|
372
|
+
)
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
function mergeContext(current, next = {}, redact2) {
|
|
376
|
+
const merge2 = (left, right, depth) => {
|
|
377
|
+
const result = { ...left };
|
|
378
|
+
for (const [key, value] of Object.entries(right)) {
|
|
379
|
+
const prior = result[key];
|
|
380
|
+
result[key] = depth < 6 && value && typeof value === "object" && !Array.isArray(value) && prior && typeof prior === "object" && !Array.isArray(prior) ? merge2(prior, value, depth + 1) : value;
|
|
381
|
+
}
|
|
382
|
+
return result;
|
|
383
|
+
};
|
|
384
|
+
return userContext(merge2(current, userContext(next, redact2), 0), redact2);
|
|
385
|
+
}
|
|
386
|
+
function toSpanAttributes(context) {
|
|
387
|
+
return Object.fromEntries(
|
|
388
|
+
Object.entries(context).filter(([, item]) => item !== null && item !== void 0).map(([key, item]) => [
|
|
389
|
+
key,
|
|
390
|
+
typeof item === "object" ? JSON.stringify(item) : item
|
|
391
|
+
])
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
var CODE_PATTERN = /^[a-z][a-z0-9_]*(\.[a-z0-9_]+){0,3}$/;
|
|
395
|
+
var CODE_MAX_LENGTH = 80;
|
|
396
|
+
var WHY_MAX = 1e3;
|
|
397
|
+
var FIX_MAX = 1e3;
|
|
398
|
+
var LINK_MAX = 500;
|
|
399
|
+
var CAUSE_DEPTH = 5;
|
|
400
|
+
function isValidErrorCode(code) {
|
|
401
|
+
return typeof code === "string" && code.length <= CODE_MAX_LENGTH && CODE_PATTERN.test(code);
|
|
402
|
+
}
|
|
403
|
+
var warned = /* @__PURE__ */ new Set();
|
|
404
|
+
function warnInvalidCode(code) {
|
|
405
|
+
const key = String(code).slice(0, 120);
|
|
406
|
+
if (warned.has(key) || warned.size >= 50) return;
|
|
407
|
+
warned.add(key);
|
|
408
|
+
try {
|
|
409
|
+
console.warn(
|
|
410
|
+
`[autter-runtime] error code ${JSON.stringify(key)} does not match ${CODE_PATTERN} (max ${CODE_MAX_LENGTH} chars); it is dropped and the error groups by message`
|
|
411
|
+
);
|
|
412
|
+
} catch (e9) {
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
var RuntimeError = class extends Error {
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
constructor(options) {
|
|
423
|
+
const opts = typeof options === "string" ? { message: options } : options;
|
|
424
|
+
super(
|
|
425
|
+
opts.message,
|
|
426
|
+
opts.cause !== void 0 ? { cause: opts.cause } : void 0
|
|
427
|
+
);
|
|
428
|
+
this.name = "RuntimeError";
|
|
429
|
+
if (opts.code !== void 0) {
|
|
430
|
+
if (isValidErrorCode(opts.code)) this.code = opts.code;
|
|
431
|
+
else warnInvalidCode(opts.code);
|
|
432
|
+
}
|
|
433
|
+
if (typeof opts.why === "string") this.why = opts.why.slice(0, WHY_MAX);
|
|
434
|
+
if (typeof opts.fix === "string") this.fix = opts.fix.slice(0, FIX_MAX);
|
|
435
|
+
if (typeof opts.link === "string") this.link = opts.link.slice(0, LINK_MAX);
|
|
436
|
+
if (typeof opts.status === "number" && Number.isFinite(opts.status))
|
|
437
|
+
this.status = Math.trunc(opts.status);
|
|
438
|
+
if (typeof opts.expected === "boolean") this.expected = opts.expected;
|
|
439
|
+
if (opts.internal !== void 0)
|
|
440
|
+
Object.defineProperty(this, "internal", {
|
|
441
|
+
value: opts.internal,
|
|
442
|
+
enumerable: false,
|
|
443
|
+
writable: false,
|
|
444
|
+
configurable: true
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/** Client-safe JSON (what `toClientError` returns, minus the wrapper). */
|
|
448
|
+
toJSON() {
|
|
449
|
+
return toClientError(this).error;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
function defineRuntimeErrors(namespace, catalog) {
|
|
453
|
+
const out = {};
|
|
454
|
+
for (const [key, entry] of Object.entries(catalog)) {
|
|
455
|
+
const code = `${namespace}.${key}`;
|
|
456
|
+
const valid = isValidErrorCode(code);
|
|
457
|
+
if (!valid) warnInvalidCode(code);
|
|
458
|
+
const build = (definition, extras) => {
|
|
459
|
+
const error = new RuntimeError({
|
|
460
|
+
...definition,
|
|
461
|
+
..._optionalChain([extras, 'optionalAccess', _6 => _6.message]) !== void 0 ? { message: extras.message } : {},
|
|
462
|
+
...valid ? { code } : {},
|
|
463
|
+
..._optionalChain([extras, 'optionalAccess', _7 => _7.cause]) !== void 0 ? { cause: extras.cause } : {},
|
|
464
|
+
..._optionalChain([extras, 'optionalAccess', _8 => _8.internal]) !== void 0 ? { internal: extras.internal } : {}
|
|
465
|
+
});
|
|
466
|
+
const captureStackTrace = Error.captureStackTrace;
|
|
467
|
+
_optionalChain([captureStackTrace, 'optionalCall', _9 => _9(error, factory)]);
|
|
468
|
+
return error;
|
|
469
|
+
};
|
|
470
|
+
const factory = typeof entry === "function" ? (args, extras) => build(entry(args), extras) : (extras) => build(entry, extras);
|
|
471
|
+
Object.defineProperty(factory, "code", { value: code, enumerable: true });
|
|
472
|
+
out[key] = factory;
|
|
473
|
+
}
|
|
474
|
+
return out;
|
|
475
|
+
}
|
|
476
|
+
function isRuntimeErrorLike(err) {
|
|
477
|
+
if (err instanceof RuntimeError) return true;
|
|
478
|
+
if (!err || typeof err !== "object") return false;
|
|
479
|
+
const e = err;
|
|
480
|
+
return typeof e.code === "string" || typeof e.why === "string" || typeof e.fix === "string" || typeof e.link === "string" || typeof e.status === "number" || typeof e.statusCode === "number" || typeof e.expected === "boolean";
|
|
481
|
+
}
|
|
482
|
+
function field(err, key) {
|
|
483
|
+
if (!err || typeof err !== "object") return void 0;
|
|
484
|
+
try {
|
|
485
|
+
return err[key];
|
|
486
|
+
} catch (e10) {
|
|
487
|
+
return void 0;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function errorCodeOf(err) {
|
|
491
|
+
const code = field(err, "code");
|
|
492
|
+
return isValidErrorCode(code) ? code : void 0;
|
|
493
|
+
}
|
|
494
|
+
function errorStatusOf(err) {
|
|
495
|
+
for (const key of ["status", "statusCode"]) {
|
|
496
|
+
const status = field(err, key);
|
|
497
|
+
if (typeof status === "number" && Number.isInteger(status) && status >= 100 && status <= 599)
|
|
498
|
+
return status;
|
|
499
|
+
}
|
|
500
|
+
return void 0;
|
|
501
|
+
}
|
|
502
|
+
function isExpectedError(err) {
|
|
503
|
+
return field(err, "expected") === true;
|
|
504
|
+
}
|
|
505
|
+
function errorAttributes(err, options = {}) {
|
|
506
|
+
const out = {};
|
|
507
|
+
if (!err || typeof err !== "object") return out;
|
|
508
|
+
const code = errorCodeOf(err);
|
|
509
|
+
if (code) out["autter.error.code"] = code;
|
|
510
|
+
const why = field(err, "why");
|
|
511
|
+
if (typeof why === "string" && why) out["autter.error.why"] = why.slice(0, WHY_MAX);
|
|
512
|
+
const fix = field(err, "fix");
|
|
513
|
+
if (typeof fix === "string" && fix) out["autter.error.fix"] = fix.slice(0, FIX_MAX);
|
|
514
|
+
const link = field(err, "link");
|
|
515
|
+
if (typeof link === "string" && link) out["autter.error.link"] = link.slice(0, LINK_MAX);
|
|
516
|
+
const status = errorStatusOf(err);
|
|
517
|
+
if (status !== void 0 && isRuntimeErrorLike(err)) out["autter.error.status"] = status;
|
|
518
|
+
const expected = field(err, "expected");
|
|
519
|
+
if (typeof expected === "boolean") out["autter.error.expected"] = expected;
|
|
520
|
+
if (options.causes !== false) {
|
|
521
|
+
let cause = field(err, "cause");
|
|
522
|
+
const seen = /* @__PURE__ */ new Set([err]);
|
|
523
|
+
for (let n = 1; n <= CAUSE_DEPTH && cause !== void 0 && cause !== null; n++) {
|
|
524
|
+
if (seen.has(cause)) break;
|
|
525
|
+
seen.add(cause);
|
|
526
|
+
const isError = typeof cause === "object";
|
|
527
|
+
const type = isError ? String(_nullishCoalesce(_nullishCoalesce(field(cause, "name"), () => ( _optionalChain([cause, 'access', _10 => _10.constructor, 'optionalAccess', _11 => _11.name]))), () => ( "Error"))) : typeof cause;
|
|
528
|
+
const message = isError ? field(cause, "message") : cause;
|
|
529
|
+
out[`exception.cause.${n}.type`] = type.slice(0, 200);
|
|
530
|
+
out[`exception.cause.${n}.message`] = String(_nullishCoalesce(message, () => ( ""))).slice(0, 1e3);
|
|
531
|
+
const causeCode = field(cause, "code");
|
|
532
|
+
if (typeof causeCode === "string" && causeCode)
|
|
533
|
+
out[`exception.cause.${n}.code`] = causeCode.slice(0, CODE_MAX_LENGTH);
|
|
534
|
+
cause = isError ? field(cause, "cause") : void 0;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return out;
|
|
538
|
+
}
|
|
539
|
+
function errorInternal(err) {
|
|
540
|
+
const internal = field(err, "internal");
|
|
541
|
+
return internal && typeof internal === "object" && !Array.isArray(internal) ? internal : void 0;
|
|
542
|
+
}
|
|
543
|
+
var GENERIC_MESSAGE = "Internal Server Error";
|
|
544
|
+
function toClientError(err, requestId) {
|
|
545
|
+
const code = errorCodeOf(err);
|
|
546
|
+
const status = errorStatusOf(err);
|
|
547
|
+
const declared = err instanceof RuntimeError || code !== void 0 || status !== void 0 && status < 500 && isRuntimeErrorLike(err);
|
|
548
|
+
const rawMessage = field(err, "message");
|
|
549
|
+
const message = declared && typeof rawMessage === "string" && rawMessage ? rawMessage.slice(0, 1e3) : GENERIC_MESSAGE;
|
|
550
|
+
const body = { message };
|
|
551
|
+
if (code) body.code = code;
|
|
552
|
+
if (declared) {
|
|
553
|
+
const why = field(err, "why");
|
|
554
|
+
if (typeof why === "string" && why) body.why = why.slice(0, WHY_MAX);
|
|
555
|
+
const fix = field(err, "fix");
|
|
556
|
+
if (typeof fix === "string" && fix) body.fix = fix.slice(0, FIX_MAX);
|
|
557
|
+
const link = field(err, "link");
|
|
558
|
+
if (typeof link === "string" && link) body.link = link.slice(0, LINK_MAX);
|
|
559
|
+
}
|
|
560
|
+
if (typeof requestId === "string" && requestId) body.requestId = requestId;
|
|
561
|
+
return { error: body };
|
|
562
|
+
}
|
|
563
|
+
function responseStatusOf(err) {
|
|
564
|
+
const status = errorStatusOf(err);
|
|
565
|
+
return status !== void 0 && status >= 400 ? status : 500;
|
|
566
|
+
}
|
|
567
|
+
var INLINE_LOG_LIMIT = 50;
|
|
568
|
+
var INLINE_MESSAGE_MAX = 300;
|
|
569
|
+
var INLINE_CHARACTER_BUDGET = 6e3;
|
|
570
|
+
var AI_MODEL_LIMIT = 10;
|
|
571
|
+
function createInlineLogState(startedAt) {
|
|
572
|
+
return {
|
|
573
|
+
startedAt,
|
|
574
|
+
logs: [],
|
|
575
|
+
logsTruncated: false,
|
|
576
|
+
logCharacters: 0,
|
|
577
|
+
level: "info"
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
function appendInlineLog(state, level, message, attrs, redact2, now = Date.now()) {
|
|
581
|
+
state.level = maxLevel(state.level, level);
|
|
582
|
+
if (state.logs.length >= INLINE_LOG_LIMIT) {
|
|
583
|
+
state.logsTruncated = true;
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
const text = String(_nullishCoalesce(boundContext({ message }, redact2).message, () => ( ""))).slice(
|
|
587
|
+
0,
|
|
588
|
+
INLINE_MESSAGE_MAX
|
|
589
|
+
);
|
|
590
|
+
let small;
|
|
591
|
+
if (attrs && Object.keys(attrs).length) {
|
|
592
|
+
small = boundContext(attrs, redact2);
|
|
593
|
+
const encoded = JSON.stringify(small);
|
|
594
|
+
if (encoded.length > 1e3) small = { "autter.context.truncated": true };
|
|
595
|
+
}
|
|
596
|
+
const size = text.length + (small ? JSON.stringify(small).length : 0);
|
|
597
|
+
if (state.logCharacters + size > INLINE_CHARACTER_BUDGET) {
|
|
598
|
+
state.logsTruncated = true;
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
state.logCharacters += size;
|
|
602
|
+
state.logs.push({
|
|
603
|
+
t: Math.max(0, now - state.startedAt),
|
|
604
|
+
level,
|
|
605
|
+
message: text,
|
|
606
|
+
...small ? { attrs: small } : {}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
function addAiUsage(rollup, usage) {
|
|
610
|
+
const next = _nullishCoalesce(rollup, () => ( {
|
|
611
|
+
calls: 0,
|
|
612
|
+
input_tokens: 0,
|
|
613
|
+
output_tokens: 0,
|
|
614
|
+
cache_read_tokens: 0,
|
|
615
|
+
cost_usd: 0,
|
|
616
|
+
models: []
|
|
617
|
+
}));
|
|
618
|
+
const count = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
|
|
619
|
+
next.calls += 1;
|
|
620
|
+
next.input_tokens += count(usage.inputTokens);
|
|
621
|
+
next.output_tokens += count(usage.outputTokens);
|
|
622
|
+
next.cache_read_tokens += count(usage.cacheReadTokens);
|
|
623
|
+
if (typeof usage.costUsd === "number" && Number.isFinite(usage.costUsd) && usage.costUsd > 0)
|
|
624
|
+
next.cost_usd = Math.round((next.cost_usd + usage.costUsd) * 1e8) / 1e8;
|
|
625
|
+
if (usage.model && !next.models.includes(usage.model) && next.models.length < AI_MODEL_LIMIT)
|
|
626
|
+
next.models.push(String(usage.model).slice(0, 100));
|
|
627
|
+
return next;
|
|
628
|
+
}
|
|
629
|
+
var TRACE_ID = /^[a-f0-9]{32}$/;
|
|
630
|
+
var SPAN_ID = /^[a-f0-9]{16}$/;
|
|
631
|
+
function createRuntimeEvent(input) {
|
|
632
|
+
const valid = input.traceId !== void 0 && TRACE_ID.test(input.traceId) && !/^0+$/.test(input.traceId);
|
|
633
|
+
return {
|
|
634
|
+
time: _nullishCoalesce(input.time, () => ( Date.now())),
|
|
635
|
+
level: input.level,
|
|
636
|
+
message: input.message,
|
|
637
|
+
attributes: input.attributes,
|
|
638
|
+
...valid ? {
|
|
639
|
+
traceId: input.traceId,
|
|
640
|
+
...input.spanId && SPAN_ID.test(input.spanId) ? { spanId: input.spanId } : { spanId: _nullishCoalesce(input.spanId, () => ( "")) }
|
|
641
|
+
} : {}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
function isSummary(event) {
|
|
645
|
+
return event.attributes["autter.event.type"] === "operation";
|
|
646
|
+
}
|
|
647
|
+
var SEVERITY = { debug: 5, info: 9, warning: 13, error: 17 };
|
|
648
|
+
function otlpValue(input) {
|
|
649
|
+
if (typeof input === "number") return { doubleValue: input };
|
|
650
|
+
if (typeof input === "boolean") return { boolValue: input };
|
|
651
|
+
if (Array.isArray(input))
|
|
652
|
+
return { arrayValue: { values: input.slice(0, 64).map(otlpValue) } };
|
|
653
|
+
if (input && typeof input === "object")
|
|
654
|
+
return {
|
|
655
|
+
kvlistValue: {
|
|
656
|
+
values: Object.entries(input).slice(0, 128).map(([key, item]) => ({ key, value: otlpValue(item) }))
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
return { stringValue: String(_nullishCoalesce(input, () => ( ""))).slice(0, 32e3) };
|
|
660
|
+
}
|
|
661
|
+
function toOtlpLogRecord(event) {
|
|
662
|
+
return {
|
|
663
|
+
timeUnixNano: String(BigInt(Math.trunc(event.time)) * 1000000n),
|
|
664
|
+
severityNumber: SEVERITY[event.level],
|
|
665
|
+
severityText: event.level.toUpperCase(),
|
|
666
|
+
body: otlpValue(event.message),
|
|
667
|
+
attributes: Object.entries(event.attributes).map(([key, item]) => ({
|
|
668
|
+
key,
|
|
669
|
+
value: otlpValue(item)
|
|
670
|
+
})),
|
|
671
|
+
...event.traceId ? { traceId: event.traceId, spanId: _nullishCoalesce(event.spanId, () => ( "")) } : {}
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function buildOtlpLogsRequest(resource, records) {
|
|
675
|
+
return {
|
|
676
|
+
resourceLogs: [
|
|
677
|
+
{
|
|
678
|
+
resource: {
|
|
679
|
+
attributes: Object.entries({
|
|
680
|
+
"service.name": resource.service,
|
|
681
|
+
"deployment.environment.name": resource.environment,
|
|
682
|
+
...resource.release ? { "service.version": resource.release } : {},
|
|
683
|
+
...resource.distro ? {
|
|
684
|
+
"telemetry.distro.name": resource.distro.name,
|
|
685
|
+
"telemetry.distro.version": resource.distro.version
|
|
686
|
+
} : {}
|
|
687
|
+
}).map(([key, item]) => ({ key, value: otlpValue(item) }))
|
|
688
|
+
},
|
|
689
|
+
scopeLogs: [
|
|
690
|
+
{
|
|
691
|
+
scope: { name: "autter-runtime" },
|
|
692
|
+
logRecords: records
|
|
693
|
+
}
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
]
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
var REQUEST_ID_PATTERN = /^[\w.-]{8,128}$/;
|
|
700
|
+
var DEFAULT_REQUEST_ID_HEADER = "x-request-id";
|
|
701
|
+
function randomId() {
|
|
702
|
+
const c = globalThis.crypto;
|
|
703
|
+
if (_optionalChain([c, 'optionalAccess', _12 => _12.randomUUID])) return c.randomUUID();
|
|
704
|
+
return "10000000-1000-4000-8000-100000000000".replace(
|
|
705
|
+
/[018]/g,
|
|
706
|
+
(d) => (Number(d) ^ Math.random() * 16 >> Number(d) / 4).toString(16)
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
function resolveRequestId(header) {
|
|
710
|
+
const value = Array.isArray(header) ? header[0] : header;
|
|
711
|
+
return typeof value === "string" && REQUEST_ID_PATTERN.test(value.trim()) ? value.trim() : randomId();
|
|
712
|
+
}
|
|
713
|
+
function normalizeRoutePath(path) {
|
|
714
|
+
const pathname = (_nullishCoalesce(path.split(/[?#]/)[0], () => ( ""))) || "/";
|
|
715
|
+
return pathname.split("/").map((segment) => {
|
|
716
|
+
if (!segment) return segment;
|
|
717
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
718
|
+
segment
|
|
719
|
+
))
|
|
720
|
+
return ":id";
|
|
721
|
+
if (/^\d+$/.test(segment)) return ":id";
|
|
722
|
+
if (/^[0-9a-f]{8,}$/i.test(segment)) return ":id";
|
|
723
|
+
return segment;
|
|
724
|
+
}).join("/").slice(0, 200);
|
|
725
|
+
}
|
|
726
|
+
function compileIgnore(patterns = []) {
|
|
727
|
+
const regexes = patterns.map((pattern) => {
|
|
728
|
+
let source = "";
|
|
729
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
730
|
+
const char = pattern[i];
|
|
731
|
+
if (char === "*" && pattern[i + 1] === "*") {
|
|
732
|
+
source += ".*";
|
|
733
|
+
i++;
|
|
734
|
+
} else if (char === "*") source += "[^/]*";
|
|
735
|
+
else source += char.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
736
|
+
}
|
|
737
|
+
return new RegExp(`^${source}/?$`);
|
|
738
|
+
});
|
|
739
|
+
return (path) => {
|
|
740
|
+
const pathname = _nullishCoalesce(path.split(/[?#]/)[0], () => ( ""));
|
|
741
|
+
return regexes.some((re) => re.test(pathname));
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
function requestOutcome(input) {
|
|
745
|
+
if (input.explicit) return input.explicit;
|
|
746
|
+
if (input.error !== void 0 && isExpectedError(input.error)) return "degraded";
|
|
747
|
+
if (input.thrown || input.status !== void 0 && input.status >= 500)
|
|
748
|
+
return "failed";
|
|
749
|
+
if (input.aborted) return "cancelled";
|
|
750
|
+
return "succeeded";
|
|
751
|
+
}
|
|
752
|
+
var OPERATION_ID = /^[\w.-]{1,128}$/;
|
|
753
|
+
var TRACEPARENT = /^00-([a-f0-9]{32})-([a-f0-9]{16})-([a-f0-9]{2})$/;
|
|
754
|
+
function formatTraceparent(traceId, spanId, sampled) {
|
|
755
|
+
const value = `00-${traceId}-${spanId}-${sampled ? "01" : "00"}`;
|
|
756
|
+
return TRACEPARENT.test(value) && !/^0+$/.test(traceId) && !/^0+$/.test(spanId) ? value : void 0;
|
|
757
|
+
}
|
|
758
|
+
function parseTraceparent(value) {
|
|
759
|
+
if (typeof value !== "string") return null;
|
|
760
|
+
const match = TRACEPARENT.exec(value.trim());
|
|
761
|
+
if (!match || /^0+$/.test(match[1]) || /^0+$/.test(match[2])) return null;
|
|
762
|
+
return {
|
|
763
|
+
traceId: match[1],
|
|
764
|
+
spanId: match[2],
|
|
765
|
+
sampled: (Number.parseInt(match[3], 16) & 1) === 1
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function createCarrier(input) {
|
|
769
|
+
return {
|
|
770
|
+
v: 1,
|
|
771
|
+
op: input.op,
|
|
772
|
+
...input.req ? { req: input.req } : {},
|
|
773
|
+
...input.traceparent ? { traceparent: input.traceparent } : {}
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
function parseCarrier(input) {
|
|
777
|
+
let value = input;
|
|
778
|
+
if (typeof value === "string") {
|
|
779
|
+
if (value.length > 1024) return null;
|
|
780
|
+
try {
|
|
781
|
+
value = JSON.parse(value);
|
|
782
|
+
} catch (e11) {
|
|
783
|
+
return null;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (!value || typeof value !== "object") return null;
|
|
787
|
+
const raw = value;
|
|
788
|
+
if (raw.v !== 1 || typeof raw.op !== "string" || !OPERATION_ID.test(raw.op))
|
|
789
|
+
return null;
|
|
790
|
+
return createCarrier({
|
|
791
|
+
op: raw.op,
|
|
792
|
+
...typeof raw.req === "string" && REQUEST_ID_PATTERN.test(raw.req) ? { req: raw.req } : {},
|
|
793
|
+
...parseTraceparent(raw.traceparent) ? { traceparent: String(raw.traceparent).trim() } : {}
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
var BOT = /bot\b|crawler|spider|crawling|slurp|headless|lighthouse|curl\/|wget\/|python-requests|httpclient|okhttp|go-http-client|axios\/|node-fetch|undici/i;
|
|
797
|
+
function parseUserAgent(ua) {
|
|
798
|
+
const value = String(_nullishCoalesce(ua, () => ( ""))).slice(0, 512);
|
|
799
|
+
const os = /Windows/.test(value) ? "Windows" : /Android/.test(value) ? "Android" : /iPhone|iPad|iPod/.test(value) ? "iOS" : /Mac OS X/.test(value) ? "macOS" : /CrOS/.test(value) ? "ChromeOS" : /Linux/.test(value) ? "Linux" : "";
|
|
800
|
+
const edge = /Edg\/(\d+)/.exec(value);
|
|
801
|
+
const firefox = /Firefox\/(\d+)/.exec(value);
|
|
802
|
+
const chrome = /Chrome\/(\d+)/.exec(value);
|
|
803
|
+
const safari = /Version\/(\d+).+Safari/.exec(value);
|
|
804
|
+
const browser = edge ? `Edge ${edge[1]}` : firefox ? `Firefox ${firefox[1]}` : chrome ? `Chrome ${chrome[1]}` : safari ? `Safari ${safari[1]}` : "";
|
|
805
|
+
const bot = BOT.test(value);
|
|
806
|
+
const device = !value ? "unknown" : bot ? "bot" : /iPad|Tablet/.test(value) || /Android/.test(value) && !/Mobile/.test(value) ? "tablet" : /Mobi|iPhone|iPod|Android/.test(value) ? "mobile" : "desktop";
|
|
807
|
+
return { browser, os, device, bot };
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/sinks.ts
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
var _fs = require('fs');
|
|
818
|
+
var _path = require('path');
|
|
819
|
+
var sinkStats = { dropped: 0 };
|
|
820
|
+
function otlpSink(options = {}) {
|
|
821
|
+
let context = null;
|
|
822
|
+
let queue = [];
|
|
823
|
+
let queueBytes = 0;
|
|
824
|
+
let inFlightBytes = 0;
|
|
825
|
+
let inFlight = 0;
|
|
826
|
+
let timer;
|
|
827
|
+
let flushing = null;
|
|
828
|
+
let stopping = false;
|
|
829
|
+
let failureStreak = 0;
|
|
830
|
+
const scheduleFlush = () => {
|
|
831
|
+
if (!timer && context && !stopping && queue.length) {
|
|
832
|
+
timer = setTimeout(
|
|
833
|
+
() => {
|
|
834
|
+
timer = void 0;
|
|
835
|
+
void flush().catch(() => {
|
|
836
|
+
});
|
|
837
|
+
},
|
|
838
|
+
Math.min(3e4, 2e3 * 2 ** Math.min(failureStreak, 4))
|
|
839
|
+
);
|
|
840
|
+
timer.unref();
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const flush = async () => {
|
|
844
|
+
if (flushing) return flushing;
|
|
845
|
+
if (!context || !queue.length) return;
|
|
846
|
+
if (timer) {
|
|
847
|
+
clearTimeout(timer);
|
|
848
|
+
timer = void 0;
|
|
849
|
+
}
|
|
850
|
+
const active = context;
|
|
851
|
+
const endpoint = (_nullishCoalesce(options.endpoint, () => ( active.endpoint))).replace(/\/$/, "");
|
|
852
|
+
const apiKey = _nullishCoalesce(options.apiKey, () => ( active.apiKey));
|
|
853
|
+
const deadline = Date.now() + 1e4;
|
|
854
|
+
flushing = (async () => {
|
|
855
|
+
const count = queue.length;
|
|
856
|
+
for (let remaining = count; remaining > 0; ) {
|
|
857
|
+
const batch = [];
|
|
858
|
+
inFlightBytes = 0;
|
|
859
|
+
while (batch.length < Math.min(50, remaining) && queue.length) {
|
|
860
|
+
const next = queue[0];
|
|
861
|
+
if (batch.length && inFlightBytes + next.bytes > 512 * 1024) break;
|
|
862
|
+
batch.push(queue.shift());
|
|
863
|
+
inFlightBytes += next.bytes;
|
|
864
|
+
queueBytes -= next.bytes;
|
|
865
|
+
}
|
|
866
|
+
remaining -= batch.length;
|
|
867
|
+
inFlight = batch.length;
|
|
868
|
+
const body = JSON.stringify(
|
|
869
|
+
buildOtlpLogsRequest(
|
|
870
|
+
{
|
|
871
|
+
service: active.service,
|
|
872
|
+
environment: active.environment,
|
|
873
|
+
...active.release ? { release: active.release } : {},
|
|
874
|
+
...active.distro ? { distro: active.distro } : {}
|
|
875
|
+
},
|
|
876
|
+
batch.map((entry) => entry.record)
|
|
877
|
+
)
|
|
878
|
+
);
|
|
879
|
+
let failure;
|
|
880
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
881
|
+
try {
|
|
882
|
+
if (Date.now() >= deadline)
|
|
883
|
+
throw new Error("Runtime log flush exceeded 10 seconds");
|
|
884
|
+
const response = await fetch(`${endpoint}/v1/logs`, {
|
|
885
|
+
method: "POST",
|
|
886
|
+
headers: {
|
|
887
|
+
"content-type": "application/json",
|
|
888
|
+
authorization: `Bearer ${apiKey}`
|
|
889
|
+
},
|
|
890
|
+
body,
|
|
891
|
+
signal: AbortSignal.timeout(
|
|
892
|
+
Math.max(1, Math.min(3e3, deadline - Date.now()))
|
|
893
|
+
)
|
|
894
|
+
});
|
|
895
|
+
_chunkGI47WGRRcjs.observeIngesterResponse.call(void 0, { status: response.status, headers: response.headers, route: "/v1/logs" });
|
|
896
|
+
if (!response.ok)
|
|
897
|
+
throw new Error(`Runtime log export failed (${response.status})`);
|
|
898
|
+
failure = void 0;
|
|
899
|
+
break;
|
|
900
|
+
} catch (error) {
|
|
901
|
+
failure = error;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
inFlight = 0;
|
|
905
|
+
if (failure) {
|
|
906
|
+
failureStreak++;
|
|
907
|
+
queue = [...batch, ...queue];
|
|
908
|
+
queueBytes += inFlightBytes;
|
|
909
|
+
inFlightBytes = 0;
|
|
910
|
+
throw failure;
|
|
911
|
+
}
|
|
912
|
+
inFlightBytes = 0;
|
|
913
|
+
failureStreak = 0;
|
|
914
|
+
}
|
|
915
|
+
})().finally(() => {
|
|
916
|
+
flushing = null;
|
|
917
|
+
scheduleFlush();
|
|
918
|
+
});
|
|
919
|
+
return flushing;
|
|
920
|
+
};
|
|
921
|
+
return {
|
|
922
|
+
name: "otlp",
|
|
923
|
+
start(next) {
|
|
924
|
+
context = next;
|
|
925
|
+
stopping = false;
|
|
926
|
+
failureStreak = 0;
|
|
927
|
+
},
|
|
928
|
+
write(event) {
|
|
929
|
+
if (!context) return;
|
|
930
|
+
if (stopping) {
|
|
931
|
+
sinkStats.dropped++;
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
const record = toOtlpLogRecord(event);
|
|
935
|
+
const bytes = Buffer.byteLength(JSON.stringify(record));
|
|
936
|
+
if (bytes > 256 * 1024 || queue.length + inFlight >= 1e3 || queueBytes + inFlightBytes + bytes > 4 * 1024 * 1024) {
|
|
937
|
+
sinkStats.dropped++;
|
|
938
|
+
console.warn(
|
|
939
|
+
"[autter-runtime] log buffer or record limit reached; record dropped"
|
|
940
|
+
);
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
queue.push({ record, bytes });
|
|
944
|
+
queueBytes += bytes;
|
|
945
|
+
_chunkGI47WGRRcjs.noteCompatFeature.call(void 0, "operation_logging");
|
|
946
|
+
scheduleFlush();
|
|
947
|
+
},
|
|
948
|
+
flush,
|
|
949
|
+
async shutdown() {
|
|
950
|
+
stopping = true;
|
|
951
|
+
try {
|
|
952
|
+
await flush();
|
|
953
|
+
} finally {
|
|
954
|
+
if (queue.length) {
|
|
955
|
+
sinkStats.dropped += queue.length;
|
|
956
|
+
console.warn(
|
|
957
|
+
`[autter-runtime] ${queue.length} log records could not be delivered before shutdown`
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
queue = [];
|
|
961
|
+
queueBytes = 0;
|
|
962
|
+
context = null;
|
|
963
|
+
if (timer) clearTimeout(timer);
|
|
964
|
+
timer = void 0;
|
|
965
|
+
}
|
|
966
|
+
},
|
|
967
|
+
buffered: () => queue.length + inFlight
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
var ANSI = {
|
|
971
|
+
dim: "\x1B[2m",
|
|
972
|
+
red: "\x1B[31m",
|
|
973
|
+
yellow: "\x1B[33m",
|
|
974
|
+
green: "\x1B[32m",
|
|
975
|
+
cyan: "\x1B[36m",
|
|
976
|
+
bold: "\x1B[1m",
|
|
977
|
+
reset: "\x1B[0m"
|
|
978
|
+
};
|
|
979
|
+
function shortValue(value) {
|
|
980
|
+
if (typeof value === "string") return /\s/.test(value) ? JSON.stringify(value) : value;
|
|
981
|
+
if (value && typeof value === "object") {
|
|
982
|
+
const text = JSON.stringify(value);
|
|
983
|
+
return text.length > 120 ? `${text.slice(0, 117)}...` : text;
|
|
984
|
+
}
|
|
985
|
+
return String(value);
|
|
986
|
+
}
|
|
987
|
+
function flatPairs(attributes) {
|
|
988
|
+
const pairs = [];
|
|
989
|
+
const visit = (prefix, value, depth) => {
|
|
990
|
+
if (pairs.length >= 24) return;
|
|
991
|
+
if (value && typeof value === "object" && !Array.isArray(value) && depth < 3) {
|
|
992
|
+
for (const [key, item] of Object.entries(value))
|
|
993
|
+
visit(prefix ? `${prefix}.${key}` : key, item, depth + 1);
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
pairs.push(`${prefix}=${shortValue(value)}`);
|
|
997
|
+
};
|
|
998
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
999
|
+
if (/^(?:autter\.|exception\.|http\.(?:request\.method|route|response\.status_code)$)/.test(key))
|
|
1000
|
+
continue;
|
|
1001
|
+
visit(key, value, 0);
|
|
1002
|
+
}
|
|
1003
|
+
return pairs.join(" ");
|
|
1004
|
+
}
|
|
1005
|
+
function formatPretty(event, color = false) {
|
|
1006
|
+
const paint = (code2, text) => color ? `${ANSI[code2]}${text}${ANSI.reset}` : text;
|
|
1007
|
+
const a = event.attributes;
|
|
1008
|
+
const time = new Date(event.time).toISOString().slice(11, 23);
|
|
1009
|
+
const levelColor = event.level === "error" ? "red" : event.level === "warning" ? "yellow" : "dim";
|
|
1010
|
+
const level = paint(levelColor, event.level.toUpperCase().padEnd(7));
|
|
1011
|
+
if (!isSummary(event)) {
|
|
1012
|
+
const context2 = flatPairs(a);
|
|
1013
|
+
const op = typeof a["autter.operation.name"] === "string" ? paint("dim", ` [${a["autter.operation.name"]}]`) : "";
|
|
1014
|
+
return `${paint("dim", time)} ${level} ${event.message}${context2 ? ` ${paint("dim", context2)}` : ""}${op}`;
|
|
1015
|
+
}
|
|
1016
|
+
const outcome = String(_nullishCoalesce(a["autter.operation.outcome"], () => ( "")));
|
|
1017
|
+
const outcomeColor = outcome === "failed" ? "red" : outcome === "succeeded" ? "green" : "yellow";
|
|
1018
|
+
const status = a["http.response.status_code"];
|
|
1019
|
+
const head = [
|
|
1020
|
+
paint("dim", time),
|
|
1021
|
+
level,
|
|
1022
|
+
paint("bold", String(_nullishCoalesce(a["autter.operation.name"], () => ( event.message)))),
|
|
1023
|
+
paint(outcomeColor, outcome),
|
|
1024
|
+
...status !== void 0 ? [String(status)] : [],
|
|
1025
|
+
`${Math.round(Number(_nullishCoalesce(a["autter.operation.duration_ms"], () => ( 0))))}ms`,
|
|
1026
|
+
...a["autter.request.id"] ? [paint("dim", `req=${a["autter.request.id"]}`)] : []
|
|
1027
|
+
].join(" ");
|
|
1028
|
+
const lines = [head];
|
|
1029
|
+
const row = (label, text) => lines.push(` ${paint("cyan", label.padEnd(8))} ${text}`);
|
|
1030
|
+
if (outcome !== "succeeded" && event.message && !event.message.endsWith(`: ${outcome}`))
|
|
1031
|
+
row("message", event.message);
|
|
1032
|
+
const context = flatPairs(a);
|
|
1033
|
+
if (context) row("context", context);
|
|
1034
|
+
const steps = a["autter.operation.steps"];
|
|
1035
|
+
if (Array.isArray(steps) && steps.length)
|
|
1036
|
+
row(
|
|
1037
|
+
"steps",
|
|
1038
|
+
steps.map((step) => {
|
|
1039
|
+
const s = step;
|
|
1040
|
+
const mark = s.status === "failed" ? paint("red", "\u2717") : paint("green", "\u2713");
|
|
1041
|
+
return `${s.name} ${mark} ${s.durationMs}ms`;
|
|
1042
|
+
}).join(" \xB7 ")
|
|
1043
|
+
);
|
|
1044
|
+
const code = a["autter.error.code"];
|
|
1045
|
+
if (code || a["exception.type"])
|
|
1046
|
+
row(
|
|
1047
|
+
"error",
|
|
1048
|
+
[
|
|
1049
|
+
code ? paint("red", String(code)) : String(a["exception.type"]),
|
|
1050
|
+
a["autter.error.expected"] === true ? paint("dim", "(expected)") : "",
|
|
1051
|
+
a["autter.error.why"] ? `why: ${a["autter.error.why"]}` : "",
|
|
1052
|
+
a["autter.error.fix"] ? `fix: ${a["autter.error.fix"]}` : ""
|
|
1053
|
+
].filter(Boolean).join(" ")
|
|
1054
|
+
);
|
|
1055
|
+
const ai = a["autter.operation.ai"];
|
|
1056
|
+
if (ai && typeof ai === "object")
|
|
1057
|
+
row(
|
|
1058
|
+
"ai",
|
|
1059
|
+
`${ai.calls} call(s) \xB7 ${ai.input_tokens} in / ${ai.output_tokens} out \xB7 $${ai.cost_usd} \xB7 ${(_nullishCoalesce(ai.models, () => ( []))).join(", ")}`
|
|
1060
|
+
);
|
|
1061
|
+
const logs = a["autter.operation.logs"];
|
|
1062
|
+
if (Array.isArray(logs))
|
|
1063
|
+
for (const entry of logs) {
|
|
1064
|
+
const log = entry;
|
|
1065
|
+
const extra = log.attrs ? ` ${paint("dim", flatPairs(log.attrs))}` : "";
|
|
1066
|
+
row("log", `+${log.t}ms ${log.level} ${log.message}${extra}`);
|
|
1067
|
+
}
|
|
1068
|
+
if (a["autter.operation.logs_truncated"] === true) row("log", paint("dim", "\u2026 more messages truncated"));
|
|
1069
|
+
return lines.join("\n");
|
|
1070
|
+
}
|
|
1071
|
+
function consoleSink(options = {}) {
|
|
1072
|
+
const format = _nullishCoalesce(options.format, () => ( (process.env.NODE_ENV === "production" ? "json" : "pretty")));
|
|
1073
|
+
const color = _nullishCoalesce(options.color, () => ( (_optionalChain([process, 'access', _13 => _13.stdout, 'optionalAccess', _14 => _14.isTTY]) === true && !process.env.NO_COLOR)));
|
|
1074
|
+
const write = _nullishCoalesce(options.write, () => ( ((line) => console.log(line))));
|
|
1075
|
+
return {
|
|
1076
|
+
name: "console",
|
|
1077
|
+
write(event) {
|
|
1078
|
+
write(
|
|
1079
|
+
format === "json" ? JSON.stringify({
|
|
1080
|
+
...event.attributes,
|
|
1081
|
+
level: event.level,
|
|
1082
|
+
message: event.message
|
|
1083
|
+
}) : formatPretty(event, color)
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
var FILE_NAME = /^(\d{4}-\d{2}-\d{2})(?:\.(\d+))?\.jsonl$/;
|
|
1089
|
+
function fileSink(options = {}) {
|
|
1090
|
+
const dir = _path.resolve.call(void 0, _nullishCoalesce(options.dir, () => ( ".autter/runtime")));
|
|
1091
|
+
const maxFiles = Math.max(1, _nullishCoalesce(options.maxFiles, () => ( 7)));
|
|
1092
|
+
const maxBytes = Math.max(1024, _nullishCoalesce(options.maxBytes, () => ( 10 * 1024 * 1024)));
|
|
1093
|
+
let context = null;
|
|
1094
|
+
let disabled = false;
|
|
1095
|
+
let day = "";
|
|
1096
|
+
let index = 0;
|
|
1097
|
+
let currentBytes = 0;
|
|
1098
|
+
const files = () => _fs.readdirSync.call(void 0, dir).map((name) => ({ name, match: FILE_NAME.exec(name) })).filter((file) => file.match).map((file) => ({
|
|
1099
|
+
name: file.name,
|
|
1100
|
+
day: file.match[1],
|
|
1101
|
+
index: Number(_nullishCoalesce(file.match[2], () => ( 0)))
|
|
1102
|
+
})).sort((a, b) => a.day === b.day ? a.index - b.index : a.day < b.day ? -1 : 1);
|
|
1103
|
+
const fileName = (d, i) => i === 0 ? `${d}.jsonl` : `${d}.${i}.jsonl`;
|
|
1104
|
+
const prune = () => {
|
|
1105
|
+
const current = fileName(day, index);
|
|
1106
|
+
const existing = files().filter((file) => file.name !== current);
|
|
1107
|
+
const excess = existing.length + 1 - maxFiles;
|
|
1108
|
+
for (const file of existing.slice(0, Math.max(0, excess)))
|
|
1109
|
+
_fs.unlinkSync.call(void 0, _path.join.call(void 0, dir, file.name));
|
|
1110
|
+
};
|
|
1111
|
+
const open = (nextDay) => {
|
|
1112
|
+
_fs.mkdirSync.call(void 0, dir, { recursive: true });
|
|
1113
|
+
day = nextDay;
|
|
1114
|
+
const sameDay = files().filter((file) => file.day === day);
|
|
1115
|
+
index = sameDay.length ? sameDay[sameDay.length - 1].index : 0;
|
|
1116
|
+
try {
|
|
1117
|
+
currentBytes = _fs.statSync.call(void 0, _path.join.call(void 0, dir, fileName(day, index))).size;
|
|
1118
|
+
} catch (e12) {
|
|
1119
|
+
currentBytes = 0;
|
|
1120
|
+
}
|
|
1121
|
+
prune();
|
|
1122
|
+
};
|
|
1123
|
+
const disable = (error) => {
|
|
1124
|
+
disabled = true;
|
|
1125
|
+
const code = _nullishCoalesce(_optionalChain([error, 'optionalAccess', _15 => _15.code]), () => ( "error"));
|
|
1126
|
+
console.warn(
|
|
1127
|
+
`[autter-runtime] local runtime files disabled (${code} writing ${dir}); set logging.file: false to silence`
|
|
1128
|
+
);
|
|
1129
|
+
};
|
|
1130
|
+
return {
|
|
1131
|
+
name: "file",
|
|
1132
|
+
start(next) {
|
|
1133
|
+
context = next;
|
|
1134
|
+
},
|
|
1135
|
+
write(event) {
|
|
1136
|
+
if (disabled) return;
|
|
1137
|
+
try {
|
|
1138
|
+
const line = `${JSON.stringify({
|
|
1139
|
+
time: new Date(event.time).toISOString(),
|
|
1140
|
+
level: event.level,
|
|
1141
|
+
message: event.message,
|
|
1142
|
+
...context ? {
|
|
1143
|
+
service: context.service,
|
|
1144
|
+
environment: context.environment,
|
|
1145
|
+
...context.release ? { release: context.release } : {}
|
|
1146
|
+
} : {},
|
|
1147
|
+
...event.traceId ? { traceId: event.traceId, spanId: event.spanId } : {},
|
|
1148
|
+
...event.attributes
|
|
1149
|
+
})}
|
|
1150
|
+
`;
|
|
1151
|
+
const bytes = Buffer.byteLength(line);
|
|
1152
|
+
const today = new Date(event.time).toISOString().slice(0, 10);
|
|
1153
|
+
if (today !== day) open(today);
|
|
1154
|
+
if (currentBytes > 0 && currentBytes + bytes > maxBytes) {
|
|
1155
|
+
index++;
|
|
1156
|
+
currentBytes = 0;
|
|
1157
|
+
prune();
|
|
1158
|
+
}
|
|
1159
|
+
_fs.appendFileSync.call(void 0, _path.join.call(void 0, dir, fileName(day, index)), line);
|
|
1160
|
+
currentBytes += bytes;
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
disable(error);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
function memorySink() {
|
|
1168
|
+
const events = [];
|
|
1169
|
+
const exceptions = [];
|
|
1170
|
+
return {
|
|
1171
|
+
name: "memory",
|
|
1172
|
+
events,
|
|
1173
|
+
exceptions,
|
|
1174
|
+
write(event) {
|
|
1175
|
+
events.push(event);
|
|
1176
|
+
},
|
|
1177
|
+
exception(record) {
|
|
1178
|
+
exceptions.push(record);
|
|
1179
|
+
},
|
|
1180
|
+
clear() {
|
|
1181
|
+
events.length = 0;
|
|
1182
|
+
exceptions.length = 0;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// src/logger.ts
|
|
1188
|
+
var _async_hooks = require('async_hooks');
|
|
1189
|
+
var _crypto = require('crypto');
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
var _api = require('@opentelemetry/api');
|
|
1193
|
+
var local = new (0, _async_hooks.AsyncLocalStorage)();
|
|
1194
|
+
var config = null;
|
|
1195
|
+
var sinks = [];
|
|
1196
|
+
var extraSinks = /* @__PURE__ */ new Set();
|
|
1197
|
+
var fallbackConsole = null;
|
|
1198
|
+
function redact(attributes) {
|
|
1199
|
+
return _nullishCoalesce(_optionalChain([config, 'optionalAccess', _16 => _16.redact, 'call', _17 => _17(attributes)]), () => ( redactAttributes(attributes)));
|
|
1200
|
+
}
|
|
1201
|
+
var safe = (attributes = {}) => boundContext(attributes, redact);
|
|
1202
|
+
var merge = (current, next) => mergeContext(current, next, redact);
|
|
1203
|
+
function activeSinks() {
|
|
1204
|
+
if (config) return extraSinks.size ? [...sinks, ...extraSinks] : sinks;
|
|
1205
|
+
if (extraSinks.size) return [...extraSinks];
|
|
1206
|
+
fallbackConsole ??= consoleSink();
|
|
1207
|
+
return [fallbackConsole];
|
|
1208
|
+
}
|
|
1209
|
+
function defaultSinks(next) {
|
|
1210
|
+
const options = _nullishCoalesce(next.options, () => ( {}));
|
|
1211
|
+
if (options.sinks) return [...options.sinks];
|
|
1212
|
+
const file = options.file === void 0 ? process.env.NODE_ENV === "development" : options.file !== false;
|
|
1213
|
+
return [
|
|
1214
|
+
...next.apiKey ? [otlpSink()] : [],
|
|
1215
|
+
...options.console !== false ? [consoleSink()] : [],
|
|
1216
|
+
...file ? [fileSink(typeof options.file === "object" ? options.file : {})] : []
|
|
1217
|
+
];
|
|
1218
|
+
}
|
|
1219
|
+
function currentOperation() {
|
|
1220
|
+
const state = local.getStore();
|
|
1221
|
+
return state && !state.sealed ? state : void 0;
|
|
1222
|
+
}
|
|
1223
|
+
function operationAttributes(state) {
|
|
1224
|
+
return state ? {
|
|
1225
|
+
"autter.operation.id": state.id,
|
|
1226
|
+
"autter.operation.name": state.name,
|
|
1227
|
+
...state.parentId ? { "autter.operation.parent_id": state.parentId } : {},
|
|
1228
|
+
...state.requestId ? { "autter.request.id": state.requestId } : {},
|
|
1229
|
+
...state.parentTraceId ? { "autter.parent_trace_id": state.parentTraceId } : {},
|
|
1230
|
+
...state.attributes
|
|
1231
|
+
} : {};
|
|
1232
|
+
}
|
|
1233
|
+
function traceAttributes(state) {
|
|
1234
|
+
return toSpanAttributes(operationAttributes(state));
|
|
1235
|
+
}
|
|
1236
|
+
function emit(level, message, attributes, extra = {}, options = {}) {
|
|
1237
|
+
const state = options.state !== void 0 ? _nullishCoalesce(options.state, () => ( void 0)) : local.getStore();
|
|
1238
|
+
if (_optionalChain([state, 'optionalAccess', _18 => _18.sealed])) return;
|
|
1239
|
+
const summary = extra["autter.event.type"] === "operation";
|
|
1240
|
+
if (!summary && LEVEL_SEVERITY[level] < LEVEL_SEVERITY[_nullishCoalesce(_optionalChain([config, 'optionalAccess', _19 => _19.options, 'optionalAccess', _20 => _20.minLevel]), () => ( "debug"))])
|
|
1241
|
+
return;
|
|
1242
|
+
if (!summary && state && _optionalChain([config, 'optionalAccess', _21 => _21.options, 'optionalAccess', _22 => _22.inline]) !== false) {
|
|
1243
|
+
const { "exception.stacktrace": _stack, ...inlineAttrs } = userContext(
|
|
1244
|
+
attributes,
|
|
1245
|
+
redact
|
|
1246
|
+
);
|
|
1247
|
+
appendInlineLog(state.inline, level, message, inlineAttrs, redact);
|
|
1248
|
+
if (level === "debug" || level === "info") return;
|
|
1249
|
+
}
|
|
1250
|
+
const span = _nullishCoalesce(options.span, () => ( _optionalChain([_api.trace, 'access', _23 => _23.getActiveSpan, 'call', _24 => _24(), 'optionalAccess', _25 => _25.spanContext, 'call', _26 => _26()])));
|
|
1251
|
+
const user = merge(_nullishCoalesce(_optionalChain([state, 'optionalAccess', _27 => _27.attributes]), () => ( {})), attributes);
|
|
1252
|
+
const exceptions = Object.fromEntries(
|
|
1253
|
+
Object.entries(user).filter(([key]) => key.startsWith("exception."))
|
|
1254
|
+
);
|
|
1255
|
+
const raw = {
|
|
1256
|
+
"autter.event.id": _crypto.randomUUID.call(void 0, ),
|
|
1257
|
+
...extra,
|
|
1258
|
+
...exceptions,
|
|
1259
|
+
...operationAttributes(state),
|
|
1260
|
+
...user
|
|
1261
|
+
};
|
|
1262
|
+
const enrichers = _optionalChain([config, 'optionalAccess', _28 => _28.options, 'optionalAccess', _29 => _29.enrich]);
|
|
1263
|
+
if (summary && state && _optionalChain([enrichers, 'optionalAccess', _30 => _30.length])) {
|
|
1264
|
+
const event2 = { level, message, attributes: raw };
|
|
1265
|
+
for (const enrich of enrichers) {
|
|
1266
|
+
try {
|
|
1267
|
+
enrich(event2, {
|
|
1268
|
+
req: state.req,
|
|
1269
|
+
res: state.res,
|
|
1270
|
+
operation: { id: state.id, name: state.name, kind: state.kind }
|
|
1271
|
+
});
|
|
1272
|
+
} catch (e13) {
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
const event = createRuntimeEvent({
|
|
1277
|
+
level,
|
|
1278
|
+
message: String(_nullishCoalesce(safe({ message }).message, () => ( ""))).slice(0, 4e3),
|
|
1279
|
+
attributes: safe(raw),
|
|
1280
|
+
...span ? { traceId: span.traceId, spanId: span.spanId } : {}
|
|
1281
|
+
});
|
|
1282
|
+
for (const sink of activeSinks()) {
|
|
1283
|
+
try {
|
|
1284
|
+
sink.write(event);
|
|
1285
|
+
} catch (e14) {
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
function configureRuntimeLogger(next) {
|
|
1290
|
+
config = next;
|
|
1291
|
+
sinks = defaultSinks(next);
|
|
1292
|
+
for (const sink of sinks) {
|
|
1293
|
+
try {
|
|
1294
|
+
_optionalChain([sink, 'access', _31 => _31.start, 'optionalCall', _32 => _32({
|
|
1295
|
+
endpoint: next.endpoint,
|
|
1296
|
+
apiKey: next.apiKey,
|
|
1297
|
+
service: next.service,
|
|
1298
|
+
environment: next.environment,
|
|
1299
|
+
...next.release ? { release: next.release } : {},
|
|
1300
|
+
...next.distro ? { distro: next.distro } : {}
|
|
1301
|
+
})]);
|
|
1302
|
+
} catch (e15) {
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
function addRuntimeSink(sink) {
|
|
1307
|
+
extraSinks.add(sink);
|
|
1308
|
+
return () => extraSinks.delete(sink);
|
|
1309
|
+
}
|
|
1310
|
+
function notifyException(error, attributes = {}) {
|
|
1311
|
+
if (!extraSinks.size && !sinks.some((sink) => sink.exception)) return;
|
|
1312
|
+
const state = local.getStore();
|
|
1313
|
+
const record = {
|
|
1314
|
+
time: Date.now(),
|
|
1315
|
+
error,
|
|
1316
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1317
|
+
type: error instanceof Error ? error.name : "Error",
|
|
1318
|
+
attributes: { ...attributes, ...errorAttributes(error) },
|
|
1319
|
+
...state ? { operationId: state.id } : {},
|
|
1320
|
+
..._optionalChain([state, 'optionalAccess', _33 => _33.requestId]) ? { requestId: state.requestId } : {}
|
|
1321
|
+
};
|
|
1322
|
+
for (const sink of [...sinks, ...extraSinks]) {
|
|
1323
|
+
try {
|
|
1324
|
+
_optionalChain([sink, 'access', _34 => _34.exception, 'optionalCall', _35 => _35(record)]);
|
|
1325
|
+
} catch (e16) {
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
function runtimeLogStats() {
|
|
1330
|
+
return {
|
|
1331
|
+
buffered: sinks.reduce((sum, sink) => sum + (_nullishCoalesce(_optionalChain([sink, 'access', _36 => _36.buffered, 'optionalCall', _37 => _37()]), () => ( 0))), 0),
|
|
1332
|
+
dropped: sinkStats.dropped
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
async function flushRuntimeLogs() {
|
|
1336
|
+
if (!config) return;
|
|
1337
|
+
const results = await Promise.allSettled(
|
|
1338
|
+
sinks.map((sink) => Promise.resolve().then(() => _optionalChain([sink, 'access', _38 => _38.flush, 'optionalCall', _39 => _39()])))
|
|
1339
|
+
);
|
|
1340
|
+
const failed = results.find((result) => result.status === "rejected");
|
|
1341
|
+
if (failed) throw failed.reason;
|
|
1342
|
+
}
|
|
1343
|
+
async function shutdownRuntimeLogger() {
|
|
1344
|
+
const active = sinks;
|
|
1345
|
+
const results = await Promise.allSettled(
|
|
1346
|
+
active.map((sink) => Promise.resolve().then(() => _optionalChain([sink, 'access', _40 => _40.shutdown, 'optionalCall', _41 => _41()])))
|
|
1347
|
+
);
|
|
1348
|
+
config = null;
|
|
1349
|
+
sinks = [];
|
|
1350
|
+
const failed = results.find((result) => result.status === "rejected");
|
|
1351
|
+
if (failed) throw failed.reason;
|
|
1352
|
+
}
|
|
1353
|
+
function noteOperationError(error, thrown = false, state = currentOperation()) {
|
|
1354
|
+
if (!state || state.sealed) return;
|
|
1355
|
+
state.error = error;
|
|
1356
|
+
if (thrown) state.errorThrown = true;
|
|
1357
|
+
}
|
|
1358
|
+
function recordOperationAiUsage(usage) {
|
|
1359
|
+
const state = currentOperation();
|
|
1360
|
+
if (state) state.ai = addAiUsage(state.ai, usage);
|
|
1361
|
+
}
|
|
1362
|
+
function createRuntimeLogger(attributes = {}) {
|
|
1363
|
+
const attrs = userContext(attributes, redact);
|
|
1364
|
+
return {
|
|
1365
|
+
debug: (message, extra) => emit("debug", message, merge(attrs, extra)),
|
|
1366
|
+
info: (message, extra) => emit("info", message, merge(attrs, extra)),
|
|
1367
|
+
warn: (message, extra) => emit("warning", message, merge(attrs, extra)),
|
|
1368
|
+
error: (error, extra) => emit(
|
|
1369
|
+
"error",
|
|
1370
|
+
error instanceof Error ? error.message : String(error),
|
|
1371
|
+
{
|
|
1372
|
+
...attrs,
|
|
1373
|
+
...extra,
|
|
1374
|
+
...error instanceof Error ? {
|
|
1375
|
+
"exception.type": error.name,
|
|
1376
|
+
"exception.stacktrace": _nullishCoalesce(error.stack, () => ( ""))
|
|
1377
|
+
} : {}
|
|
1378
|
+
},
|
|
1379
|
+
errorAttributes(error)
|
|
1380
|
+
)
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
var runtimeLogger = createRuntimeLogger();
|
|
1384
|
+
function captureExceptionAsLog(error, attributes = {}) {
|
|
1385
|
+
const isError = error instanceof Error;
|
|
1386
|
+
const message = isError ? error.message : String(error);
|
|
1387
|
+
const stack = isError && error.stack ? error.stack : _nullishCoalesce(_optionalChain([new Error(), 'access', _42 => _42.stack, 'optionalAccess', _43 => _43.split, 'call', _44 => _44("\n"), 'access', _45 => _45.filter, 'call', _46 => _46((line, i) => i === 0 || !/captureException/.test(line)), 'access', _47 => _47.join, 'call', _48 => _48("\n")]), () => ( ""));
|
|
1388
|
+
noteOperationError(error);
|
|
1389
|
+
emit(
|
|
1390
|
+
"error",
|
|
1391
|
+
message,
|
|
1392
|
+
{
|
|
1393
|
+
...attributes,
|
|
1394
|
+
"exception.type": isError ? error.name : "Error",
|
|
1395
|
+
"exception.message": message,
|
|
1396
|
+
"exception.stacktrace": stack
|
|
1397
|
+
},
|
|
1398
|
+
{ "autter.capture.mode": "log", ...errorAttributes(error) }
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
function newState(name, kind, attributes, link) {
|
|
1402
|
+
const startedAt = Date.now();
|
|
1403
|
+
return {
|
|
1404
|
+
id: _crypto.randomUUID.call(void 0, ),
|
|
1405
|
+
name: String(safe({ name }).name).slice(0, 200),
|
|
1406
|
+
kind,
|
|
1407
|
+
...link.parentId ? { parentId: link.parentId } : {},
|
|
1408
|
+
...link.requestId ? { requestId: link.requestId } : {},
|
|
1409
|
+
...link.parentTraceId ? { parentTraceId: link.parentTraceId } : {},
|
|
1410
|
+
attributes: merge(_nullishCoalesce(link.base, () => ( {})), attributes),
|
|
1411
|
+
startedAt,
|
|
1412
|
+
outcome: "succeeded",
|
|
1413
|
+
steps: [],
|
|
1414
|
+
inline: createInlineLogState(startedAt)
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
function createRequestState(input) {
|
|
1418
|
+
const parent = currentOperation();
|
|
1419
|
+
const state = newState(input.name, "request", {}, {
|
|
1420
|
+
requestId: input.requestId,
|
|
1421
|
+
...parent ? { parentId: parent.id } : {}
|
|
1422
|
+
});
|
|
1423
|
+
state.req = input.req;
|
|
1424
|
+
state.res = input.res;
|
|
1425
|
+
return state;
|
|
1426
|
+
}
|
|
1427
|
+
function setOutcome(state, status, message) {
|
|
1428
|
+
if (state.sealed) return;
|
|
1429
|
+
state.outcome = status;
|
|
1430
|
+
state.explicitOutcome = true;
|
|
1431
|
+
state.message = message;
|
|
1432
|
+
if (status === "failed")
|
|
1433
|
+
state.reportingStack = _nullishCoalesce(new Error("Operation outcome reported here").stack, () => ( ""));
|
|
1434
|
+
}
|
|
1435
|
+
function operationHandle(state) {
|
|
1436
|
+
return {
|
|
1437
|
+
id: state.id,
|
|
1438
|
+
setContext: (attrs) => {
|
|
1439
|
+
if (!state.sealed) {
|
|
1440
|
+
state.attributes = merge(state.attributes, attrs);
|
|
1441
|
+
_optionalChain([_api.trace, 'access', _49 => _49.getActiveSpan, 'call', _50 => _50(), 'optionalAccess', _51 => _51.setAttributes, 'call', _52 => _52(traceAttributes(state))]);
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
outcome: (status, message) => setOutcome(state, status, message),
|
|
1445
|
+
step: async (stepName, stepFn) => {
|
|
1446
|
+
const started = Date.now();
|
|
1447
|
+
let status = "succeeded";
|
|
1448
|
+
try {
|
|
1449
|
+
return await stepFn();
|
|
1450
|
+
} catch (error) {
|
|
1451
|
+
status = "failed";
|
|
1452
|
+
throw error;
|
|
1453
|
+
} finally {
|
|
1454
|
+
if (!state.sealed && state.steps.length < 64)
|
|
1455
|
+
state.steps.push({
|
|
1456
|
+
name: String(safe({ name: stepName }).name).slice(0, 200),
|
|
1457
|
+
status,
|
|
1458
|
+
durationMs: Date.now() - started
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
function summaryExtra(state, level, http = {}) {
|
|
1465
|
+
const err = state.error;
|
|
1466
|
+
return {
|
|
1467
|
+
"autter.event.type": "operation",
|
|
1468
|
+
"autter.operation.outcome": state.outcome,
|
|
1469
|
+
"autter.operation.duration_ms": Date.now() - state.startedAt,
|
|
1470
|
+
"autter.operation.steps": state.steps,
|
|
1471
|
+
"autter.operation.kind": state.kind,
|
|
1472
|
+
"autter.operation.level": maxLevel(state.inline.level, level),
|
|
1473
|
+
...state.ai ? { "autter.operation.ai": state.ai } : {},
|
|
1474
|
+
...http,
|
|
1475
|
+
...err !== void 0 ? errorAttributes(err) : {},
|
|
1476
|
+
...state.inline.logsTruncated ? { "autter.operation.logs_truncated": true } : {},
|
|
1477
|
+
...state.inline.logs.length ? { "autter.operation.logs": state.inline.logs } : {}
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
function emitSummary(state, options = {}) {
|
|
1481
|
+
if (state.sealed) return;
|
|
1482
|
+
const err = state.error;
|
|
1483
|
+
const level = state.outcome === "failed" ? "error" : "info";
|
|
1484
|
+
emit(
|
|
1485
|
+
level,
|
|
1486
|
+
_nullishCoalesce(state.message, () => ( `${state.name}: ${state.outcome}`)),
|
|
1487
|
+
{
|
|
1488
|
+
...operationAttributes(state),
|
|
1489
|
+
...err instanceof Error ? {
|
|
1490
|
+
"exception.type": err.name,
|
|
1491
|
+
"exception.stacktrace": _nullishCoalesce(err.stack, () => ( ""))
|
|
1492
|
+
} : {}
|
|
1493
|
+
},
|
|
1494
|
+
summaryExtra(state, level, options.http),
|
|
1495
|
+
{ state, ...options.span ? { span: options.span } : {} }
|
|
1496
|
+
);
|
|
1497
|
+
state.sealed = true;
|
|
1498
|
+
}
|
|
1499
|
+
function reportExplicitFailure(state) {
|
|
1500
|
+
if (state.outcome === "failed" && state.explicitOutcome && !state.errorThrown)
|
|
1501
|
+
_optionalChain([config, 'optionalAccess', _53 => _53.reportOutcome, 'call', _54 => _54(state.name, _nullishCoalesce(state.message, () => ( "Operation failed")), {
|
|
1502
|
+
...traceAttributes(state),
|
|
1503
|
+
"autter.outcome.stack": _nullishCoalesce(state.reportingStack, () => ( ""))
|
|
1504
|
+
})]);
|
|
1505
|
+
}
|
|
1506
|
+
function startOperation(name, fn, attributes, options, internal = {}) {
|
|
1507
|
+
const parent = _nullishCoalesce(internal.forkParent, () => ( local.getStore()));
|
|
1508
|
+
const carrier = options.from ? parseCarrier(options.from) : null;
|
|
1509
|
+
const traceparent = _optionalChain([carrier, 'optionalAccess', _55 => _55.traceparent]) ? parseTraceparent(carrier.traceparent) : null;
|
|
1510
|
+
const linked = internal.forkParent !== void 0 || parent && !parent.sealed;
|
|
1511
|
+
const state = newState(
|
|
1512
|
+
name,
|
|
1513
|
+
"operation",
|
|
1514
|
+
attributes,
|
|
1515
|
+
carrier ? {
|
|
1516
|
+
parentId: carrier.op,
|
|
1517
|
+
...carrier.req ? { requestId: carrier.req } : {},
|
|
1518
|
+
...traceparent ? { parentTraceId: traceparent.traceId } : {}
|
|
1519
|
+
} : {
|
|
1520
|
+
...linked && parent ? { parentId: parent.id, base: parent.attributes } : {},
|
|
1521
|
+
..._optionalChain([parent, 'optionalAccess', _56 => _56.requestId]) ? { requestId: parent.requestId } : {}
|
|
1522
|
+
}
|
|
1523
|
+
);
|
|
1524
|
+
const operation = operationHandle(state);
|
|
1525
|
+
const run = () => local.run(state, async () => {
|
|
1526
|
+
let thrown;
|
|
1527
|
+
try {
|
|
1528
|
+
return await fn(operation);
|
|
1529
|
+
} catch (error) {
|
|
1530
|
+
state.outcome = "failed";
|
|
1531
|
+
thrown = error;
|
|
1532
|
+
noteOperationError(error, true, state);
|
|
1533
|
+
_optionalChain([config, 'optionalAccess', _57 => _57.captureThrown, 'optionalCall', _58 => _58(error)]);
|
|
1534
|
+
throw error;
|
|
1535
|
+
} finally {
|
|
1536
|
+
_optionalChain([_api.trace, 'access', _59 => _59.getActiveSpan, 'call', _60 => _60(), 'optionalAccess', _61 => _61.setAttributes, 'call', _62 => _62({
|
|
1537
|
+
...traceAttributes(state),
|
|
1538
|
+
"autter.operation.outcome": state.outcome,
|
|
1539
|
+
"autter.operation.kind": state.kind
|
|
1540
|
+
})]);
|
|
1541
|
+
if (state.outcome === "failed" && !thrown)
|
|
1542
|
+
_optionalChain([config, 'optionalAccess', _63 => _63.reportOutcome, 'call', _64 => _64(
|
|
1543
|
+
state.name,
|
|
1544
|
+
_nullishCoalesce(state.message, () => ( "Operation failed")),
|
|
1545
|
+
{
|
|
1546
|
+
...traceAttributes(state),
|
|
1547
|
+
"autter.outcome.stack": _nullishCoalesce(state.reportingStack, () => ( ""))
|
|
1548
|
+
}
|
|
1549
|
+
)]);
|
|
1550
|
+
emitSummary(state);
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
const links = traceparent ? [
|
|
1554
|
+
{
|
|
1555
|
+
context: {
|
|
1556
|
+
traceId: traceparent.traceId,
|
|
1557
|
+
spanId: traceparent.spanId,
|
|
1558
|
+
traceFlags: traceparent.sampled ? 1 : 0,
|
|
1559
|
+
isRemote: true
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
] : [];
|
|
1563
|
+
const promise = _optionalChain([config, 'optionalAccess', _65 => _65.run]) ? config.run(state.name, run, traceAttributes(state), links) : run();
|
|
1564
|
+
if (!options.waitUntil) return promise;
|
|
1565
|
+
const waitUntil = options.waitUntil;
|
|
1566
|
+
return promise.finally(() => {
|
|
1567
|
+
try {
|
|
1568
|
+
waitUntil(flushRuntimeLogs().catch(() => {
|
|
1569
|
+
}));
|
|
1570
|
+
} catch (e17) {
|
|
1571
|
+
}
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
function withRuntimeOperation(name, fn, attributes = {}, options = {}) {
|
|
1575
|
+
return startOperation(name, fn, attributes, options);
|
|
1576
|
+
}
|
|
1577
|
+
function runInBackground(name, fn) {
|
|
1578
|
+
return runtimeContext.fork(name, fn).catch(() => void 0);
|
|
1579
|
+
}
|
|
1580
|
+
var runtimeContext = {
|
|
1581
|
+
/** Merge attributes into the current summary's context. */
|
|
1582
|
+
set(attributes) {
|
|
1583
|
+
const state = currentOperation();
|
|
1584
|
+
if (!state) return;
|
|
1585
|
+
state.attributes = merge(state.attributes, attributes);
|
|
1586
|
+
_optionalChain([_api.trace, 'access', _66 => _66.getActiveSpan, 'call', _67 => _67(), 'optionalAccess', _68 => _68.setAttributes, 'call', _69 => _69(traceAttributes(state))]);
|
|
1587
|
+
},
|
|
1588
|
+
/** Set the outcome explicitly (wins over status/thrown-error rules). */
|
|
1589
|
+
outcome(status, message) {
|
|
1590
|
+
const state = currentOperation();
|
|
1591
|
+
if (state) setOutcome(state, status, message);
|
|
1592
|
+
},
|
|
1593
|
+
debug(message, attributes) {
|
|
1594
|
+
runtimeLogger.debug(message, attributes);
|
|
1595
|
+
},
|
|
1596
|
+
info(message, attributes) {
|
|
1597
|
+
runtimeLogger.info(message, attributes);
|
|
1598
|
+
},
|
|
1599
|
+
warn(message, attributes) {
|
|
1600
|
+
runtimeLogger.warn(message, attributes);
|
|
1601
|
+
},
|
|
1602
|
+
/** Log an error and attach it (code/why/fix) to the current summary. */
|
|
1603
|
+
error(error, attributes) {
|
|
1604
|
+
noteOperationError(error);
|
|
1605
|
+
runtimeLogger.error(error, attributes);
|
|
1606
|
+
},
|
|
1607
|
+
/** Current operation id. */
|
|
1608
|
+
get id() {
|
|
1609
|
+
return _optionalChain([local, 'access', _70 => _70.getStore, 'call', _71 => _71(), 'optionalAccess', _72 => _72.id]);
|
|
1610
|
+
},
|
|
1611
|
+
/** Current request id (inherited by child operations and forks). */
|
|
1612
|
+
get requestId() {
|
|
1613
|
+
return _optionalChain([local, 'access', _73 => _73.getStore, 'call', _74 => _74(), 'optionalAccess', _75 => _75.requestId]);
|
|
1614
|
+
},
|
|
1615
|
+
/**
|
|
1616
|
+
* Run `fn` as a child operation whose parent link is captured NOW, so it
|
|
1617
|
+
* still links after the parent has finished (background work).
|
|
1618
|
+
*/
|
|
1619
|
+
fork(name, fn) {
|
|
1620
|
+
const parent = local.getStore();
|
|
1621
|
+
return startOperation(name, fn, {}, {}, parent ? { forkParent: parent } : {});
|
|
1622
|
+
},
|
|
1623
|
+
/** Serialisable link for queue payloads: `{ v: 1, op, req?, traceparent? }`. */
|
|
1624
|
+
carrier() {
|
|
1625
|
+
const state = local.getStore();
|
|
1626
|
+
if (!state) return void 0;
|
|
1627
|
+
const span = _optionalChain([_api.trace, 'access', _76 => _76.getActiveSpan, 'call', _77 => _77(), 'optionalAccess', _78 => _78.spanContext, 'call', _79 => _79()]);
|
|
1628
|
+
const traceparent = span ? formatTraceparent(span.traceId, span.spanId, (span.traceFlags & 1) === 1) : void 0;
|
|
1629
|
+
return createCarrier({
|
|
1630
|
+
op: state.id,
|
|
1631
|
+
...state.requestId ? { req: state.requestId } : {},
|
|
1632
|
+
...traceparent ? { traceparent } : {}
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
};
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
|
|
1639
|
+
|
|
1640
|
+
|
|
1641
|
+
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
|
|
1648
|
+
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
|
|
1664
|
+
|
|
1665
|
+
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
|
|
1669
|
+
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
exports.redactAttributes = redactAttributes; exports.redactText = redactText; exports.makeRedactor = makeRedactor; exports.CODE_PATTERN = CODE_PATTERN; exports.RuntimeError = RuntimeError; exports.defineRuntimeErrors = defineRuntimeErrors; exports.isRuntimeErrorLike = isRuntimeErrorLike; exports.errorCodeOf = errorCodeOf; exports.errorAttributes = errorAttributes; exports.errorInternal = errorInternal; exports.toClientError = toClientError; exports.responseStatusOf = responseStatusOf; exports.isSummary = isSummary; exports.DEFAULT_REQUEST_ID_HEADER = DEFAULT_REQUEST_ID_HEADER; exports.resolveRequestId = resolveRequestId; exports.normalizeRoutePath = normalizeRoutePath; exports.compileIgnore = compileIgnore; exports.requestOutcome = requestOutcome; exports.parseUserAgent = parseUserAgent; exports.otlpSink = otlpSink; exports.consoleSink = consoleSink; exports.fileSink = fileSink; exports.memorySink = memorySink; exports.local = local; exports.currentOperation = currentOperation; exports.configureRuntimeLogger = configureRuntimeLogger; exports.addRuntimeSink = addRuntimeSink; exports.notifyException = notifyException; exports.runtimeLogStats = runtimeLogStats; exports.flushRuntimeLogs = flushRuntimeLogs; exports.shutdownRuntimeLogger = shutdownRuntimeLogger; exports.noteOperationError = noteOperationError; exports.recordOperationAiUsage = recordOperationAiUsage; exports.createRuntimeLogger = createRuntimeLogger; exports.runtimeLogger = runtimeLogger; exports.captureExceptionAsLog = captureExceptionAsLog; exports.createRequestState = createRequestState; exports.emitSummary = emitSummary; exports.reportExplicitFailure = reportExplicitFailure; exports.withRuntimeOperation = withRuntimeOperation; exports.runInBackground = runInBackground; exports.runtimeContext = runtimeContext;
|