logixia 2.0.7 → 2.0.9
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 +10 -1
- package/dist/{builder-C_TgxEOW.mjs → builder-BlIJNIuk.mjs} +221 -82
- package/dist/builder-BlIJNIuk.mjs.map +1 -0
- package/dist/{builder-CzmM_4Ub.js → builder-Bs0qkfkY.js} +226 -82
- package/dist/builder-Bs0qkfkY.js.map +1 -0
- package/dist/index.d.mts +9 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.mjs +2 -2
- package/dist/{logitron-logger-Qh3y9-WH.d.ts → logitron-logger-DVUdgmBY.d.ts} +20 -1
- package/dist/logitron-logger-DVUdgmBY.d.ts.map +1 -0
- package/dist/{logitron-logger-sYuk8fOb.d.mts → logitron-logger-DoWmMjYB.d.mts} +20 -1
- package/dist/logitron-logger-DoWmMjYB.d.mts.map +1 -0
- package/dist/nest.d.mts +1 -1
- package/dist/nest.d.ts +1 -1
- package/dist/nest.js +1 -1
- package/dist/nest.mjs +1 -1
- package/package.json +1 -2
- package/dist/builder-C_TgxEOW.mjs.map +0 -1
- package/dist/builder-CzmM_4Ub.js.map +0 -1
- package/dist/logitron-logger-Qh3y9-WH.d.ts.map +0 -1
- package/dist/logitron-logger-sYuk8fOb.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Most Node loggers give you a fast `info()` and leave the rest to you. logixia ke
|
|
|
35
35
|
- **Transports for real destinations.** Console, rotating files, PostgreSQL, MySQL, MongoDB, SQLite, CloudWatch, Google Cloud Logging, Azure Monitor, Datadog, OTLP, Slack, Discord, and a worker-thread wrapper. Several can run on one log call.
|
|
36
36
|
- **OpenTelemetry-native.** Read the active span for trace/log correlation, or export logs as OTLP/HTTP records. The OTLP transport builds the JSON itself, so no `@opentelemetry/*` SDK is required to emit logs.
|
|
37
37
|
- **Runs outside Node too.** `logixia/browser` has no Node built-ins and is written for browsers and edge runtimes such as Cloudflare Workers.
|
|
38
|
-
- **Small footprint.**
|
|
38
|
+
- **Small footprint.** Two runtime dependencies (`commander`, `picocolors`), no install scripts, ESM and CommonJS builds with types.
|
|
39
39
|
|
|
40
40
|
Log calls are `async` and transport failures are caught internally, so a full disk or a flaky database does not crash your process.
|
|
41
41
|
|
|
@@ -81,6 +81,13 @@ Output (colors omitted, stack trace shortened):
|
|
|
81
81
|
[2026-10-30T14:24:30.625Z] [ERROR] [api] [ec339fb5-5afb-4675-8c39-ecbad4353818] Connection timeout {"orderId":"ord_123","error":{"name":"Error","message":"Connection timeout","stack":"Error: Connection timeout\n at main (...)"}}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
Errors can also sit in a field, in a nested object or in an array. They keep their name, message, stack, `cause` and extra fields such as `code`, up to three levels down:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
await logger.error('Payment failed', { orderId: 'ord_123', error: new Error('Card declined') });
|
|
88
|
+
// → {"orderId":"ord_123","error":{"name":"Error","message":"Card declined","stack":"Error: Card declined..."}}
|
|
89
|
+
```
|
|
90
|
+
|
|
84
91
|
Without a `transports` key logs go to the console. Add `transports` to write to files, databases or cloud services, all concurrently. There is also a ready-made default instance: `import { logger } from 'logixia'`.
|
|
85
92
|
|
|
86
93
|
→ [Getting started](https://logixia.github.io/logixia/guide/getting-started) · [Configuration](https://logixia.github.io/logixia/guide/configuration) · [Log levels](https://logixia.github.io/logixia/guide/log-levels)
|
|
@@ -150,6 +157,8 @@ await logger.info('Login', { user: 'alice', password: 'hunter2' });
|
|
|
150
157
|
|
|
151
158
|
Paths support `*` (one segment) and `**` (any depth), match case-insensitively, and the input object is never mutated. Circular references are printed as `[Circular]`.
|
|
152
159
|
|
|
160
|
+
An error's stack repeats its message, so to hide a message by path, list both `error.message` and `error.stack`, or use a pattern, which covers both.
|
|
161
|
+
|
|
153
162
|
→ [Redaction](https://logixia.github.io/logixia/guide/redaction)
|
|
154
163
|
|
|
155
164
|
### Transports
|
|
@@ -6,7 +6,6 @@ import { n as internalLog, r as internalWarn, t as internalError } from "./inter
|
|
|
6
6
|
import { t as safeToString } from "./coerce.utils-B_rEudCn.mjs";
|
|
7
7
|
import { i as stringifyForLog } from "./safe-stringify--7gbe95n.mjs";
|
|
8
8
|
import { c as TransportManager, n as _getOtelPayloadIfEnabled, r as _isOtelBridgeEnabled, v as stripControlChars } from "./otel-DOuwGPCd.mjs";
|
|
9
|
-
import buildFastStringify from "fast-json-stringify";
|
|
10
9
|
import { constants } from "node:os";
|
|
11
10
|
// src/types/index.ts
|
|
12
11
|
const LogLevel = {
|
|
@@ -194,6 +193,16 @@ const EXTRA_FIELDS = [
|
|
|
194
193
|
"port",
|
|
195
194
|
"type"
|
|
196
195
|
];
|
|
196
|
+
const SKIPPED_FIELDS = /* @__PURE__ */ new Set([
|
|
197
|
+
"name",
|
|
198
|
+
"message",
|
|
199
|
+
"stack",
|
|
200
|
+
"cause",
|
|
201
|
+
"errors",
|
|
202
|
+
...EXTRA_FIELDS
|
|
203
|
+
]);
|
|
204
|
+
const NO_OPTIONS = Object.freeze({});
|
|
205
|
+
const NO_FIELDS = [];
|
|
197
206
|
/**
|
|
198
207
|
* Serialize an Error into a plain JSON-safe object, including:
|
|
199
208
|
* - `name`, `message`, `stack`
|
|
@@ -202,8 +211,8 @@ const EXTRA_FIELDS = [
|
|
|
202
211
|
* - standard Node.js error fields (`code`, `statusCode`, `errno`, …)
|
|
203
212
|
* - any other enumerable own properties
|
|
204
213
|
*/
|
|
205
|
-
function serializeError(error, options =
|
|
206
|
-
const { includeStack = true, maxDepth = 5, excludeFields =
|
|
214
|
+
function serializeError(error, options = NO_OPTIONS) {
|
|
215
|
+
const { includeStack = true, maxDepth = 5, excludeFields = NO_FIELDS } = options;
|
|
207
216
|
return _serializeError(error, includeStack, maxDepth, excludeFields, 0, /* @__PURE__ */ new WeakSet());
|
|
208
217
|
}
|
|
209
218
|
function _serializeError(error, includeStack, maxDepth, excludeFields, depth, seen) {
|
|
@@ -231,16 +240,8 @@ function _serializeError(error, includeStack, maxDepth, excludeFields, depth, se
|
|
|
231
240
|
const aggregateError = error;
|
|
232
241
|
if (Array.isArray(aggregateError.errors)) serialized.errors = aggregateError.errors.map((e) => e instanceof Error ? _serializeError(e, includeStack, maxDepth, excludeFields, depth + 1, seen) : serializeValue(e, maxDepth - depth - 1, seen));
|
|
233
242
|
const errorRecord = error;
|
|
234
|
-
for (const field of EXTRA_FIELDS) if (!excludeFields.includes(field) &&
|
|
235
|
-
const skip = /* @__PURE__ */ new Set([
|
|
236
|
-
"name",
|
|
237
|
-
"message",
|
|
238
|
-
"stack",
|
|
239
|
-
"cause",
|
|
240
|
-
"errors",
|
|
241
|
-
...EXTRA_FIELDS,
|
|
242
|
-
...excludeFields
|
|
243
|
-
]);
|
|
243
|
+
for (const field of EXTRA_FIELDS) if (!excludeFields.includes(field) && errorRecord[field] !== void 0) serialized[field] = errorRecord[field];
|
|
244
|
+
const skip = excludeFields.length === 0 ? SKIPPED_FIELDS : /* @__PURE__ */ new Set([...SKIPPED_FIELDS, ...excludeFields]);
|
|
244
245
|
for (const key of Object.getOwnPropertyNames(error)) {
|
|
245
246
|
if (skip.has(key)) continue;
|
|
246
247
|
try {
|
|
@@ -296,6 +297,61 @@ function serializeValue(value, remainingDepth, seen) {
|
|
|
296
297
|
function isError(value) {
|
|
297
298
|
return value instanceof Error || Boolean(value) && typeof value === "object" && "name" in value && "message" in value;
|
|
298
299
|
}
|
|
300
|
+
const MAX_ERROR_SEARCH_DEPTH = 3;
|
|
301
|
+
const MAX_ERROR_SEARCH_NODES = 2e3;
|
|
302
|
+
/**
|
|
303
|
+
* Replaces real Error instances inside a log payload with their serialized form,
|
|
304
|
+
* because JSON output drops an Error's non-enumerable `message` and `stack`. Runs on
|
|
305
|
+
* every log call, so its work is capped and it copies nothing until it finds one.
|
|
306
|
+
* Duck-typed objects are data, and an Error with its own toJSON has already chosen
|
|
307
|
+
* what to show. The caller's objects are never mutated.
|
|
308
|
+
*/
|
|
309
|
+
function serializeNestedErrors(data) {
|
|
310
|
+
const outerBudget = errorSearchBudget;
|
|
311
|
+
errorSearchBudget = MAX_ERROR_SEARCH_NODES;
|
|
312
|
+
try {
|
|
313
|
+
return walkForErrors(data, MAX_ERROR_SEARCH_DEPTH, void 0, void 0);
|
|
314
|
+
} finally {
|
|
315
|
+
errorSearchBudget = outerBudget;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
let errorSearchBudget = 0;
|
|
319
|
+
const hasOwn = Object.prototype.hasOwnProperty;
|
|
320
|
+
function walkForErrors(value, depth, parent, grandparent) {
|
|
321
|
+
if (value instanceof Error) return typeof value.toJSON === "function" ? value : serializeError(value);
|
|
322
|
+
if (depth === 0 || --errorSearchBudget < 0 || value === parent || value === grandparent) return value;
|
|
323
|
+
let copy;
|
|
324
|
+
if (Array.isArray(value)) for (let i = 0; i < value.length; i++) {
|
|
325
|
+
const item = value[i];
|
|
326
|
+
if (item === null || typeof item !== "object") continue;
|
|
327
|
+
const next = walkForErrors(item, depth - 1, value, parent);
|
|
328
|
+
if (next !== item) {
|
|
329
|
+
copy ??= value.slice();
|
|
330
|
+
copy[i] = next;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
const proto = Object.getPrototypeOf(value);
|
|
335
|
+
if (proto !== Object.prototype && proto !== null) return value;
|
|
336
|
+
const record = value;
|
|
337
|
+
for (const key in record) {
|
|
338
|
+
if (!hasOwn.call(record, key)) continue;
|
|
339
|
+
let item;
|
|
340
|
+
try {
|
|
341
|
+
item = record[key];
|
|
342
|
+
} catch {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (item === null || typeof item !== "object") continue;
|
|
346
|
+
const next = walkForErrors(item, depth - 1, record, parent);
|
|
347
|
+
if (next !== item) {
|
|
348
|
+
copy ??= { ...record };
|
|
349
|
+
assignOwn(copy, key, next);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return copy ?? value;
|
|
354
|
+
}
|
|
299
355
|
/**
|
|
300
356
|
* Coerce any thrown value into a proper Error instance.
|
|
301
357
|
*/
|
|
@@ -978,23 +1034,6 @@ function warnOnReservedLevelNames(levels) {
|
|
|
978
1034
|
* - Feature 4: Cause-chain error serialization (handled in error.utils)
|
|
979
1035
|
* - Feature 5: Adaptive log level based on NODE_ENV / CI detection
|
|
980
1036
|
*/
|
|
981
|
-
const _fastStringifyEntry = buildFastStringify({
|
|
982
|
-
type: "object",
|
|
983
|
-
properties: {
|
|
984
|
-
timestamp: { type: "string" },
|
|
985
|
-
level: { type: "string" },
|
|
986
|
-
appName: { type: "string" },
|
|
987
|
-
environment: { type: "string" },
|
|
988
|
-
message: { type: "string" },
|
|
989
|
-
context: { type: "string" },
|
|
990
|
-
traceId: { type: "string" },
|
|
991
|
-
payload: {
|
|
992
|
-
type: "object",
|
|
993
|
-
additionalProperties: true
|
|
994
|
-
}
|
|
995
|
-
},
|
|
996
|
-
additionalProperties: true
|
|
997
|
-
});
|
|
998
1037
|
let _tsCacheMs = 0;
|
|
999
1038
|
let _tsCacheStr = "";
|
|
1000
1039
|
function nowIso() {
|
|
@@ -1005,6 +1044,39 @@ function nowIso() {
|
|
|
1005
1044
|
}
|
|
1006
1045
|
return _tsCacheStr;
|
|
1007
1046
|
}
|
|
1047
|
+
const RESOLVED = Promise.resolve();
|
|
1048
|
+
const JSON_STRING_FIELDS = [
|
|
1049
|
+
"timestamp",
|
|
1050
|
+
"level",
|
|
1051
|
+
"appName",
|
|
1052
|
+
"environment",
|
|
1053
|
+
"message",
|
|
1054
|
+
"context",
|
|
1055
|
+
"traceId"
|
|
1056
|
+
];
|
|
1057
|
+
function toJsonString(value) {
|
|
1058
|
+
if (value === null) return "";
|
|
1059
|
+
if (value instanceof Date) return value.toISOString();
|
|
1060
|
+
if (value instanceof RegExp) return value.source;
|
|
1061
|
+
return String(value);
|
|
1062
|
+
}
|
|
1063
|
+
function toJsonEntry(entry) {
|
|
1064
|
+
const record = entry;
|
|
1065
|
+
let copy;
|
|
1066
|
+
for (const field of JSON_STRING_FIELDS) {
|
|
1067
|
+
const value = record[field];
|
|
1068
|
+
if (value !== void 0 && typeof value !== "string") {
|
|
1069
|
+
copy ??= { ...record };
|
|
1070
|
+
copy[field] = toJsonString(value);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
const payload = entry.payload;
|
|
1074
|
+
if (payload !== void 0 && (payload === null || typeof payload !== "object" || Array.isArray(payload))) {
|
|
1075
|
+
copy ??= { ...record };
|
|
1076
|
+
copy["payload"] = Object.assign({}, payload);
|
|
1077
|
+
}
|
|
1078
|
+
return copy ?? entry;
|
|
1079
|
+
}
|
|
1008
1080
|
function namespacePatternToRegex(pattern) {
|
|
1009
1081
|
const escaped = pattern.split(".").map((s) => s === "*" ? "[^.]+" : s.replace(/[$()*+.?[\\\]^{|}]/g, "\\$&")).join("\\.");
|
|
1010
1082
|
return new RegExp(`^${escaped}$`);
|
|
@@ -1086,6 +1158,11 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1086
1158
|
this._hasContextData = false;
|
|
1087
1159
|
this._formattedLevels = /* @__PURE__ */ new Map();
|
|
1088
1160
|
this._formattedAppName = "";
|
|
1161
|
+
this._jsonHeads = /* @__PURE__ */ new Map();
|
|
1162
|
+
this._jsonHeadsApp = "";
|
|
1163
|
+
this._jsonHeadsEnv = "";
|
|
1164
|
+
this._jsonContextKey = void 0;
|
|
1165
|
+
this._jsonContext = "";
|
|
1089
1166
|
this._hasRedact = false;
|
|
1090
1167
|
this._nsSeenVersion = 0;
|
|
1091
1168
|
this._parent = parent;
|
|
@@ -1186,9 +1263,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1186
1263
|
var _this$config$levelOpt3, _this$config$levelOpt4;
|
|
1187
1264
|
warnOnReservedLevelNames((_this$config$levelOpt3 = this.config.levelOptions) === null || _this$config$levelOpt3 === void 0 ? void 0 : _this$config$levelOpt3.levels);
|
|
1188
1265
|
if ((_this$config$levelOpt4 = this.config.levelOptions) === null || _this$config$levelOpt4 === void 0 ? void 0 : _this$config$levelOpt4.levels) {
|
|
1189
|
-
for (const levelName of Object.keys(this.config.levelOptions.levels)) if (!this[levelName.toLowerCase()]) this[levelName.toLowerCase()] =
|
|
1190
|
-
await this.logLevel(levelName.toLowerCase(), message, data);
|
|
1191
|
-
};
|
|
1266
|
+
for (const levelName of Object.keys(this.config.levelOptions.levels)) if (!this[levelName.toLowerCase()]) this[levelName.toLowerCase()] = (message, data) => this.logLevel(levelName.toLowerCase(), message, data);
|
|
1192
1267
|
}
|
|
1193
1268
|
}
|
|
1194
1269
|
/**
|
|
@@ -1290,40 +1365,53 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1290
1365
|
* (name, message, stack) under `data.error`; a string is logged as-is.
|
|
1291
1366
|
* `data` is merged into the entry payload.
|
|
1292
1367
|
*/
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1368
|
+
error(messageOrError, data) {
|
|
1369
|
+
try {
|
|
1370
|
+
return isError(messageOrError) ? this._run("error", messageOrError.message, {
|
|
1371
|
+
...data,
|
|
1372
|
+
error: serializeError(messageOrError)
|
|
1373
|
+
}) : this._run("error", messageOrError, data);
|
|
1374
|
+
} catch (error) {
|
|
1375
|
+
return Promise.reject(error);
|
|
1376
|
+
}
|
|
1299
1377
|
}
|
|
1300
1378
|
/** Log `message` at `warn` level; `data` is merged into the entry payload. */
|
|
1301
|
-
|
|
1302
|
-
|
|
1379
|
+
warn(message, data) {
|
|
1380
|
+
return this._run("warn", message, data);
|
|
1303
1381
|
}
|
|
1304
1382
|
/** Log `message` at `info` level; `data` is merged into the entry payload. */
|
|
1305
|
-
|
|
1306
|
-
|
|
1383
|
+
info(message, data) {
|
|
1384
|
+
return this._run("info", message, data);
|
|
1307
1385
|
}
|
|
1308
1386
|
/** Log `message` at `debug` level; `data` is merged into the entry payload. */
|
|
1309
|
-
|
|
1310
|
-
|
|
1387
|
+
debug(message, data) {
|
|
1388
|
+
return this._run("debug", message, data);
|
|
1311
1389
|
}
|
|
1312
1390
|
/** Log `message` at `trace` level; `data` is merged into the entry payload. */
|
|
1313
|
-
|
|
1314
|
-
|
|
1391
|
+
trace(message, data) {
|
|
1392
|
+
return this._run("trace", message, data);
|
|
1315
1393
|
}
|
|
1316
1394
|
/** Log `message` at `verbose` level; `data` is merged into the entry payload. */
|
|
1317
|
-
|
|
1318
|
-
|
|
1395
|
+
verbose(message, data) {
|
|
1396
|
+
return this._run("verbose", message, data);
|
|
1319
1397
|
}
|
|
1320
1398
|
/**
|
|
1321
1399
|
* Log at an arbitrary level name, including custom levels. Levels below the
|
|
1322
1400
|
* active threshold are dropped, as are level names that are not registered
|
|
1323
1401
|
* in `levelOptions.levels` (and are not built-in).
|
|
1324
1402
|
*/
|
|
1325
|
-
|
|
1326
|
-
|
|
1403
|
+
logLevel(level, message, data) {
|
|
1404
|
+
return this._run(level, message, data);
|
|
1405
|
+
}
|
|
1406
|
+
_run(level, message, data) {
|
|
1407
|
+
try {
|
|
1408
|
+
return this._settle(this.log(level, message, data));
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
return Promise.reject(error);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
_settle(out) {
|
|
1414
|
+
return out ?? RESOLVED;
|
|
1327
1415
|
}
|
|
1328
1416
|
/** Start a named timer; finish it with {@link timeEnd}. Reusing a label restarts it. */
|
|
1329
1417
|
time(label) {
|
|
@@ -1629,12 +1717,15 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1629
1717
|
await this._pluginRegistry.runOnShutdown();
|
|
1630
1718
|
deregisterFromShutdown(this);
|
|
1631
1719
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1720
|
+
/** Returns a Promise only when a plugin or a transport is asynchronous. */
|
|
1721
|
+
log(level, message, rawData) {
|
|
1722
|
+
const config = this.config;
|
|
1723
|
+
if (config.silent) return;
|
|
1634
1724
|
if (!this.shouldLog(level)) return;
|
|
1725
|
+
const data = rawData instanceof Error ? { error: serializeError(rawData) } : rawData;
|
|
1635
1726
|
const alsContext = LogixiaContext.get();
|
|
1636
1727
|
let activeTraceId;
|
|
1637
|
-
if (
|
|
1728
|
+
if (config.traceId) {
|
|
1638
1729
|
const ctxTraceId = alsContext === null || alsContext === void 0 ? void 0 : alsContext.traceId;
|
|
1639
1730
|
activeTraceId = TraceContext.instance.getCurrentTraceId() ?? (typeof ctxTraceId === "string" ? ctxTraceId : void 0);
|
|
1640
1731
|
}
|
|
@@ -1642,7 +1733,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1642
1733
|
const hasAls = alsContext !== void 0 && Object.keys(alsContext).length > 0;
|
|
1643
1734
|
const otelFields = _isOtelBridgeEnabled() ? _getOtelPayloadIfEnabled() : void 0;
|
|
1644
1735
|
const hasOtel = otelFields !== void 0 && Object.keys(otelFields).length > 0;
|
|
1645
|
-
const traceId =
|
|
1736
|
+
const traceId = config.traceId ? activeTraceId ?? this.fallbackTraceId : void 0;
|
|
1646
1737
|
let mergedData;
|
|
1647
1738
|
if (hasAls) {
|
|
1648
1739
|
const als = { ...alsContext };
|
|
@@ -1657,14 +1748,19 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1657
1748
|
...data
|
|
1658
1749
|
};
|
|
1659
1750
|
else mergedData = data;
|
|
1660
|
-
|
|
1751
|
+
let rawPayload = this._hasContextData ? {
|
|
1661
1752
|
...this.contextData,
|
|
1662
1753
|
...mergedData
|
|
1663
1754
|
} : mergedData;
|
|
1755
|
+
if (rawPayload) try {
|
|
1756
|
+
rawPayload = serializeNestedErrors(rawPayload);
|
|
1757
|
+
} catch (error) {
|
|
1758
|
+
internalError("Error serialization failed", error);
|
|
1759
|
+
}
|
|
1664
1760
|
let payload;
|
|
1665
1761
|
if (rawPayload !== void 0 && rawPayload !== null) {
|
|
1666
1762
|
if (this._hasRedact) try {
|
|
1667
|
-
payload = applyRedaction(rawPayload,
|
|
1763
|
+
payload = applyRedaction(rawPayload, config.redact) ?? rawPayload;
|
|
1668
1764
|
} catch (error) {
|
|
1669
1765
|
internalError("Redaction failed", error);
|
|
1670
1766
|
payload = { redaction: REDACTION_FAILED };
|
|
@@ -1673,7 +1769,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1673
1769
|
}
|
|
1674
1770
|
let safeMessage = message;
|
|
1675
1771
|
if (this._hasRedact) try {
|
|
1676
|
-
safeMessage = applyRedactionToString(message,
|
|
1772
|
+
safeMessage = applyRedactionToString(message, config.redact);
|
|
1677
1773
|
} catch (error) {
|
|
1678
1774
|
internalError("Redaction failed", error);
|
|
1679
1775
|
safeMessage = REDACTION_FAILED;
|
|
@@ -1681,20 +1777,20 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1681
1777
|
const entry = {
|
|
1682
1778
|
timestamp: nowIso(),
|
|
1683
1779
|
level,
|
|
1684
|
-
appName:
|
|
1685
|
-
environment:
|
|
1780
|
+
appName: config.appName ?? "App",
|
|
1781
|
+
environment: config.environment ?? "development",
|
|
1686
1782
|
message: safeMessage
|
|
1687
1783
|
};
|
|
1688
1784
|
if (this.context) entry.context = this.context;
|
|
1689
|
-
if (payload !== void 0) entry.payload = payload;
|
|
1690
1785
|
if (traceId !== void 0) entry.traceId = traceId;
|
|
1691
|
-
|
|
1692
|
-
if (this._pluginRegistry.size > 0)
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
const
|
|
1697
|
-
if (
|
|
1786
|
+
if (payload !== void 0) entry.payload = payload;
|
|
1787
|
+
if (this._pluginRegistry.size > 0) return this._logThroughPlugins(entry, level);
|
|
1788
|
+
return this.output(entry, level);
|
|
1789
|
+
}
|
|
1790
|
+
async _logThroughPlugins(entry, level) {
|
|
1791
|
+
const finalEntry = await this._pluginRegistry.runOnLog(entry);
|
|
1792
|
+
if (finalEntry === null) return;
|
|
1793
|
+
await this.output(finalEntry, level);
|
|
1698
1794
|
}
|
|
1699
1795
|
/**
|
|
1700
1796
|
* Hot-path level check: a single Map lookup + integer compare.
|
|
@@ -1736,19 +1832,27 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1736
1832
|
return this.getLevel();
|
|
1737
1833
|
}
|
|
1738
1834
|
formatLog(entry) {
|
|
1739
|
-
|
|
1740
|
-
if (
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1835
|
+
const format = this.config.format;
|
|
1836
|
+
if (format === null || format === void 0 ? void 0 : format.json) {
|
|
1837
|
+
if (this._pluginRegistry.size === 0) try {
|
|
1838
|
+
const line = this._buildJsonLine(entry);
|
|
1839
|
+
if (line !== void 0) return line;
|
|
1840
|
+
} catch {}
|
|
1841
|
+
let jsonEntry = entry;
|
|
1842
|
+
try {
|
|
1843
|
+
jsonEntry = toJsonEntry(entry);
|
|
1844
|
+
return JSON.stringify(jsonEntry);
|
|
1845
|
+
} catch {
|
|
1846
|
+
return stringifyForLog(jsonEntry);
|
|
1847
|
+
}
|
|
1744
1848
|
}
|
|
1745
1849
|
let formatted = "";
|
|
1746
|
-
const doColorize = (
|
|
1850
|
+
const doColorize = (format === null || format === void 0 ? void 0 : format.colorize) ?? true;
|
|
1747
1851
|
const gray = doColorize ? this._colorMap.get("gray") : "";
|
|
1748
1852
|
const cyan = doColorize ? this._colorMap.get("cyan") : "";
|
|
1749
1853
|
const yellow = doColorize ? this._colorMap.get("yellow") : "";
|
|
1750
1854
|
const reset = doColorize ? this._colorMap.get("reset") : "";
|
|
1751
|
-
if ((
|
|
1855
|
+
if ((format === null || format === void 0 ? void 0 : format.timestamp) !== false && this._fieldCache.get("timestamp") !== false) formatted += `${gray}[${entry.timestamp}]${reset} `;
|
|
1752
1856
|
if (this._fieldCache.get("level") !== false) formatted += this._formattedLevels.get(entry.level) ?? `[${entry.level.toUpperCase()}] `;
|
|
1753
1857
|
formatted += this._formattedAppName;
|
|
1754
1858
|
if (entry.traceId && this._fieldCache.get("traceId") !== false) formatted += `${cyan}[${stripControlChars(String(entry.traceId))}]${reset} `;
|
|
@@ -1757,9 +1861,46 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1757
1861
|
if (entry.payload !== void 0 && this._fieldCache.get("payload") !== false) formatted += ` ${stringifyForLog(entry.payload)}`;
|
|
1758
1862
|
return formatted;
|
|
1759
1863
|
}
|
|
1864
|
+
/**
|
|
1865
|
+
* The same bytes JSON.stringify(entry) gives for an entry log() built, without
|
|
1866
|
+
* walking the fixed fields. Returns undefined when a field has an unexpected type.
|
|
1867
|
+
*/
|
|
1868
|
+
_buildJsonLine(entry) {
|
|
1869
|
+
const { timestamp, level, appName, environment, message, context, traceId, payload } = entry;
|
|
1870
|
+
if (typeof timestamp !== "string" || typeof message !== "string" || typeof appName !== "string" || typeof environment !== "string") return;
|
|
1871
|
+
if (appName !== this._jsonHeadsApp || environment !== this._jsonHeadsEnv) {
|
|
1872
|
+
this._jsonHeads.clear();
|
|
1873
|
+
this._jsonHeadsApp = appName;
|
|
1874
|
+
this._jsonHeadsEnv = environment;
|
|
1875
|
+
}
|
|
1876
|
+
let head = this._jsonHeads.get(level);
|
|
1877
|
+
if (head === void 0) {
|
|
1878
|
+
if (typeof level !== "string") return void 0;
|
|
1879
|
+
head = `,"level":${JSON.stringify(level)},"appName":${JSON.stringify(appName)},"environment":${JSON.stringify(environment)},"message":`;
|
|
1880
|
+
this._jsonHeads.set(level, head);
|
|
1881
|
+
}
|
|
1882
|
+
let line = `{"timestamp":"${timestamp}"${head}${JSON.stringify(message)}`;
|
|
1883
|
+
if (context !== void 0) {
|
|
1884
|
+
if (typeof context !== "string") return void 0;
|
|
1885
|
+
if (context !== this._jsonContextKey) {
|
|
1886
|
+
this._jsonContextKey = context;
|
|
1887
|
+
this._jsonContext = `,"context":${JSON.stringify(context)}`;
|
|
1888
|
+
}
|
|
1889
|
+
line += this._jsonContext;
|
|
1890
|
+
}
|
|
1891
|
+
if (traceId !== void 0) {
|
|
1892
|
+
if (typeof traceId !== "string") return void 0;
|
|
1893
|
+
line += `,"traceId":${JSON.stringify(traceId)}`;
|
|
1894
|
+
}
|
|
1895
|
+
if (payload !== void 0) {
|
|
1896
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload) || typeof payload.toJSON === "function") return;
|
|
1897
|
+
line += `,"payload":${JSON.stringify(payload)}`;
|
|
1898
|
+
}
|
|
1899
|
+
return `${line}}`;
|
|
1900
|
+
}
|
|
1760
1901
|
colorize(text, color) {
|
|
1761
|
-
var _this$config$
|
|
1762
|
-
if (!((_this$config$
|
|
1902
|
+
var _this$config$format2;
|
|
1903
|
+
if (!((_this$config$format2 = this.config.format) === null || _this$config$format2 === void 0 ? void 0 : _this$config$format2.colorize)) return text;
|
|
1763
1904
|
return `${this._colorMap.get(color.toLowerCase()) ?? this._colorMap.get("white")}${text}${this._colorMap.get("reset")}`;
|
|
1764
1905
|
}
|
|
1765
1906
|
/**
|
|
@@ -1811,9 +1952,7 @@ function createLogger(config, context) {
|
|
|
1811
1952
|
const logger = new LogixiaLogger(config, context);
|
|
1812
1953
|
const mutableLogger = logger;
|
|
1813
1954
|
if ((_config$levelOptions3 = config.levelOptions) === null || _config$levelOptions3 === void 0 ? void 0 : _config$levelOptions3.levels) {
|
|
1814
|
-
for (const levelName of Object.keys(config.levelOptions.levels)) if (!mutableLogger[levelName]) mutableLogger[levelName] =
|
|
1815
|
-
await logger.logLevel(levelName, message, data);
|
|
1816
|
-
};
|
|
1955
|
+
for (const levelName of Object.keys(config.levelOptions.levels)) if (!mutableLogger[levelName]) mutableLogger[levelName] = (message, data) => logger.logLevel(levelName, message, data);
|
|
1817
1956
|
}
|
|
1818
1957
|
return logger;
|
|
1819
1958
|
}
|
|
@@ -2040,6 +2179,6 @@ var ErrorResponseBuilder = class {
|
|
|
2040
2179
|
};
|
|
2041
2180
|
}
|
|
2042
2181
|
};
|
|
2043
|
-
export {
|
|
2182
|
+
export { DEFAULT_LOG_COLORS as C, DEFAULT_CONFIG as S, LogLevel as T, serializeError as _, isLogixiaException as a, globalPluginRegistry as b, _shutdownRegistrySize as c, registerForShutdown as d, resetShutdownHandlers as f, normalizeError as g, isError as h, LogixiaException as i, deregisterFromShutdown as l, redactObject as m, generateRequestId as n, LogixiaLogger as o, applyRedaction as p, generateTraceId as r, createLogger as s, ErrorResponseBuilder as t, flushOnExit as u, serializeNestedErrors as v, DEFAULT_LOG_LEVELS as w, usePlugin as x, PluginRegistry as y };
|
|
2044
2183
|
|
|
2045
|
-
//# sourceMappingURL=builder-
|
|
2184
|
+
//# sourceMappingURL=builder-BlIJNIuk.mjs.map
|