@ekkolyth/logging 0.1.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/LICENSE +21 -0
- package/README.md +751 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.js +27 -0
- package/dist/browser.js.map +1 -0
- package/dist/context-BU9CEJZ3.js +25 -0
- package/dist/context-BU9CEJZ3.js.map +1 -0
- package/dist/context-seam-DzbwDxiY.js +12 -0
- package/dist/context-seam-DzbwDxiY.js.map +1 -0
- package/dist/context.browser.d.ts +7 -0
- package/dist/context.browser.js +14 -0
- package/dist/context.browser.js.map +1 -0
- package/dist/context.d.ts +9 -0
- package/dist/context.js +2 -0
- package/dist/env-Dur55C_F.js +50 -0
- package/dist/env-Dur55C_F.js.map +1 -0
- package/dist/http.browser.d.ts +16 -0
- package/dist/http.browser.js +23 -0
- package/dist/http.browser.js.map +1 -0
- package/dist/http.d.ts +22 -0
- package/dist/http.js +112 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-BxxJhfg8.js +446 -0
- package/dist/logger-BxxJhfg8.js.map +1 -0
- package/dist/logger-V7XF9Wuo.d.ts +35 -0
- package/dist/outbound-CQkyIyxd.d.ts +10 -0
- package/dist/outbound-YYy-EfTF.js +216 -0
- package/dist/outbound-YYy-EfTF.js.map +1 -0
- package/dist/throttler-s0TCHZNK.js +45 -0
- package/dist/throttler-s0TCHZNK.js.map +1 -0
- package/dist/types-CieIrR8p.d.ts +7 -0
- package/package.json +56 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { t as activeContext } from "./context-seam-DzbwDxiY.js";
|
|
2
|
+
import { n as parseWindow, r as shouldEmitEvery } from "./throttler-s0TCHZNK.js";
|
|
3
|
+
//#region src/clock.ts
|
|
4
|
+
let clock = () => /* @__PURE__ */ new Date();
|
|
5
|
+
function now() {
|
|
6
|
+
return clock();
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/types.ts
|
|
10
|
+
const RESERVED_RECORD_FIELDS = /* @__PURE__ */ new Set([
|
|
11
|
+
"time",
|
|
12
|
+
"level",
|
|
13
|
+
"msg",
|
|
14
|
+
"service",
|
|
15
|
+
"scope"
|
|
16
|
+
]);
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/normalize.ts
|
|
19
|
+
const MAX_DEPTH = 8;
|
|
20
|
+
const MAX_STRING_BYTES = 16384;
|
|
21
|
+
const MAX_COLLECTION_ITEMS = 100;
|
|
22
|
+
const TRUNCATED_KEYS_FIELD = "_logging_truncated";
|
|
23
|
+
const MAX_DEPTH_MARKER = "[MaxDepth]";
|
|
24
|
+
const CIRCULAR_MARKER = "[Circular]";
|
|
25
|
+
const UNSERIALIZABLE_MARKER = "[Unserializable]";
|
|
26
|
+
const TRUNCATED_STRING_SUFFIX = "[Truncated]";
|
|
27
|
+
const stringEncoder = new TextEncoder();
|
|
28
|
+
const stringDecoder = new TextDecoder();
|
|
29
|
+
const truncateString = (value) => {
|
|
30
|
+
const bytes = stringEncoder.encode(value);
|
|
31
|
+
if (bytes.length <= MAX_STRING_BYTES) return value;
|
|
32
|
+
const suffixBytes = stringEncoder.encode(TRUNCATED_STRING_SUFFIX);
|
|
33
|
+
let cut = MAX_STRING_BYTES - suffixBytes.length;
|
|
34
|
+
while (cut > 0 && (bytes[cut] & 192) === 128) cut--;
|
|
35
|
+
return stringDecoder.decode(bytes.subarray(0, cut)) + TRUNCATED_STRING_SUFFIX;
|
|
36
|
+
};
|
|
37
|
+
const compareByCodePoint = (a, b) => {
|
|
38
|
+
const aChars = Array.from(a);
|
|
39
|
+
const bChars = Array.from(b);
|
|
40
|
+
const length = Math.min(aChars.length, bChars.length);
|
|
41
|
+
for (let i = 0; i < length; i++) {
|
|
42
|
+
const diff = (aChars[i].codePointAt(0) ?? 0) - (bChars[i].codePointAt(0) ?? 0);
|
|
43
|
+
if (diff !== 0) return diff;
|
|
44
|
+
}
|
|
45
|
+
return aChars.length - bChars.length;
|
|
46
|
+
};
|
|
47
|
+
const normalizeNumber = (value) => {
|
|
48
|
+
if (Number.isNaN(value)) return "NaN";
|
|
49
|
+
if (value === Number.POSITIVE_INFINITY) return "Infinity";
|
|
50
|
+
if (value === Number.NEGATIVE_INFINITY) return "-Infinity";
|
|
51
|
+
return value;
|
|
52
|
+
};
|
|
53
|
+
const errorTypeName = (error) => error.name || error.constructor?.name || "Error";
|
|
54
|
+
const normalizeErrorCode = (code, depth, seen) => {
|
|
55
|
+
if (typeof code === "string" || typeof code === "number" || typeof code === "bigint" || typeof code === "boolean") return truncateString(String(code));
|
|
56
|
+
return normalizeValue(code, depth, seen);
|
|
57
|
+
};
|
|
58
|
+
const normalizeError = (error, depth, seen) => {
|
|
59
|
+
if (depth > MAX_DEPTH) return MAX_DEPTH_MARKER;
|
|
60
|
+
if (seen.has(error)) return CIRCULAR_MARKER;
|
|
61
|
+
seen.add(error);
|
|
62
|
+
const result = {
|
|
63
|
+
type: errorTypeName(error),
|
|
64
|
+
message: truncateString(error.message)
|
|
65
|
+
};
|
|
66
|
+
const code = error.code;
|
|
67
|
+
if (code !== void 0) result.code = normalizeErrorCode(code, depth + 1, seen);
|
|
68
|
+
if (typeof error.stack === "string") result.stack = truncateString(error.stack);
|
|
69
|
+
const cause = error.cause;
|
|
70
|
+
if (cause !== void 0) result.cause = normalizeValue(cause, depth + 1, seen);
|
|
71
|
+
const aggregateErrors = error.errors;
|
|
72
|
+
if (Array.isArray(aggregateErrors)) result.causes = aggregateErrors.map((entry) => normalizeValue(entry, depth + 1, seen));
|
|
73
|
+
seen.delete(error);
|
|
74
|
+
return result;
|
|
75
|
+
};
|
|
76
|
+
const normalizeArray = (value, depth, seen) => {
|
|
77
|
+
if (seen.has(value)) return CIRCULAR_MARKER;
|
|
78
|
+
seen.add(value);
|
|
79
|
+
const length = value.length;
|
|
80
|
+
const upper = Math.min(length, MAX_COLLECTION_ITEMS);
|
|
81
|
+
const items = [];
|
|
82
|
+
for (let i = 0; i < upper; i++) try {
|
|
83
|
+
items.push(normalizeValue(value[i], depth + 1, seen));
|
|
84
|
+
} catch {
|
|
85
|
+
items.push(UNSERIALIZABLE_MARKER);
|
|
86
|
+
}
|
|
87
|
+
if (length > MAX_COLLECTION_ITEMS) items.push(`[Truncated: ${length - MAX_COLLECTION_ITEMS} items]`);
|
|
88
|
+
seen.delete(value);
|
|
89
|
+
return items;
|
|
90
|
+
};
|
|
91
|
+
const normalizeMap = (value, depth, seen) => {
|
|
92
|
+
if (seen.has(value)) return CIRCULAR_MARKER;
|
|
93
|
+
seen.add(value);
|
|
94
|
+
const entries = Array.from(value.entries()).sort((a, b) => compareByCodePoint(String(a[0]), String(b[0])));
|
|
95
|
+
const kept = entries.slice(0, MAX_COLLECTION_ITEMS);
|
|
96
|
+
const result = {};
|
|
97
|
+
for (const [key, entry] of kept) {
|
|
98
|
+
const stringKey = String(key);
|
|
99
|
+
try {
|
|
100
|
+
result[stringKey] = normalizeValue(entry, depth + 1, seen);
|
|
101
|
+
} catch {
|
|
102
|
+
result[stringKey] = UNSERIALIZABLE_MARKER;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (entries.length > kept.length) result[TRUNCATED_KEYS_FIELD] = entries.length - kept.length;
|
|
106
|
+
seen.delete(value);
|
|
107
|
+
return result;
|
|
108
|
+
};
|
|
109
|
+
const normalizeObject = (value, depth, seen) => {
|
|
110
|
+
if (seen.has(value)) return CIRCULAR_MARKER;
|
|
111
|
+
seen.add(value);
|
|
112
|
+
const keys = Object.keys(value).sort(compareByCodePoint);
|
|
113
|
+
const kept = keys.slice(0, MAX_COLLECTION_ITEMS);
|
|
114
|
+
const result = {};
|
|
115
|
+
for (const key of kept) try {
|
|
116
|
+
result[key] = normalizeValue(value[key], depth + 1, seen);
|
|
117
|
+
} catch {
|
|
118
|
+
result[key] = UNSERIALIZABLE_MARKER;
|
|
119
|
+
}
|
|
120
|
+
if (keys.length > kept.length) result[TRUNCATED_KEYS_FIELD] = keys.length - kept.length;
|
|
121
|
+
seen.delete(value);
|
|
122
|
+
return result;
|
|
123
|
+
};
|
|
124
|
+
function normalizeValue(value, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
125
|
+
if (depth > MAX_DEPTH) return MAX_DEPTH_MARKER;
|
|
126
|
+
switch (typeof value) {
|
|
127
|
+
case "undefined": return;
|
|
128
|
+
case "string": return truncateString(value);
|
|
129
|
+
case "number": return normalizeNumber(value);
|
|
130
|
+
case "boolean": return value;
|
|
131
|
+
case "bigint": return value.toString();
|
|
132
|
+
case "function": return "[Unsupported: function]";
|
|
133
|
+
case "symbol": return "[Unsupported: symbol]";
|
|
134
|
+
}
|
|
135
|
+
if (value === null) return null;
|
|
136
|
+
if (value instanceof Date) {
|
|
137
|
+
const time = value.getTime();
|
|
138
|
+
return Number.isNaN(time) ? UNSERIALIZABLE_MARKER : value.toISOString();
|
|
139
|
+
}
|
|
140
|
+
if (value instanceof Error) return normalizeError(value, depth, seen);
|
|
141
|
+
if (Array.isArray(value)) return normalizeArray(value, depth, seen);
|
|
142
|
+
if (value instanceof Map) return normalizeMap(value, depth, seen);
|
|
143
|
+
if (value instanceof Set) return "[Unsupported: Set]";
|
|
144
|
+
return normalizeObject(value, depth, seen);
|
|
145
|
+
}
|
|
146
|
+
const describeErrorAttribute = (value) => {
|
|
147
|
+
if (value === null) return "null";
|
|
148
|
+
try {
|
|
149
|
+
return truncateString(String(value));
|
|
150
|
+
} catch {
|
|
151
|
+
return UNSERIALIZABLE_MARKER;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const normalizeErrorAttribute = (value, seen) => {
|
|
155
|
+
if (value instanceof Error) return normalizeError(value, 0, seen);
|
|
156
|
+
return {
|
|
157
|
+
type: typeof value,
|
|
158
|
+
message: describeErrorAttribute(value)
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
function normalizeRecord(input) {
|
|
162
|
+
const seen = /* @__PURE__ */ new Set();
|
|
163
|
+
const record = {
|
|
164
|
+
time: input.time.toISOString(),
|
|
165
|
+
level: input.level,
|
|
166
|
+
msg: truncateString(input.msg)
|
|
167
|
+
};
|
|
168
|
+
if (input.service) record.service = input.service;
|
|
169
|
+
if (input.scope) record.scope = input.scope;
|
|
170
|
+
const attributeKeys = Object.keys(input.attributes ?? {}).filter((key) => !RESERVED_RECORD_FIELDS.has(key)).sort(compareByCodePoint);
|
|
171
|
+
for (const key of attributeKeys) {
|
|
172
|
+
let value;
|
|
173
|
+
try {
|
|
174
|
+
const raw = input.attributes[key];
|
|
175
|
+
value = key === "error" && raw !== void 0 ? normalizeErrorAttribute(raw, seen) : normalizeValue(raw, 0, seen);
|
|
176
|
+
} catch {
|
|
177
|
+
value = UNSERIALIZABLE_MARKER;
|
|
178
|
+
}
|
|
179
|
+
if (value === void 0) continue;
|
|
180
|
+
record[key] = value;
|
|
181
|
+
}
|
|
182
|
+
return record;
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/format.ts
|
|
186
|
+
const ESC = String.fromCharCode(27);
|
|
187
|
+
const ANSI_RESET = `${ESC}[0m`;
|
|
188
|
+
const ANSI_DIM = `${ESC}[2m`;
|
|
189
|
+
const ANSI_BLUE = `${ESC}[34m`;
|
|
190
|
+
const ANSI_YELLOW = `${ESC}[33m`;
|
|
191
|
+
const ANSI_RED = `${ESC}[31m`;
|
|
192
|
+
const ANSI_GREEN = `${ESC}[32m`;
|
|
193
|
+
const ANSI_MAGENTA = `${ESC}[35m`;
|
|
194
|
+
const ANSI_CYAN = `${ESC}[36m`;
|
|
195
|
+
const ANSI_BOLD = `${ESC}[1m`;
|
|
196
|
+
const ANSI_BOLD_GREEN = `${ESC}[1;32m`;
|
|
197
|
+
const ANSI_BOLD_BLUE = `${ESC}[1;34m`;
|
|
198
|
+
const ANSI_BOLD_YELLOW = `${ESC}[1;33m`;
|
|
199
|
+
const ANSI_BOLD_CYAN = `${ESC}[1;36m`;
|
|
200
|
+
const ANSI_BOLD_RED = `${ESC}[1;31m`;
|
|
201
|
+
const ANSI_BOLD_DIM = `${ESC}[1;2m`;
|
|
202
|
+
const UNSAFE_BARE_STRING = /[\s"'\\]/;
|
|
203
|
+
const isControlCharCode = (code) => code <= 31 || code === 127;
|
|
204
|
+
const paint = (text, code) => `${code}${text}${ANSI_RESET}`;
|
|
205
|
+
const levelColor = (level) => {
|
|
206
|
+
switch (level) {
|
|
207
|
+
case "debug": return ANSI_DIM;
|
|
208
|
+
case "info": return ANSI_BLUE;
|
|
209
|
+
case "warn": return ANSI_YELLOW;
|
|
210
|
+
case "error": return ANSI_RED;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const needsQuoting = (value) => {
|
|
214
|
+
if (value.length === 0) return true;
|
|
215
|
+
if (UNSAFE_BARE_STRING.test(value)) return true;
|
|
216
|
+
for (let i = 0; i < value.length; i++) if (isControlCharCode(value.charCodeAt(i))) return true;
|
|
217
|
+
return false;
|
|
218
|
+
};
|
|
219
|
+
const formatScalar = (value) => {
|
|
220
|
+
if (typeof value === "string") return needsQuoting(value) ? JSON.stringify(value) : value;
|
|
221
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
222
|
+
if (value === null) return "null";
|
|
223
|
+
if (value === void 0) return "undefined";
|
|
224
|
+
return JSON.stringify(value);
|
|
225
|
+
};
|
|
226
|
+
const sanitizeLineSegment = (value) => {
|
|
227
|
+
let result = "";
|
|
228
|
+
for (let i = 0; i < value.length; i++) {
|
|
229
|
+
const char = value[i];
|
|
230
|
+
result += isControlCharCode(value.charCodeAt(i)) ? JSON.stringify(char).slice(1, -1) : char;
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
233
|
+
};
|
|
234
|
+
const attributeKeysOf = (record) => Object.keys(record).filter((key) => !RESERVED_RECORD_FIELDS.has(key)).sort(compareByCodePoint);
|
|
235
|
+
function formatJSON(record) {
|
|
236
|
+
const fields = [];
|
|
237
|
+
const appendField = (key, value) => {
|
|
238
|
+
fields.push(`${JSON.stringify(key)}:${JSON.stringify(value)}`);
|
|
239
|
+
};
|
|
240
|
+
appendField("time", record.time);
|
|
241
|
+
appendField("level", record.level);
|
|
242
|
+
appendField("msg", record.msg);
|
|
243
|
+
if (record.service !== void 0) appendField("service", record.service);
|
|
244
|
+
if (record.scope !== void 0) appendField("scope", record.scope);
|
|
245
|
+
for (const key of attributeKeysOf(record)) {
|
|
246
|
+
const value = record[key];
|
|
247
|
+
if (value === void 0) continue;
|
|
248
|
+
appendField(key, value);
|
|
249
|
+
}
|
|
250
|
+
return `{${fields.join(",")}}\n`;
|
|
251
|
+
}
|
|
252
|
+
function formatPretty(record, options = {}) {
|
|
253
|
+
const color = options.color ?? false;
|
|
254
|
+
const clock = record.time.slice(11, 23);
|
|
255
|
+
const segments = [color ? paint(clock, ANSI_DIM) : clock];
|
|
256
|
+
if (record.service) {
|
|
257
|
+
const text = `[${sanitizeLineSegment(record.service)}]`;
|
|
258
|
+
segments.push(color ? paint(text, ANSI_MAGENTA) : text);
|
|
259
|
+
}
|
|
260
|
+
if (record.scope) {
|
|
261
|
+
const text = `[${sanitizeLineSegment(record.scope)}]`;
|
|
262
|
+
segments.push(color ? paint(text, ANSI_CYAN) : text);
|
|
263
|
+
}
|
|
264
|
+
const levelText = record.level.toUpperCase().padEnd(5, " ");
|
|
265
|
+
segments.push(color ? paint(levelText, levelColor(record.level)) : levelText);
|
|
266
|
+
let line = `${segments.join(" ")} ${sanitizeLineSegment(record.msg)}`;
|
|
267
|
+
for (const key of attributeKeysOf(record)) {
|
|
268
|
+
const value = record[key];
|
|
269
|
+
if (value === void 0) continue;
|
|
270
|
+
const rendered = formatScalar(value);
|
|
271
|
+
const keyText = `${sanitizeLineSegment(key)}=`;
|
|
272
|
+
if (color) {
|
|
273
|
+
const valueCode = attrValueColor(key, value, rendered);
|
|
274
|
+
line += ` ${paint(keyText, ANSI_DIM)}${valueCode ? paint(rendered, valueCode) : rendered}`;
|
|
275
|
+
} else line += ` ${keyText}${rendered}`;
|
|
276
|
+
}
|
|
277
|
+
return `${line}\n`;
|
|
278
|
+
}
|
|
279
|
+
const attrValueColor = (key, raw, rendered) => {
|
|
280
|
+
switch (key) {
|
|
281
|
+
case "error": return ANSI_RED;
|
|
282
|
+
case "request_id":
|
|
283
|
+
case "trace_id":
|
|
284
|
+
case "span_id": return ANSI_DIM;
|
|
285
|
+
case "method": switch (rendered) {
|
|
286
|
+
case "GET": return ANSI_BOLD_GREEN;
|
|
287
|
+
case "POST": return ANSI_BOLD_BLUE;
|
|
288
|
+
case "PUT": return ANSI_BOLD_YELLOW;
|
|
289
|
+
case "PATCH": return ANSI_BOLD_CYAN;
|
|
290
|
+
case "DELETE": return ANSI_BOLD_RED;
|
|
291
|
+
case "HEAD": return ANSI_BOLD_DIM;
|
|
292
|
+
default: return ANSI_BOLD;
|
|
293
|
+
}
|
|
294
|
+
case "status":
|
|
295
|
+
if (typeof raw === "number") {
|
|
296
|
+
if (raw < 300) return ANSI_GREEN;
|
|
297
|
+
if (raw < 400) return ANSI_CYAN;
|
|
298
|
+
if (raw < 500) return ANSI_YELLOW;
|
|
299
|
+
return ANSI_RED;
|
|
300
|
+
}
|
|
301
|
+
return "";
|
|
302
|
+
case "duration_ms":
|
|
303
|
+
if (typeof raw === "number") {
|
|
304
|
+
if (raw > 500) return ANSI_RED;
|
|
305
|
+
if (raw > 100) return ANSI_YELLOW;
|
|
306
|
+
return ANSI_DIM;
|
|
307
|
+
}
|
|
308
|
+
return "";
|
|
309
|
+
default: return "";
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region src/levels.ts
|
|
314
|
+
const LEVEL_ORDER = {
|
|
315
|
+
debug: 0,
|
|
316
|
+
info: 1,
|
|
317
|
+
warn: 2,
|
|
318
|
+
error: 3,
|
|
319
|
+
silent: 4
|
|
320
|
+
};
|
|
321
|
+
function enabledAt(level, threshold) {
|
|
322
|
+
return LEVEL_ORDER[level] >= LEVEL_ORDER[threshold];
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/redact.ts
|
|
326
|
+
const DEFAULT_REDACTED_KEYS = [
|
|
327
|
+
"password",
|
|
328
|
+
"passwd",
|
|
329
|
+
"secret",
|
|
330
|
+
"token",
|
|
331
|
+
"authorization",
|
|
332
|
+
"proxy_authorization",
|
|
333
|
+
"cookie",
|
|
334
|
+
"set_cookie",
|
|
335
|
+
"api_key",
|
|
336
|
+
"access_token",
|
|
337
|
+
"refresh_token",
|
|
338
|
+
"private_key",
|
|
339
|
+
"client_secret"
|
|
340
|
+
];
|
|
341
|
+
const REDACTED_MARKER = "[REDACTED]";
|
|
342
|
+
const normalizeKey = (key) => key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
343
|
+
const buildRedactedKeySet = (extra) => {
|
|
344
|
+
const keys = new Set(DEFAULT_REDACTED_KEYS.map(normalizeKey));
|
|
345
|
+
for (const key of extra) keys.add(normalizeKey(key));
|
|
346
|
+
return keys;
|
|
347
|
+
};
|
|
348
|
+
const redactValue = (value, keys) => {
|
|
349
|
+
if (Array.isArray(value)) return value.map((entry) => redactValue(entry, keys));
|
|
350
|
+
if (value !== null && typeof value === "object") {
|
|
351
|
+
const result = {};
|
|
352
|
+
for (const [key, nested] of Object.entries(value)) result[key] = keys.has(normalizeKey(key)) ? REDACTED_MARKER : redactValue(nested, keys);
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
return value;
|
|
356
|
+
};
|
|
357
|
+
function redactRecord(record, redact = []) {
|
|
358
|
+
const keys = buildRedactedKeySet(redact);
|
|
359
|
+
return redactValue(record, keys);
|
|
360
|
+
}
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/logger.ts
|
|
363
|
+
const bindingsByLogger = /* @__PURE__ */ new WeakMap();
|
|
364
|
+
const describeError = (error) => error instanceof Error ? error.stack ?? error.message : String(error);
|
|
365
|
+
function reportInternalError(config, error) {
|
|
366
|
+
if (config.onInternalError) {
|
|
367
|
+
try {
|
|
368
|
+
config.onInternalError(error);
|
|
369
|
+
} catch {}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
config.stderrWrite(`@ekkolyth/logging: internal error — ${describeError(error)}\n`);
|
|
374
|
+
} catch {}
|
|
375
|
+
}
|
|
376
|
+
function buildEngine(config) {
|
|
377
|
+
const emit = (level, msg, attributes) => {
|
|
378
|
+
if (!enabledAt(level, config.level)) return;
|
|
379
|
+
let line;
|
|
380
|
+
try {
|
|
381
|
+
const redacted = redactRecord(normalizeRecord({
|
|
382
|
+
attributes: {
|
|
383
|
+
...config.bindings,
|
|
384
|
+
...activeContext(),
|
|
385
|
+
...attributes
|
|
386
|
+
},
|
|
387
|
+
level,
|
|
388
|
+
msg,
|
|
389
|
+
scope: config.scope,
|
|
390
|
+
service: config.service,
|
|
391
|
+
time: now()
|
|
392
|
+
}), config.redact);
|
|
393
|
+
line = config.format === "json" ? formatJSON(redacted) : formatPretty(redacted, { color: config.colors });
|
|
394
|
+
} catch (error) {
|
|
395
|
+
reportInternalError(config, error);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
config.output(line);
|
|
400
|
+
} catch (error) {
|
|
401
|
+
reportInternalError(config, error);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
const every = (window, ...keyParts) => {
|
|
405
|
+
const windowMs = parseWindow(window);
|
|
406
|
+
const key = [
|
|
407
|
+
config.service ?? "",
|
|
408
|
+
config.scope ?? "",
|
|
409
|
+
...keyParts
|
|
410
|
+
].filter(Boolean).join("|");
|
|
411
|
+
const gated = (level) => (message, attributes) => {
|
|
412
|
+
if (!shouldEmitEvery(level, windowMs, key, message)) return;
|
|
413
|
+
emit(level, message, attributes);
|
|
414
|
+
};
|
|
415
|
+
return {
|
|
416
|
+
debug: gated("debug"),
|
|
417
|
+
error: gated("error"),
|
|
418
|
+
info: gated("info"),
|
|
419
|
+
warn: gated("warn")
|
|
420
|
+
};
|
|
421
|
+
};
|
|
422
|
+
const logger = {
|
|
423
|
+
debug: (message, attributes) => emit("debug", message, attributes),
|
|
424
|
+
enabled: (level) => enabledAt(level, config.level),
|
|
425
|
+
error: (message, attributes) => emit("error", message, attributes),
|
|
426
|
+
every,
|
|
427
|
+
info: (message, attributes) => emit("info", message, attributes),
|
|
428
|
+
warn: (message, attributes) => emit("warn", message, attributes),
|
|
429
|
+
with: (bindings) => buildEngine({
|
|
430
|
+
...config,
|
|
431
|
+
bindings: {
|
|
432
|
+
...config.bindings,
|
|
433
|
+
...bindings
|
|
434
|
+
}
|
|
435
|
+
})
|
|
436
|
+
};
|
|
437
|
+
bindingsByLogger.set(logger, config.bindings);
|
|
438
|
+
return logger;
|
|
439
|
+
}
|
|
440
|
+
function getBindings(logger) {
|
|
441
|
+
return { ...bindingsByLogger.get(logger) ?? {} };
|
|
442
|
+
}
|
|
443
|
+
//#endregion
|
|
444
|
+
export { getBindings as n, buildEngine as t };
|
|
445
|
+
|
|
446
|
+
//# sourceMappingURL=logger-BxxJhfg8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger-BxxJhfg8.js","names":[],"sources":["../src/clock.ts","../src/types.ts","../src/normalize.ts","../src/format.ts","../src/levels.ts","../src/redact.ts","../src/logger.ts"],"sourcesContent":["type ClockFn = () => Date\n\nlet clock: ClockFn = () => new Date()\n\n// internal only — not re-exported by index.ts/browser.ts. Contract-fixture\n// tests import this relative path directly to make record timestamps\n// deterministic without adding a public clock API.\nfunction now(): Date {\n return clock()\n}\n\nfunction setClockForTests(next: ClockFn | undefined): void {\n clock = next ?? (() => new Date())\n}\n\nexport { now, setClockForTests }\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'\n\nexport type LogFormat = 'auto' | 'json' | 'pretty'\n\nexport type LogAttributes = Record<string, unknown>\n\nexport interface NormalizedRecord {\n level: Exclude<LogLevel, 'silent'>\n msg: string\n scope?: string\n service?: string\n time: string\n [key: string]: unknown\n}\n\nexport const RESERVED_RECORD_FIELDS: ReadonlySet<string> = new Set([\n 'time',\n 'level',\n 'msg',\n 'service',\n 'scope',\n])\n","import {\n type LogAttributes,\n type LogLevel,\n type NormalizedRecord,\n RESERVED_RECORD_FIELDS,\n} from './types'\n\nconst MAX_DEPTH = 8\nconst MAX_STRING_BYTES = 16 * 1024\nconst MAX_COLLECTION_ITEMS = 100\nconst TRUNCATED_KEYS_FIELD = '_logging_truncated'\nconst MAX_DEPTH_MARKER = '[MaxDepth]'\nconst CIRCULAR_MARKER = '[Circular]'\nconst UNSERIALIZABLE_MARKER = '[Unserializable]'\nconst TRUNCATED_STRING_SUFFIX = '[Truncated]'\n\nconst stringEncoder = new TextEncoder()\nconst stringDecoder = new TextDecoder()\n\nconst truncateString = (value: string): string => {\n const bytes = stringEncoder.encode(value)\n if (bytes.length <= MAX_STRING_BYTES) return value\n\n const suffixBytes = stringEncoder.encode(TRUNCATED_STRING_SUFFIX)\n let cut = MAX_STRING_BYTES - suffixBytes.length\n // back off until we're not mid-way through a multi-byte UTF-8 sequence\n while (cut > 0 && (bytes[cut] & 0b1100_0000) === 0b1000_0000) cut--\n\n return (\n stringDecoder.decode(bytes.subarray(0, cut)) + TRUNCATED_STRING_SUFFIX\n )\n}\n\n// matches Go's byte-wise UTF-8 string comparison, which is codepoint order\nconst compareByCodePoint = (a: string, b: string): number => {\n const aChars = Array.from(a)\n const bChars = Array.from(b)\n const length = Math.min(aChars.length, bChars.length)\n for (let i = 0; i < length; i++) {\n const diff =\n (aChars[i].codePointAt(0) ?? 0) - (bChars[i].codePointAt(0) ?? 0)\n if (diff !== 0) return diff\n }\n return aChars.length - bChars.length\n}\n\nconst normalizeNumber = (value: number): unknown => {\n if (Number.isNaN(value)) return 'NaN'\n if (value === Number.POSITIVE_INFINITY) return 'Infinity'\n if (value === Number.NEGATIVE_INFINITY) return '-Infinity'\n return value\n}\n\nconst errorTypeName = (error: Error): string =>\n error.name || error.constructor?.name || 'Error'\n\nconst normalizeErrorCode = (\n code: unknown,\n depth: number,\n seen: Set<unknown>\n): unknown => {\n if (\n typeof code === 'string' ||\n typeof code === 'number' ||\n typeof code === 'bigint' ||\n typeof code === 'boolean'\n ) {\n return truncateString(String(code))\n }\n return normalizeValue(code, depth, seen)\n}\n\nconst normalizeError = (\n error: Error,\n depth: number,\n seen: Set<unknown>\n): unknown => {\n if (depth > MAX_DEPTH) return MAX_DEPTH_MARKER\n if (seen.has(error)) return CIRCULAR_MARKER\n seen.add(error)\n\n const result: Record<string, unknown> = {\n type: errorTypeName(error),\n message: truncateString(error.message),\n }\n\n const code = (error as { code?: unknown }).code\n if (code !== undefined)\n result.code = normalizeErrorCode(code, depth + 1, seen)\n\n if (typeof error.stack === 'string')\n result.stack = truncateString(error.stack)\n\n const cause = (error as { cause?: unknown }).cause\n if (cause !== undefined)\n result.cause = normalizeValue(cause, depth + 1, seen)\n\n const aggregateErrors = (error as { errors?: unknown }).errors\n if (Array.isArray(aggregateErrors)) {\n result.causes = aggregateErrors.map((entry) =>\n normalizeValue(entry, depth + 1, seen)\n )\n }\n\n seen.delete(error)\n return result\n}\n\nconst normalizeArray = (\n value: unknown[],\n depth: number,\n seen: Set<unknown>\n): unknown => {\n if (seen.has(value)) return CIRCULAR_MARKER\n seen.add(value)\n\n const length = value.length\n const upper = Math.min(length, MAX_COLLECTION_ITEMS)\n const items: unknown[] = []\n for (let i = 0; i < upper; i++) {\n try {\n items.push(normalizeValue(value[i], depth + 1, seen))\n } catch {\n items.push(UNSERIALIZABLE_MARKER)\n }\n }\n if (length > MAX_COLLECTION_ITEMS) {\n items.push(`[Truncated: ${length - MAX_COLLECTION_ITEMS} items]`)\n }\n\n seen.delete(value)\n return items\n}\n\nconst normalizeMap = (\n value: Map<unknown, unknown>,\n depth: number,\n seen: Set<unknown>\n): unknown => {\n if (seen.has(value)) return CIRCULAR_MARKER\n seen.add(value)\n\n const entries = Array.from(value.entries()).sort((a, b) =>\n compareByCodePoint(String(a[0]), String(b[0]))\n )\n const kept = entries.slice(0, MAX_COLLECTION_ITEMS)\n const result: Record<string, unknown> = {}\n for (const [key, entry] of kept) {\n const stringKey = String(key)\n try {\n result[stringKey] = normalizeValue(entry, depth + 1, seen)\n } catch {\n result[stringKey] = UNSERIALIZABLE_MARKER\n }\n }\n if (entries.length > kept.length) {\n result[TRUNCATED_KEYS_FIELD] = entries.length - kept.length\n }\n\n seen.delete(value)\n return result\n}\n\nconst normalizeObject = (\n value: Record<string, unknown>,\n depth: number,\n seen: Set<unknown>\n): unknown => {\n if (seen.has(value)) return CIRCULAR_MARKER\n seen.add(value)\n\n const keys = Object.keys(value).sort(compareByCodePoint)\n const kept = keys.slice(0, MAX_COLLECTION_ITEMS)\n const result: Record<string, unknown> = {}\n for (const key of kept) {\n try {\n result[key] = normalizeValue(value[key], depth + 1, seen)\n } catch {\n result[key] = UNSERIALIZABLE_MARKER\n }\n }\n if (keys.length > kept.length) {\n result[TRUNCATED_KEYS_FIELD] = keys.length - kept.length\n }\n\n seen.delete(value)\n return result\n}\n\nfunction normalizeValue(\n value: unknown,\n depth = 0,\n seen: Set<unknown> = new Set()\n): unknown {\n if (depth > MAX_DEPTH) return MAX_DEPTH_MARKER\n\n switch (typeof value) {\n case 'undefined':\n return undefined\n case 'string':\n return truncateString(value)\n case 'number':\n return normalizeNumber(value)\n case 'boolean':\n return value\n case 'bigint':\n return value.toString()\n case 'function':\n return '[Unsupported: function]'\n case 'symbol':\n return '[Unsupported: symbol]'\n }\n\n if (value === null) return null\n if (value instanceof Date) {\n const time = value.getTime()\n return Number.isNaN(time) ? UNSERIALIZABLE_MARKER : value.toISOString()\n }\n if (value instanceof Error) return normalizeError(value, depth, seen)\n if (Array.isArray(value)) return normalizeArray(value, depth, seen)\n if (value instanceof Map) return normalizeMap(value, depth, seen)\n if (value instanceof Set) return '[Unsupported: Set]'\n\n return normalizeObject(value as Record<string, unknown>, depth, seen)\n}\n\nconst describeErrorAttribute = (value: unknown): string => {\n if (value === null) return 'null'\n try {\n return truncateString(String(value))\n } catch {\n return UNSERIALIZABLE_MARKER\n }\n}\n\nconst normalizeErrorAttribute = (\n value: unknown,\n seen: Set<unknown>\n): unknown => {\n if (value instanceof Error) return normalizeError(value, 0, seen)\n return {\n type: typeof value,\n message: describeErrorAttribute(value),\n }\n}\n\nexport interface RawRecordInput {\n attributes?: LogAttributes\n level: Exclude<LogLevel, 'silent'>\n msg: string\n scope?: string\n service?: string\n time: Date\n}\n\nfunction normalizeRecord(input: RawRecordInput): NormalizedRecord {\n const seen = new Set<unknown>()\n const record: NormalizedRecord = {\n time: input.time.toISOString(),\n level: input.level,\n msg: truncateString(input.msg),\n }\n if (input.service) record.service = input.service\n if (input.scope) record.scope = input.scope\n\n const attributeKeys = Object.keys(input.attributes ?? {})\n .filter((key) => !RESERVED_RECORD_FIELDS.has(key))\n .sort(compareByCodePoint)\n\n for (const key of attributeKeys) {\n let value: unknown\n try {\n const raw = (input.attributes as LogAttributes)[key]\n value =\n key === 'error' && raw !== undefined\n ? normalizeErrorAttribute(raw, seen)\n : normalizeValue(raw, 0, seen)\n } catch {\n value = UNSERIALIZABLE_MARKER\n }\n // Go has no undefined — an attribute that normalizes to undefined\n // (only an explicit `undefined` value can) is dropped rather than\n // kept as a key JSON.stringify would otherwise silently omit anyway.\n if (value === undefined) continue\n record[key] = value\n }\n\n return record\n}\n\nexport { compareByCodePoint, normalizeRecord, normalizeValue }\n","import { compareByCodePoint } from './normalize'\nimport type { LogLevel, NormalizedRecord } from './types'\nimport { RESERVED_RECORD_FIELDS } from './types'\n\ninterface PrettyOptions {\n color?: boolean\n}\n\nconst ESC = String.fromCharCode(27)\nconst ANSI_RESET = `${ESC}[0m`\nconst ANSI_DIM = `${ESC}[2m`\nconst ANSI_BLUE = `${ESC}[34m`\nconst ANSI_YELLOW = `${ESC}[33m`\nconst ANSI_RED = `${ESC}[31m`\nconst ANSI_GREEN = `${ESC}[32m`\nconst ANSI_MAGENTA = `${ESC}[35m`\nconst ANSI_CYAN = `${ESC}[36m`\nconst ANSI_BOLD = `${ESC}[1m`\nconst ANSI_BOLD_GREEN = `${ESC}[1;32m`\nconst ANSI_BOLD_BLUE = `${ESC}[1;34m`\nconst ANSI_BOLD_YELLOW = `${ESC}[1;33m`\nconst ANSI_BOLD_CYAN = `${ESC}[1;36m`\nconst ANSI_BOLD_RED = `${ESC}[1;31m`\nconst ANSI_BOLD_DIM = `${ESC}[1;2m`\n\nconst UNSAFE_BARE_STRING = /[\\s\"'\\\\]/\nconst isControlCharCode = (code: number): boolean =>\n code <= 0x1f || code === 0x7f\n\nconst paint = (text: string, code: string): string =>\n `${code}${text}${ANSI_RESET}`\n\nconst levelColor = (level: Exclude<LogLevel, 'silent'>): string => {\n switch (level) {\n case 'debug':\n return ANSI_DIM\n case 'info':\n return ANSI_BLUE\n case 'warn':\n return ANSI_YELLOW\n case 'error':\n return ANSI_RED\n }\n}\n\nconst needsQuoting = (value: string): boolean => {\n if (value.length === 0) return true\n if (UNSAFE_BARE_STRING.test(value)) return true\n for (let i = 0; i < value.length; i++) {\n if (isControlCharCode(value.charCodeAt(i))) return true\n }\n return false\n}\n\nconst formatScalar = (value: unknown): string => {\n if (typeof value === 'string') {\n return needsQuoting(value) ? JSON.stringify(value) : value\n }\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value)\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n return JSON.stringify(value)\n}\n\n// escapes only the offending control byte (newline, ESC, etc.) using the same\n// JSON-string-escape representation attribute values already use, so a\n// literal newline or ESC byte can never split the physical line or inject\n// unowned ANSI — ordinary text stays bare\nconst sanitizeLineSegment = (value: string): string => {\n let result = ''\n for (let i = 0; i < value.length; i++) {\n const char = value[i]\n result += isControlCharCode(value.charCodeAt(i))\n ? JSON.stringify(char).slice(1, -1)\n : char\n }\n return result\n}\n\n// Object.keys/JSON.stringify hoist integer-index-like keys (\"2\", \"10\")\n// ahead of every other own key regardless of insertion order, so the\n// canonical field order can't be trusted to a single JSON.stringify(record)\n// call — each field is stringified and concatenated in explicit order\n// instead.\nconst attributeKeysOf = (record: NormalizedRecord): string[] =>\n Object.keys(record)\n .filter((key) => !RESERVED_RECORD_FIELDS.has(key))\n .sort(compareByCodePoint)\n\nfunction formatJSON(record: NormalizedRecord): string {\n const fields: string[] = []\n const appendField = (key: string, value: unknown): void => {\n fields.push(`${JSON.stringify(key)}:${JSON.stringify(value)}`)\n }\n\n appendField('time', record.time)\n appendField('level', record.level)\n appendField('msg', record.msg)\n if (record.service !== undefined) appendField('service', record.service)\n if (record.scope !== undefined) appendField('scope', record.scope)\n for (const key of attributeKeysOf(record)) {\n const value = record[key]\n // JSON has no undefined — JSON.stringify(undefined) returns the\n // value undefined, not a string, so appending it unguarded emits\n // the bare token `undefined` and breaks JSON.parse.\n if (value === undefined) continue\n appendField(key, value)\n }\n\n return `{${fields.join(',')}}\\n`\n}\n\nfunction formatPretty(\n record: NormalizedRecord,\n options: PrettyOptions = {}\n): string {\n const color = options.color ?? false\n const clock = record.time.slice(11, 23)\n\n const segments: string[] = [color ? paint(clock, ANSI_DIM) : clock]\n\n if (record.service) {\n const text = `[${sanitizeLineSegment(record.service)}]`\n segments.push(color ? paint(text, ANSI_MAGENTA) : text)\n }\n if (record.scope) {\n const text = `[${sanitizeLineSegment(record.scope)}]`\n segments.push(color ? paint(text, ANSI_CYAN) : text)\n }\n\n const levelText = record.level.toUpperCase().padEnd(5, ' ')\n segments.push(\n color ? paint(levelText, levelColor(record.level)) : levelText\n )\n\n let line = `${segments.join(' ')} ${sanitizeLineSegment(record.msg)}`\n\n for (const key of attributeKeysOf(record)) {\n const value = record[key]\n if (value === undefined) continue\n const rendered = formatScalar(value)\n const keyText = `${sanitizeLineSegment(key)}=`\n if (color) {\n const valueCode = attrValueColor(key, value, rendered)\n line += ` ${paint(keyText, ANSI_DIM)}${valueCode ? paint(rendered, valueCode) : rendered}`\n } else {\n line += ` ${keyText}${rendered}`\n }\n }\n\n return `${line}\\n`\n}\n\n// keeps the old dev styling: error values red, HTTP verbs bold, status by\n// class, duration by latency, correlation ids dim; '' leaves the value bare\nconst attrValueColor = (\n key: string,\n raw: unknown,\n rendered: string\n): string => {\n switch (key) {\n case 'error':\n return ANSI_RED\n case 'request_id':\n case 'trace_id':\n case 'span_id':\n return ANSI_DIM\n case 'method':\n switch (rendered) {\n case 'GET':\n return ANSI_BOLD_GREEN\n case 'POST':\n return ANSI_BOLD_BLUE\n case 'PUT':\n return ANSI_BOLD_YELLOW\n case 'PATCH':\n return ANSI_BOLD_CYAN\n case 'DELETE':\n return ANSI_BOLD_RED\n case 'HEAD':\n return ANSI_BOLD_DIM\n default:\n return ANSI_BOLD\n }\n case 'status':\n if (typeof raw === 'number') {\n if (raw < 300) return ANSI_GREEN\n if (raw < 400) return ANSI_CYAN\n if (raw < 500) return ANSI_YELLOW\n return ANSI_RED\n }\n return ''\n case 'duration_ms':\n if (typeof raw === 'number') {\n if (raw > 500) return ANSI_RED\n if (raw > 100) return ANSI_YELLOW\n return ANSI_DIM\n }\n return ''\n default:\n return ''\n }\n}\n\nexport { formatJSON, formatPretty }\n","import type { LogLevel } from './types'\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n}\n\nfunction enabledAt(\n level: Exclude<LogLevel, 'silent'>,\n threshold: LogLevel\n): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[threshold]\n}\n\nexport { enabledAt }\n","import type { LogAttributes } from './types'\n\nconst DEFAULT_REDACTED_KEYS = [\n 'password',\n 'passwd',\n 'secret',\n 'token',\n 'authorization',\n 'proxy_authorization',\n 'cookie',\n 'set_cookie',\n 'api_key',\n 'access_token',\n 'refresh_token',\n 'private_key',\n 'client_secret',\n]\n\nconst REDACTED_MARKER = '[REDACTED]'\n\nconst normalizeKey = (key: string): string =>\n key.toLowerCase().replace(/[^a-z0-9]/g, '')\n\nconst buildRedactedKeySet = (extra: readonly string[]): Set<string> => {\n const keys = new Set(DEFAULT_REDACTED_KEYS.map(normalizeKey))\n for (const key of extra) keys.add(normalizeKey(key))\n return keys\n}\n\nconst redactValue = (value: unknown, keys: Set<string>): unknown => {\n if (Array.isArray(value))\n return value.map((entry) => redactValue(entry, keys))\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, nested] of Object.entries(\n value as Record<string, unknown>\n )) {\n result[key] = keys.has(normalizeKey(key))\n ? REDACTED_MARKER\n : redactValue(nested, keys)\n }\n return result\n }\n return value\n}\n\nfunction redactRecord(\n record: LogAttributes,\n redact: readonly string[] = []\n): LogAttributes {\n const keys = buildRedactedKeySet(redact)\n return redactValue(record, keys) as LogAttributes\n}\n\nexport { redactRecord }\n","import { now } from './clock'\nimport { activeContext } from './context-seam'\nimport { formatJSON, formatPretty } from './format'\nimport { enabledAt } from './levels'\nimport { normalizeRecord, type RawRecordInput } from './normalize'\nimport { redactRecord } from './redact'\nimport { parseWindow, shouldEmitEvery, type Window } from './throttler'\nimport type {\n LogAttributes,\n LogFormat,\n LogLevel,\n NormalizedRecord,\n} from './types'\n\ntype LogOutput = (line: string) => void\n\ninterface RateLimited {\n debug(message: string, attributes?: LogAttributes): void\n error(message: string, attributes?: LogAttributes): void\n info(message: string, attributes?: LogAttributes): void\n warn(message: string, attributes?: LogAttributes): void\n}\n\ninterface LoggerOptions {\n bindings?: LogAttributes\n colors?: 'auto' | boolean\n format?: LogFormat\n level?: LogLevel\n onInternalError?: (error: unknown) => void\n output?: LogOutput\n redact?: readonly string[]\n scope?: string\n service?: string\n}\n\ninterface Logger {\n debug(message: string, attributes?: LogAttributes): void\n enabled(level: Exclude<LogLevel, 'silent'>): boolean\n error(message: string, attributes?: LogAttributes): void\n every(window: Window, ...keyParts: string[]): RateLimited\n info(message: string, attributes?: LogAttributes): void\n warn(message: string, attributes?: LogAttributes): void\n with(bindings: LogAttributes): Logger\n}\n\ninterface EngineConfig {\n bindings: LogAttributes\n colors: boolean\n format: Exclude<LogFormat, 'auto'>\n level: LogLevel\n onInternalError?: (error: unknown) => void\n output: LogOutput\n redact: readonly string[]\n scope?: string\n service?: string\n stderrWrite: (message: string) => void\n}\n\nconst bindingsByLogger = new WeakMap<Logger, LogAttributes>()\n\nconst describeError = (error: unknown): string =>\n error instanceof Error ? (error.stack ?? error.message) : String(error)\n\nfunction reportInternalError(config: EngineConfig, error: unknown): void {\n if (config.onInternalError) {\n try {\n config.onInternalError(error)\n } catch {\n // the callback itself failed — nothing left to notify\n }\n return\n }\n try {\n config.stderrWrite(\n `@ekkolyth/logging: internal error — ${describeError(error)}\\n`\n )\n } catch {\n // stderr also failed — give up\n }\n}\n\nfunction buildEngine(config: EngineConfig): Logger {\n const emit = (\n level: Exclude<LogLevel, 'silent'>,\n msg: string,\n attributes?: LogAttributes\n ): void => {\n if (!enabledAt(level, config.level)) return\n\n let line: string\n try {\n const raw: RawRecordInput = {\n attributes: {\n ...config.bindings,\n ...activeContext(),\n ...attributes,\n },\n level,\n msg,\n scope: config.scope,\n service: config.service,\n time: now(),\n }\n const redacted = redactRecord(\n normalizeRecord(raw),\n config.redact\n ) as NormalizedRecord\n line =\n config.format === 'json'\n ? formatJSON(redacted)\n : formatPretty(redacted, { color: config.colors })\n } catch (error) {\n reportInternalError(config, error)\n return\n }\n\n try {\n config.output(line)\n } catch (error) {\n reportInternalError(config, error)\n }\n }\n\n // suppression key matches the pre-rewrite package: service, scope, and\n // any caller key parts, then level + msg inside shouldEmitEvery\n const every = (window: Window, ...keyParts: string[]): RateLimited => {\n const windowMs = parseWindow(window)\n const key = [config.service ?? '', config.scope ?? '', ...keyParts]\n .filter(Boolean)\n .join('|')\n const gated =\n (level: Exclude<LogLevel, 'silent'>) =>\n (message: string, attributes?: LogAttributes) => {\n if (!shouldEmitEvery(level, windowMs, key, message)) return\n emit(level, message, attributes)\n }\n return {\n debug: gated('debug'),\n error: gated('error'),\n info: gated('info'),\n warn: gated('warn'),\n }\n }\n\n const logger: Logger = {\n debug: (message, attributes) => emit('debug', message, attributes),\n enabled: (level) => enabledAt(level, config.level),\n error: (message, attributes) => emit('error', message, attributes),\n every,\n info: (message, attributes) => emit('info', message, attributes),\n warn: (message, attributes) => emit('warn', message, attributes),\n with: (bindings) =>\n buildEngine({\n ...config,\n bindings: { ...config.bindings, ...bindings },\n }),\n }\n\n bindingsByLogger.set(logger, config.bindings)\n return logger\n}\n\n// internal only — not re-exported by index.ts/browser.ts; the HTTP module\n// reads a logger's own bindings through this relative import\nfunction getBindings(logger: Logger): Readonly<LogAttributes> {\n return { ...(bindingsByLogger.get(logger) ?? {}) }\n}\n\nexport type { EngineConfig, Logger, LoggerOptions, LogOutput, RateLimited }\nexport { buildEngine, getBindings }\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as LogFormat, r as LogLevel, t as LogAttributes } from "./types-CieIrR8p.js";
|
|
2
|
+
//#region src/throttler.d.ts
|
|
3
|
+
type Window = number | `${number}ms` | `${number}s` | `${number}m` | `${number}h`;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/logger.d.ts
|
|
6
|
+
type LogOutput = (line: string) => void;
|
|
7
|
+
interface RateLimited {
|
|
8
|
+
debug(message: string, attributes?: LogAttributes): void;
|
|
9
|
+
error(message: string, attributes?: LogAttributes): void;
|
|
10
|
+
info(message: string, attributes?: LogAttributes): void;
|
|
11
|
+
warn(message: string, attributes?: LogAttributes): void;
|
|
12
|
+
}
|
|
13
|
+
interface LoggerOptions {
|
|
14
|
+
bindings?: LogAttributes;
|
|
15
|
+
colors?: 'auto' | boolean;
|
|
16
|
+
format?: LogFormat;
|
|
17
|
+
level?: LogLevel;
|
|
18
|
+
onInternalError?: (error: unknown) => void;
|
|
19
|
+
output?: LogOutput;
|
|
20
|
+
redact?: readonly string[];
|
|
21
|
+
scope?: string;
|
|
22
|
+
service?: string;
|
|
23
|
+
}
|
|
24
|
+
interface Logger {
|
|
25
|
+
debug(message: string, attributes?: LogAttributes): void;
|
|
26
|
+
enabled(level: Exclude<LogLevel, 'silent'>): boolean;
|
|
27
|
+
error(message: string, attributes?: LogAttributes): void;
|
|
28
|
+
every(window: Window, ...keyParts: string[]): RateLimited;
|
|
29
|
+
info(message: string, attributes?: LogAttributes): void;
|
|
30
|
+
warn(message: string, attributes?: LogAttributes): void;
|
|
31
|
+
with(bindings: LogAttributes): Logger;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Window as a, RateLimited as i, Logger as n, LoggerOptions as r, LogOutput as t };
|
|
35
|
+
//# sourceMappingURL=logger-V7XF9Wuo.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/http/outbound.d.ts
|
|
2
|
+
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
interface FetchOptions {
|
|
4
|
+
provider?: string;
|
|
5
|
+
sampleRate?: number;
|
|
6
|
+
slowThresholdMs?: number;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { FetchOptions as n, FetchLike as t };
|
|
10
|
+
//# sourceMappingURL=outbound-CQkyIyxd.d.ts.map
|