logixia 1.12.4 → 1.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -27
- package/dist/.tsbuildinfo +1 -1
- package/dist/async-context-CSHWoHMB.js +88 -0
- package/dist/async-context-CSHWoHMB.js.map +1 -0
- package/dist/async-context-CwBNMm2E.mjs +68 -0
- package/dist/async-context-CwBNMm2E.mjs.map +1 -0
- package/dist/azure-monitor.transport-CG7ClkYj.d.ts +62 -0
- package/dist/azure-monitor.transport-CG7ClkYj.d.ts.map +1 -0
- package/dist/azure-monitor.transport-CHnjVRF-.mjs +152 -0
- package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +1 -0
- package/dist/azure-monitor.transport-Cm74kXZS.d.mts +62 -0
- package/dist/azure-monitor.transport-Cm74kXZS.d.mts.map +1 -0
- package/dist/azure-monitor.transport-CrvfHd9C.js +157 -0
- package/dist/azure-monitor.transport-CrvfHd9C.js.map +1 -0
- package/dist/azure.d.mts +3 -0
- package/dist/azure.d.ts +3 -0
- package/dist/azure.js +6 -0
- package/dist/azure.mjs +6 -0
- package/dist/batch-buffer-BY-mRWIK.js +170 -0
- package/dist/batch-buffer-BY-mRWIK.js.map +1 -0
- package/dist/batch-buffer-PGvSgbmd.mjs +132 -0
- package/dist/batch-buffer-PGvSgbmd.mjs.map +1 -0
- package/dist/browser.d.mts +427 -0
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.d.ts +427 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +590 -0
- package/dist/browser.js.map +1 -0
- package/dist/browser.mjs +586 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/chunk-DLSkYcPk.mjs +7 -0
- package/dist/chunk-nOFOJqeH.js +30 -0
- package/dist/cloudwatch.d.mts +3 -0
- package/dist/cloudwatch.d.ts +3 -0
- package/dist/cloudwatch.js +6 -0
- package/dist/cloudwatch.mjs +6 -0
- package/dist/cloudwatch.transport-CGHY4buE.d.mts +81 -0
- package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +1 -0
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts +81 -0
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +1 -0
- package/dist/cloudwatch.transport-pNBNWJLt.js +370 -0
- package/dist/cloudwatch.transport-pNBNWJLt.js.map +1 -0
- package/dist/cloudwatch.transport-yBwm4OeO.mjs +360 -0
- package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +1 -0
- package/dist/coerce.utils-BN980Y9V.js +44 -0
- package/dist/coerce.utils-BN980Y9V.js.map +1 -0
- package/dist/coerce.utils-Dxv4_ikC.mjs +38 -0
- package/dist/coerce.utils-Dxv4_ikC.mjs.map +1 -0
- package/dist/correlation.d.mts +238 -0
- package/dist/correlation.d.mts.map +1 -0
- package/dist/correlation.d.ts +238 -0
- package/dist/correlation.d.ts.map +1 -0
- package/dist/correlation.js +272 -0
- package/dist/correlation.js.map +1 -0
- package/dist/correlation.mjs +261 -0
- package/dist/correlation.mjs.map +1 -0
- package/dist/gcp.d.mts +3 -0
- package/dist/gcp.d.ts +3 -0
- package/dist/gcp.js +6 -0
- package/dist/gcp.mjs +6 -0
- package/dist/gcp.transport-BJuNRFe_.mjs +192 -0
- package/dist/gcp.transport-BJuNRFe_.mjs.map +1 -0
- package/dist/gcp.transport-BOhkVKlI.d.ts +71 -0
- package/dist/gcp.transport-BOhkVKlI.d.ts.map +1 -0
- package/dist/gcp.transport-Bi6CUqZR.d.mts +71 -0
- package/dist/gcp.transport-Bi6CUqZR.d.mts.map +1 -0
- package/dist/gcp.transport-SHdtc1n0.js +198 -0
- package/dist/gcp.transport-SHdtc1n0.js.map +1 -0
- package/dist/{index-CwFww7VC.d.ts → index-BPKwwERo.d.mts} +18 -174
- package/dist/index-BPKwwERo.d.mts.map +1 -0
- package/dist/{index-DnyeaoZU.d.mts → index-C1X-TE5I.d.ts} +18 -174
- package/dist/index-C1X-TE5I.d.ts.map +1 -0
- package/dist/index.d.mts +41 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +40 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +87 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -132
- package/dist/index.mjs.map +1 -1
- package/dist/internal-log-BUJYMZbE.js +70 -0
- package/dist/internal-log-BUJYMZbE.js.map +1 -0
- package/dist/internal-log-Cm8SOWSV.mjs +52 -0
- package/dist/internal-log-Cm8SOWSV.mjs.map +1 -0
- package/dist/{logitron-logger.module-BIGTm2V6.mjs → logitron-logger.module-Bs3XYZgF.mjs} +266 -166
- package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +1 -0
- package/dist/{logitron-logger.module-BTxDpK6u.js → logitron-logger.module-BsDZR5BH.js} +297 -203
- package/dist/logitron-logger.module-BsDZR5BH.js.map +1 -0
- package/dist/{logitron-logger.module-BmT-ewin.d.ts → logitron-logger.module-CxT1F6Cm.d.ts} +23 -10
- package/dist/logitron-logger.module-CxT1F6Cm.d.ts.map +1 -0
- package/dist/{logitron-logger.module-BCq3sF27.d.mts → logitron-logger.module-zDKVd_o0.d.mts} +23 -10
- package/dist/logitron-logger.module-zDKVd_o0.d.mts.map +1 -0
- package/dist/middleware.d.mts +5 -2
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +5 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +13 -4
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +14 -4
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +3 -2
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +3 -2
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +6 -2
- package/dist/nest.mjs +6 -2
- package/dist/safe-stringify-DJ66tW5I.mjs +118 -0
- package/dist/safe-stringify-DJ66tW5I.mjs.map +1 -0
- package/dist/safe-stringify-DWo3aZp_.js +142 -0
- package/dist/safe-stringify-DWo3aZp_.js.map +1 -0
- package/dist/search-CFQRISUv.mjs +1596 -0
- package/dist/search-CFQRISUv.mjs.map +1 -0
- package/dist/search-CQOo-Iq6.d.mts +816 -0
- package/dist/search-CQOo-Iq6.d.mts.map +1 -0
- package/dist/search-DujhR94O.d.ts +816 -0
- package/dist/search-DujhR94O.d.ts.map +1 -0
- package/dist/search-njTI2hdo.js +1631 -0
- package/dist/search-njTI2hdo.js.map +1 -0
- package/dist/search.d.mts +4 -1
- package/dist/search.d.ts +4 -1
- package/dist/search.js +9 -1
- package/dist/search.mjs +3 -2
- package/dist/testing.d.mts +2 -1
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.d.ts +2 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/{transport.manager-ciG4r5uz.js → transport.manager-BivyUTtU.js} +497 -437
- package/dist/transport.manager-BivyUTtU.js.map +1 -0
- package/dist/{transport.manager-DETpXuaY.mjs → transport.manager-D6KL3t9V.mjs} +473 -364
- package/dist/transport.manager-D6KL3t9V.mjs.map +1 -0
- package/dist/transport.types-B5vcyv2k.d.mts +187 -0
- package/dist/transport.types-B5vcyv2k.d.mts.map +1 -0
- package/dist/transport.types-BuY84TwO.d.ts +187 -0
- package/dist/transport.types-BuY84TwO.d.ts.map +1 -0
- package/dist/transports.d.mts +90 -29
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +90 -29
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +14 -2
- package/dist/transports.mjs +10 -2
- package/dist/worker-entry.js +1241 -0
- package/dist/worker.d.mts +3 -0
- package/dist/worker.d.ts +3 -0
- package/dist/worker.js +4 -0
- package/dist/worker.mjs +4 -0
- package/dist/worker.transport-BP8Q28Z2.d.mts +76 -0
- package/dist/worker.transport-BP8Q28Z2.d.mts.map +1 -0
- package/dist/worker.transport-BhMyvqQ2.mjs +167 -0
- package/dist/worker.transport-BhMyvqQ2.mjs.map +1 -0
- package/dist/worker.transport-CfH6z37Z.js +168 -0
- package/dist/worker.transport-CfH6z37Z.js.map +1 -0
- package/dist/worker.transport-mKXgNK0L.d.ts +76 -0
- package/dist/worker.transport-mKXgNK0L.d.ts.map +1 -0
- package/package.json +23 -18
- package/dist/index-CwFww7VC.d.ts.map +0 -1
- package/dist/index-DnyeaoZU.d.mts.map +0 -1
- package/dist/logitron-logger.module-BCq3sF27.d.mts.map +0 -1
- package/dist/logitron-logger.module-BIGTm2V6.mjs.map +0 -1
- package/dist/logitron-logger.module-BTxDpK6u.js.map +0 -1
- package/dist/logitron-logger.module-BmT-ewin.d.ts.map +0 -1
- package/dist/search-Cg_OasF-.d.ts +0 -1
- package/dist/search-DN676Dnz.d.mts +0 -1
- package/dist/search-DOvSI-mb.mjs +0 -1
- package/dist/search-DoZF3RZj.js +0 -0
- package/dist/transport.manager-DETpXuaY.mjs.map +0 -1
- package/dist/transport.manager-ciG4r5uz.js.map +0 -1
|
@@ -1,127 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
let node_events = require("node:events");
|
|
25
|
-
node_events = __toESM(node_events);
|
|
26
|
-
let node_readline = require("node:readline");
|
|
27
|
-
node_readline = __toESM(node_readline);
|
|
1
|
+
const require_chunk = require('./chunk-nOFOJqeH.js');
|
|
2
|
+
const require_internal_log = require('./internal-log-BUJYMZbE.js');
|
|
3
|
+
const require_safe_stringify = require('./safe-stringify-DWo3aZp_.js');
|
|
4
|
+
const require_coerce_utils = require('./coerce.utils-BN980Y9V.js');
|
|
28
5
|
let node_fs = require("node:fs");
|
|
29
|
-
node_fs = __toESM(node_fs);
|
|
6
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
30
7
|
let node_path = require("node:path");
|
|
31
|
-
node_path = __toESM(node_path);
|
|
8
|
+
node_path = require_chunk.__toESM(node_path);
|
|
9
|
+
let node_events = require("node:events");
|
|
10
|
+
node_events = require_chunk.__toESM(node_events);
|
|
32
11
|
let node_stream_promises = require("node:stream/promises");
|
|
33
|
-
node_stream_promises = __toESM(node_stream_promises);
|
|
12
|
+
node_stream_promises = require_chunk.__toESM(node_stream_promises);
|
|
34
13
|
let node_util = require("node:util");
|
|
35
|
-
node_util = __toESM(node_util);
|
|
14
|
+
node_util = require_chunk.__toESM(node_util);
|
|
36
15
|
let node_zlib = require("node:zlib");
|
|
37
|
-
node_zlib = __toESM(node_zlib);
|
|
38
|
-
|
|
39
|
-
//#region src/utils/internal-log.ts
|
|
40
|
-
/**
|
|
41
|
-
* Internal logging helpers for use within the logixia library itself.
|
|
42
|
-
*
|
|
43
|
-
* These functions write directly to stderr/stdout without going through
|
|
44
|
-
* LogixiaLogger — this avoids circular dependencies and ensures internal
|
|
45
|
-
* diagnostics still surface even when the logger is misconfigured.
|
|
46
|
-
*
|
|
47
|
-
* Library code must NEVER call console.log/warn/error directly. Use these
|
|
48
|
-
* helpers instead so that internal output can be silenced in tests by setting
|
|
49
|
-
* the LOGIXIA_SILENT_INTERNAL=1 environment variable.
|
|
50
|
-
*/
|
|
51
|
-
/**
|
|
52
|
-
* Read the silence flag on each call rather than caching it at import time, so
|
|
53
|
-
* setting LOGIXIA_SILENT_INTERNAL=1 AFTER the module is first imported (e.g. in
|
|
54
|
-
* a test setup file) still takes effect — the documented test-silencing
|
|
55
|
-
* behavior was previously unreliable because the value was frozen at load.
|
|
56
|
-
*/
|
|
57
|
-
function isSilent() {
|
|
58
|
-
return process.env.LOGIXIA_SILENT_INTERNAL === "1";
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Emit an internal debug/info message to stderr.
|
|
62
|
-
* Use for field-enable/disable notifications that a developer might want to see
|
|
63
|
-
* during development but should not appear in production log streams.
|
|
64
|
-
*/
|
|
65
|
-
function internalLog(message) {
|
|
66
|
-
if (!isSilent()) process.stderr.write(`[logixia] ${message}\n`);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Emit an internal warning to stderr.
|
|
70
|
-
* Use when something is misconfigured but logixia can continue operating.
|
|
71
|
-
*/
|
|
72
|
-
function internalWarn(message) {
|
|
73
|
-
if (!isSilent()) process.stderr.write(`[logixia:warn] ${message}\n`);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Emit an internal error to stderr.
|
|
77
|
-
* Use when a transport write fails or a serious internal error occurs.
|
|
78
|
-
*/
|
|
79
|
-
function internalError(message, error) {
|
|
80
|
-
if (!isSilent()) {
|
|
81
|
-
let errStr = "";
|
|
82
|
-
if (error instanceof Error) errStr = ` — ${error.message}`;
|
|
83
|
-
else if (error != null) errStr = ` — ${String(error)}`;
|
|
84
|
-
process.stderr.write(`[logixia:error] ${message}${errStr}\n`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
16
|
+
node_zlib = require_chunk.__toESM(node_zlib);
|
|
87
17
|
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/utils/coerce.utils.ts
|
|
90
|
-
/**
|
|
91
|
-
* Defensive value coercion helpers for Logixia.
|
|
92
|
-
*
|
|
93
|
-
* Logger inputs come from third-party code (NestJS framework internals,
|
|
94
|
-
* user payloads, error objects) where the runtime type is not always what
|
|
95
|
-
* the TypeScript signature promises. The formatter / transport hot paths
|
|
96
|
-
* call `.replace()` on string fields and crash if the field is anything
|
|
97
|
-
* else. Use these helpers anywhere a downstream consumer assumes a string.
|
|
98
|
-
*/
|
|
99
|
-
/**
|
|
100
|
-
* Coerce any value to a string without throwing.
|
|
101
|
-
*
|
|
102
|
-
* - `undefined` / `null` → `''` (so the field is rendered as empty rather
|
|
103
|
-
* than the literal string "undefined")
|
|
104
|
-
* - strings → returned as-is (zero allocation on the hot path)
|
|
105
|
-
* - Errors → `error.message` (matches what users would expect to see)
|
|
106
|
-
* - everything else → `JSON.stringify` if possible, falling back to
|
|
107
|
-
* `String(value)` for circular refs / values without a stringifier.
|
|
108
|
-
*/
|
|
109
|
-
function safeToString(value) {
|
|
110
|
-
var _constructor;
|
|
111
|
-
if (typeof value === "string") return value;
|
|
112
|
-
if (value === void 0 || value === null) return "";
|
|
113
|
-
if (value instanceof Error) return value.message;
|
|
114
|
-
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") return String(value);
|
|
115
|
-
if (typeof value === "symbol") return value.toString();
|
|
116
|
-
if (typeof value === "function") return `[Function: ${value.name || "anonymous"}]`;
|
|
117
|
-
try {
|
|
118
|
-
const json = JSON.stringify(value);
|
|
119
|
-
if (json !== void 0) return json;
|
|
120
|
-
} catch {}
|
|
121
|
-
return `[${((_constructor = value.constructor) === null || _constructor === void 0 ? void 0 : _constructor.name) ?? "object"}]`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
//#endregion
|
|
125
18
|
//#region src/transports/console.transport.ts
|
|
126
19
|
/**
|
|
127
20
|
* Writes log entries to stdout (info/debug/verbose) and stderr (error/warn).
|
|
@@ -154,7 +47,7 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
154
47
|
]);
|
|
155
48
|
static #_2 = this.CONTROL_CHARS_RE = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
|
|
156
49
|
static sanitize(value) {
|
|
157
|
-
return safeToString(value).replace(ConsoleTransport.CONTROL_CHARS_RE, "");
|
|
50
|
+
return require_coerce_utils.safeToString(value).replace(ConsoleTransport.CONTROL_CHARS_RE, "");
|
|
158
51
|
}
|
|
159
52
|
constructor(config = {}) {
|
|
160
53
|
this.config = config;
|
|
@@ -167,7 +60,7 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
167
60
|
(lvl === "error" || lvl === "warn" ? process.stderr : process.stdout).write(formatted);
|
|
168
61
|
}
|
|
169
62
|
formatEntry(entry) {
|
|
170
|
-
if (this.config.format === "json") return
|
|
63
|
+
if (this.config.format === "json") return require_safe_stringify.stringifyForLog({
|
|
171
64
|
timestamp: this.config.timestamp !== false ? entry.timestamp.toISOString() : void 0,
|
|
172
65
|
level: entry.level,
|
|
173
66
|
message: entry.message,
|
|
@@ -195,7 +88,7 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
195
88
|
}
|
|
196
89
|
parts.push(ConsoleTransport.sanitize(entry.message));
|
|
197
90
|
if (entry.data && Object.keys(entry.data).length > 0) {
|
|
198
|
-
const data =
|
|
91
|
+
const data = require_safe_stringify.stringifyForLog(entry.data);
|
|
199
92
|
parts.push(this.colorize(data, "blue"));
|
|
200
93
|
}
|
|
201
94
|
return parts.join(" ");
|
|
@@ -230,6 +123,15 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
230
123
|
* Validates that a SQL identifier (table/index name) contains only safe characters.
|
|
231
124
|
* Prevents SQL injection via user-supplied table names.
|
|
232
125
|
*/
|
|
126
|
+
const POSTGRES_MAX_PARAMS = 65535;
|
|
127
|
+
const POSTGRES_COLUMNS = 8;
|
|
128
|
+
const POSTGRES_ROWS_PER_INSERT = Math.floor(POSTGRES_MAX_PARAMS / POSTGRES_COLUMNS);
|
|
129
|
+
const MYSQL_ROWS_PER_INSERT = 5e3;
|
|
130
|
+
function chunk(items, size) {
|
|
131
|
+
const chunks = [];
|
|
132
|
+
for (let i = 0; i < items.length; i += size) chunks.push(items.slice(i, i + size));
|
|
133
|
+
return chunks;
|
|
134
|
+
}
|
|
233
135
|
function validateSqlIdentifier(name, label = "table") {
|
|
234
136
|
if (!/^[a-zA-Z_]\w*$/.test(name)) throw new Error(`Invalid ${label} name "${name}". Only letters, digits, and underscores are allowed, and the name must start with a letter or underscore.`);
|
|
235
137
|
}
|
|
@@ -300,7 +202,7 @@ var DatabaseTransport = class {
|
|
|
300
202
|
default: throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
301
203
|
}
|
|
302
204
|
} catch (error) {
|
|
303
|
-
internalError("Database flush error", error);
|
|
205
|
+
require_internal_log.internalError("Database flush error", error);
|
|
304
206
|
this.batch.unshift(...entriesToFlush);
|
|
305
207
|
throw error;
|
|
306
208
|
}
|
|
@@ -431,22 +333,38 @@ var DatabaseTransport = class {
|
|
|
431
333
|
}
|
|
432
334
|
async flushToPostgreSQL(entries) {
|
|
433
335
|
const tableName = this.config.table || "logs";
|
|
434
|
-
const
|
|
336
|
+
const chunks = chunk(entries.map((entry) => [
|
|
435
337
|
entry.timestamp,
|
|
436
338
|
entry.level,
|
|
437
339
|
entry.message,
|
|
438
|
-
|
|
340
|
+
require_safe_stringify.stringifyForLog(entry.data || {}),
|
|
439
341
|
entry.context,
|
|
440
342
|
entry.traceId,
|
|
441
343
|
entry.appName,
|
|
442
344
|
entry.environment
|
|
443
|
-
]);
|
|
444
|
-
const
|
|
345
|
+
]), POSTGRES_ROWS_PER_INSERT);
|
|
346
|
+
const insertChunk = async (rows) => {
|
|
347
|
+
const query = `
|
|
445
348
|
INSERT INTO ${tableName}
|
|
446
349
|
(timestamp, level, message, payload, context, trace_id, app_name, environment)
|
|
447
|
-
VALUES ${
|
|
350
|
+
VALUES ${rows.map((_, i) => {
|
|
351
|
+
return `(${Array.from({ length: POSTGRES_COLUMNS }, (_unused, c) => `$${i * POSTGRES_COLUMNS + c + 1}`).join(", ")})`;
|
|
352
|
+
}).join(", ")}
|
|
448
353
|
`;
|
|
449
|
-
|
|
354
|
+
await this.connection.query(query, rows.flat());
|
|
355
|
+
};
|
|
356
|
+
if (chunks.length === 1) {
|
|
357
|
+
await insertChunk(chunks[0]);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
await this.connection.query("BEGIN");
|
|
361
|
+
try {
|
|
362
|
+
for (const rows of chunks) await insertChunk(rows);
|
|
363
|
+
await this.connection.query("COMMIT");
|
|
364
|
+
} catch (error) {
|
|
365
|
+
await this.connection.query("ROLLBACK").catch(() => {});
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
450
368
|
}
|
|
451
369
|
async flushToMySQL(entries) {
|
|
452
370
|
const tableName = this.config.table || "logs";
|
|
@@ -454,7 +372,7 @@ var DatabaseTransport = class {
|
|
|
454
372
|
entry.timestamp,
|
|
455
373
|
entry.level,
|
|
456
374
|
entry.message,
|
|
457
|
-
|
|
375
|
+
require_safe_stringify.stringifyForLog(entry.data || {}),
|
|
458
376
|
entry.context,
|
|
459
377
|
entry.traceId,
|
|
460
378
|
entry.appName,
|
|
@@ -465,7 +383,19 @@ var DatabaseTransport = class {
|
|
|
465
383
|
(timestamp, level, message, payload, context, trace_id, app_name, environment)
|
|
466
384
|
VALUES ?
|
|
467
385
|
`;
|
|
468
|
-
|
|
386
|
+
const chunks = chunk(values, MYSQL_ROWS_PER_INSERT);
|
|
387
|
+
if (chunks.length === 1) {
|
|
388
|
+
await this.connection.query(query, [values]);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
await this.connection.beginTransaction();
|
|
392
|
+
try {
|
|
393
|
+
for (const rows of chunks) await this.connection.query(query, [rows]);
|
|
394
|
+
await this.connection.commit();
|
|
395
|
+
} catch (error) {
|
|
396
|
+
await this.connection.rollback().catch(() => {});
|
|
397
|
+
throw error;
|
|
398
|
+
}
|
|
469
399
|
}
|
|
470
400
|
async flushToSQLite(entries) {
|
|
471
401
|
const tableName = this.config.table || "logs";
|
|
@@ -474,8 +404,16 @@ var DatabaseTransport = class {
|
|
|
474
404
|
(timestamp, level, message, payload, context, trace_id, app_name, environment)
|
|
475
405
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
476
406
|
`);
|
|
477
|
-
|
|
478
|
-
|
|
407
|
+
await this.connection.exec("BEGIN");
|
|
408
|
+
try {
|
|
409
|
+
for (const entry of entries) await stmt.run(entry.timestamp instanceof Date ? entry.timestamp.toISOString() : entry.timestamp, entry.level, entry.message, require_safe_stringify.stringifyForLog(entry.data || {}), entry.context, entry.traceId, entry.appName, entry.environment);
|
|
410
|
+
await this.connection.exec("COMMIT");
|
|
411
|
+
} catch (error) {
|
|
412
|
+
await this.connection.exec("ROLLBACK").catch(() => {});
|
|
413
|
+
throw error;
|
|
414
|
+
} finally {
|
|
415
|
+
await stmt.finalize().catch(() => {});
|
|
416
|
+
}
|
|
479
417
|
}
|
|
480
418
|
async createPostgreSQLTable() {
|
|
481
419
|
const tableName = this.config.table || "logs";
|
|
@@ -543,11 +481,13 @@ var DatabaseTransport = class {
|
|
|
543
481
|
await this.connection.exec(`CREATE INDEX IF NOT EXISTS idx_${tableName}_trace_id ON ${tableName} (trace_id)`);
|
|
544
482
|
}
|
|
545
483
|
setupFlushTimer() {
|
|
484
|
+
var _this$flushTimer$unre, _this$flushTimer;
|
|
546
485
|
this.flushTimer = setInterval(() => {
|
|
547
486
|
this.flush().catch((error) => {
|
|
548
|
-
internalError("Scheduled database flush error", error);
|
|
487
|
+
require_internal_log.internalError("Scheduled database flush error", error);
|
|
549
488
|
});
|
|
550
489
|
}, this.flushInterval);
|
|
490
|
+
(_this$flushTimer$unre = (_this$flushTimer = this.flushTimer).unref) === null || _this$flushTimer$unre === void 0 || _this$flushTimer$unre.call(_this$flushTimer);
|
|
551
491
|
}
|
|
552
492
|
async close() {
|
|
553
493
|
if (this.flushTimer) {
|
|
@@ -555,12 +495,13 @@ var DatabaseTransport = class {
|
|
|
555
495
|
this.flushTimer = void 0;
|
|
556
496
|
}
|
|
557
497
|
const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
|
|
498
|
+
if (this.flushPromise) await this.flushPromise.catch(() => {});
|
|
558
499
|
for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) try {
|
|
559
500
|
await this.flush();
|
|
560
501
|
} catch (error) {
|
|
561
|
-
internalError("Database flush during close failed; entries remain buffered", error);
|
|
502
|
+
require_internal_log.internalError("Database flush during close failed; entries remain buffered", error);
|
|
562
503
|
}
|
|
563
|
-
if (this.batch.length > 0) internalError(`Database transport closing with ${this.batch.length} unflushed log entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
|
|
504
|
+
if (this.batch.length > 0) require_internal_log.internalError(`Database transport closing with ${this.batch.length} unflushed log entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
|
|
564
505
|
if (this.connection) switch (this.config.type) {
|
|
565
506
|
case "mongodb":
|
|
566
507
|
await this.connection.close();
|
|
@@ -590,14 +531,22 @@ var DatabaseTransport = class {
|
|
|
590
531
|
try {
|
|
591
532
|
switch (this.config.type) {
|
|
592
533
|
case "mongodb": return await this.connection.db(this.config.database).collection(this.config.collection || "logs").countDocuments();
|
|
593
|
-
case "postgresql":
|
|
594
|
-
|
|
595
|
-
case "sqlite": {
|
|
596
|
-
var _result$rows, _result$;
|
|
534
|
+
case "postgresql": {
|
|
535
|
+
var _result$rows;
|
|
597
536
|
const tableName = this.config.table || "logs";
|
|
598
537
|
const result = await this.connection.query(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
599
|
-
|
|
600
|
-
|
|
538
|
+
return Number((_result$rows = result.rows) === null || _result$rows === void 0 || (_result$rows = _result$rows[0]) === null || _result$rows === void 0 ? void 0 : _result$rows.count) || 0;
|
|
539
|
+
}
|
|
540
|
+
case "mysql": {
|
|
541
|
+
var _rows$;
|
|
542
|
+
const tableName = this.config.table || "logs";
|
|
543
|
+
const [rows] = await this.connection.query(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
544
|
+
return Number(rows === null || rows === void 0 || (_rows$ = rows[0]) === null || _rows$ === void 0 ? void 0 : _rows$.count) || 0;
|
|
545
|
+
}
|
|
546
|
+
case "sqlite": {
|
|
547
|
+
const tableName = this.config.table || "logs";
|
|
548
|
+
const row = await this.connection.get(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
549
|
+
return Number(row === null || row === void 0 ? void 0 : row.count) || 0;
|
|
601
550
|
}
|
|
602
551
|
default: return 0;
|
|
603
552
|
}
|
|
@@ -624,20 +573,23 @@ var AnalyticsTransport = class {
|
|
|
624
573
|
this.level = config.level;
|
|
625
574
|
this.batchSize = this.config.batchSize || 50;
|
|
626
575
|
this.flushInterval = this.config.flushInterval || 1e4;
|
|
627
|
-
this.initialize();
|
|
628
576
|
}
|
|
629
577
|
async write(entry) {
|
|
630
|
-
if (!this.isReady) await this.
|
|
578
|
+
if (!this.isReady) await this.ensureReady();
|
|
631
579
|
if (this.shouldSkipEntry(entry)) return;
|
|
632
580
|
if (this.config.batchSize && this.config.batchSize > 1) this.addToBatch(entry);
|
|
633
581
|
else await this.sendEntry(entry);
|
|
634
582
|
}
|
|
635
583
|
addToBatch(entry) {
|
|
636
584
|
this.batch.push(entry);
|
|
637
|
-
if (this.batch.length >= (this.config.batchSize || 50)) this.flush().catch((err) => internalError(`${this.name} batch flush failed`, err));
|
|
638
|
-
else if (!this.batchTimer && this.config.flushInterval)
|
|
639
|
-
|
|
640
|
-
|
|
585
|
+
if (this.batch.length >= (this.config.batchSize || 50)) this.flush().catch((err) => require_internal_log.internalError(`${this.name} batch flush failed`, err));
|
|
586
|
+
else if (!this.batchTimer && this.config.flushInterval) {
|
|
587
|
+
var _this$batchTimer$unre, _this$batchTimer;
|
|
588
|
+
this.batchTimer = setTimeout(() => {
|
|
589
|
+
this.flush().catch((err) => require_internal_log.internalError(`${this.name} interval flush failed`, err));
|
|
590
|
+
}, this.config.flushInterval);
|
|
591
|
+
(_this$batchTimer$unre = (_this$batchTimer = this.batchTimer).unref) === null || _this$batchTimer$unre === void 0 || _this$batchTimer$unre.call(_this$batchTimer);
|
|
592
|
+
}
|
|
641
593
|
}
|
|
642
594
|
async flush() {
|
|
643
595
|
if (this.batchTimer) {
|
|
@@ -663,7 +615,7 @@ var AnalyticsTransport = class {
|
|
|
663
615
|
try {
|
|
664
616
|
await this.sendBatch(entriesToSend);
|
|
665
617
|
} catch (error) {
|
|
666
|
-
internalError(`Analytics transport ${this.name} flush failed`, error);
|
|
618
|
+
require_internal_log.internalError(`Analytics transport ${this.name} flush failed`, error);
|
|
667
619
|
this.batch.unshift(...entriesToSend);
|
|
668
620
|
return;
|
|
669
621
|
}
|
|
@@ -676,7 +628,7 @@ var AnalyticsTransport = class {
|
|
|
676
628
|
}
|
|
677
629
|
const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
|
|
678
630
|
for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) await this.flush();
|
|
679
|
-
if (this.batch.length > 0) internalError(`Analytics transport ${this.name} closing with ${this.batch.length} unflushed entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
|
|
631
|
+
if (this.batch.length > 0) require_internal_log.internalError(`Analytics transport ${this.name} closing with ${this.batch.length} unflushed entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
|
|
680
632
|
await this.cleanup();
|
|
681
633
|
}
|
|
682
634
|
shouldSkipEntry(entry) {
|
|
@@ -696,10 +648,20 @@ var AnalyticsTransport = class {
|
|
|
696
648
|
if (this.config.customProperties) Object.assign(transformed, this.config.customProperties);
|
|
697
649
|
return transformed;
|
|
698
650
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
651
|
+
/**
|
|
652
|
+
* Runs initialize() once. A bad config (say, a missing API key) fails every
|
|
653
|
+
* write with the same error instead of an unhandled rejection at startup.
|
|
654
|
+
*/
|
|
655
|
+
ensureReady() {
|
|
656
|
+
this.initPromise ??= (async () => {
|
|
657
|
+
await this.initialize();
|
|
658
|
+
this.isReady = true;
|
|
659
|
+
})();
|
|
660
|
+
return this.initPromise;
|
|
661
|
+
}
|
|
662
|
+
/** @deprecated Use ensureReady(); kept for subclasses that call it. */
|
|
663
|
+
async waitForReady() {
|
|
664
|
+
await this.ensureReady();
|
|
703
665
|
}
|
|
704
666
|
};
|
|
705
667
|
|
|
@@ -725,10 +687,9 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
725
687
|
async initialize() {
|
|
726
688
|
try {
|
|
727
689
|
if (!this.datadogConfig.apiKey) throw new Error("DataDog API key is required");
|
|
728
|
-
await this.testConnection();
|
|
729
690
|
this.isReady = true;
|
|
730
691
|
} catch (error) {
|
|
731
|
-
internalError("DataDog transport initialization failed", error);
|
|
692
|
+
require_internal_log.internalError("DataDog transport initialization failed", error);
|
|
732
693
|
throw error;
|
|
733
694
|
}
|
|
734
695
|
}
|
|
@@ -776,11 +737,11 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
776
737
|
timestamp: entry.timestamp.toISOString(),
|
|
777
738
|
level: this.mapLogLevel(entry.level),
|
|
778
739
|
message: entry.message,
|
|
779
|
-
service: this.datadogConfig.service || "
|
|
740
|
+
service: this.datadogConfig.service || "logixia",
|
|
780
741
|
version: this.datadogConfig.version,
|
|
781
742
|
env: this.datadogConfig.env || "production",
|
|
782
743
|
logger: {
|
|
783
|
-
name: "
|
|
744
|
+
name: "logixia",
|
|
784
745
|
thread_name: "main"
|
|
785
746
|
},
|
|
786
747
|
...transformed,
|
|
@@ -798,7 +759,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
798
759
|
host: this.getHostname(),
|
|
799
760
|
tags: [
|
|
800
761
|
`level:${entry.level}`,
|
|
801
|
-
`service:${this.datadogConfig.service || "
|
|
762
|
+
`service:${this.datadogConfig.service || "logixia"}`,
|
|
802
763
|
`env:${this.datadogConfig.env || "production"}`,
|
|
803
764
|
...entry.context ? [`context:${entry.context}`] : [],
|
|
804
765
|
...entry.appName ? [`app:${entry.appName}`] : []
|
|
@@ -811,7 +772,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
811
772
|
span_id: this.generateSpanId(),
|
|
812
773
|
parent_id: null,
|
|
813
774
|
name: "log.entry",
|
|
814
|
-
service: this.datadogConfig.service || "
|
|
775
|
+
service: this.datadogConfig.service || "logixia",
|
|
815
776
|
resource: entry.message,
|
|
816
777
|
type: "log",
|
|
817
778
|
start: entry.timestamp.getTime() * 1e6,
|
|
@@ -848,7 +809,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
848
809
|
"Content-Type": "application/json",
|
|
849
810
|
"DD-API-KEY": this.datadogConfig.apiKey
|
|
850
811
|
},
|
|
851
|
-
body:
|
|
812
|
+
body: require_safe_stringify.stringifyForLog(data)
|
|
852
813
|
});
|
|
853
814
|
if (!response.ok) throw new Error(`DataDog Logs API error: ${response.status} ${response.statusText}`);
|
|
854
815
|
} catch (error) {
|
|
@@ -864,23 +825,13 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
864
825
|
"Content-Type": "application/json",
|
|
865
826
|
"DD-API-KEY": this.datadogConfig.apiKey
|
|
866
827
|
},
|
|
867
|
-
body:
|
|
828
|
+
body: require_safe_stringify.stringifyForLog(data)
|
|
868
829
|
});
|
|
869
830
|
if (!response.ok) throw new Error(`DataDog Metrics API error: ${response.status} ${response.statusText}`);
|
|
870
831
|
} catch (error) {
|
|
871
832
|
throw new Error(`Failed to send metrics to DataDog: ${error.message}`, { cause: error });
|
|
872
833
|
}
|
|
873
834
|
}
|
|
874
|
-
async testConnection() {
|
|
875
|
-
const testMetric = { series: [{
|
|
876
|
-
metric: "logitron.test",
|
|
877
|
-
points: [[Math.floor(Date.now() / 1e3), 1]],
|
|
878
|
-
type: "count",
|
|
879
|
-
host: this.getHostname(),
|
|
880
|
-
tags: ["test:true"]
|
|
881
|
-
}] };
|
|
882
|
-
await this.makeMetricsRequest("/api/v1/series", testMetric);
|
|
883
|
-
}
|
|
884
835
|
generateSpanId() {
|
|
885
836
|
return Math.floor(Math.random() * 0xffffffffffff).toString(16);
|
|
886
837
|
}
|
|
@@ -908,11 +859,11 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
908
859
|
date_happened: Math.floor(Date.now() / 1e3),
|
|
909
860
|
priority: "normal",
|
|
910
861
|
tags: [
|
|
911
|
-
`service:${this.datadogConfig.service || "
|
|
862
|
+
`service:${this.datadogConfig.service || "logixia"}`,
|
|
912
863
|
`env:${this.datadogConfig.env || "production"}`,
|
|
913
864
|
...tags
|
|
914
865
|
],
|
|
915
|
-
source_type_name: "
|
|
866
|
+
source_type_name: "logixia"
|
|
916
867
|
};
|
|
917
868
|
const url = `${this.baseUrl}/api/v1/events`;
|
|
918
869
|
try {
|
|
@@ -922,7 +873,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
922
873
|
"Content-Type": "application/json",
|
|
923
874
|
"DD-API-KEY": this.datadogConfig.apiKey
|
|
924
875
|
},
|
|
925
|
-
body:
|
|
876
|
+
body: require_safe_stringify.stringifyForLog(payload)
|
|
926
877
|
});
|
|
927
878
|
if (!response.ok) throw new Error(`DataDog Events API error: ${response.status} ${response.statusText}`);
|
|
928
879
|
} catch (error) {
|
|
@@ -933,16 +884,46 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
933
884
|
|
|
934
885
|
//#endregion
|
|
935
886
|
//#region src/transports/file.transport.ts
|
|
936
|
-
const
|
|
937
|
-
const
|
|
887
|
+
const appendFile = (0, node_util.promisify)(node_fs.appendFile);
|
|
888
|
+
const rename = (0, node_util.promisify)(node_fs.rename);
|
|
938
889
|
const unlink = (0, node_util.promisify)(node_fs.unlink);
|
|
939
890
|
const readdir = (0, node_util.promisify)(node_fs.readdir);
|
|
940
891
|
const stat = (0, node_util.promisify)(node_fs.stat);
|
|
892
|
+
const DROP_WARN_INTERVAL_MS = 5e3;
|
|
893
|
+
const SIZE_UNITS = {
|
|
894
|
+
"": 1,
|
|
895
|
+
k: 1024,
|
|
896
|
+
m: 1024 ** 2,
|
|
897
|
+
g: 1024 ** 3,
|
|
898
|
+
t: 1024 ** 4
|
|
899
|
+
};
|
|
900
|
+
/**
|
|
901
|
+
* Parses a size like `50MB`, `1.5g`, `512 KiB` or a plain byte count.
|
|
902
|
+
* Units are binary (1KB = 1024 bytes). Returns undefined for anything else.
|
|
903
|
+
*/
|
|
904
|
+
function parseSize(value) {
|
|
905
|
+
if (value === void 0) return void 0;
|
|
906
|
+
if (typeof value === "number") return Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
|
|
907
|
+
const match = /^(\d+(?:\.\d+)?) ?([kmgt]?)(?:i?b)?$/i.exec(value.trim());
|
|
908
|
+
if (!match) return void 0;
|
|
909
|
+
const bytes = Math.floor(Number(match[1]) * (SIZE_UNITS[(match[2] ?? "").toLowerCase()] ?? 1));
|
|
910
|
+
return bytes > 0 ? bytes : void 0;
|
|
911
|
+
}
|
|
912
|
+
/** Formats a date with the YYYY, MM, DD, HH, mm and ss tokens, in local time. */
|
|
913
|
+
function formatDatePattern(date, pattern) {
|
|
914
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
915
|
+
return pattern.replace(/YYYY/g, String(date.getFullYear())).replace(/MM/g, pad(date.getMonth() + 1)).replace(/DD/g, pad(date.getDate())).replace(/HH/g, pad(date.getHours())).replace(/mm/g, pad(date.getMinutes())).replace(/ss/g, pad(date.getSeconds()));
|
|
916
|
+
}
|
|
941
917
|
/**
|
|
942
918
|
* Appends log entries to a local file with automatic rotation.
|
|
943
919
|
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
920
|
+
* Rotates by size (`maxSize`), by date (`datePattern`), by interval
|
|
921
|
+
* (`rotation.interval`) or by a custom `rotation.shouldRotate` check. Rotated
|
|
922
|
+
* files can be gzipped (`zippedArchive`) and pruned to the newest `maxFiles`.
|
|
923
|
+
*
|
|
924
|
+
* Without a `rotation` block the live file keeps its name (`app.log`) and
|
|
925
|
+
* rotated files are renamed beside it (`app-2026-10-22T09-30-00-000.log`).
|
|
926
|
+
* With a `rotation` block every file, the live one included, is timestamped.
|
|
946
927
|
*
|
|
947
928
|
* @example
|
|
948
929
|
* transports: { file: { filename: 'app.log', dirname: './logs', maxSize: '50MB' } }
|
|
@@ -952,7 +933,17 @@ var FileTransport = class {
|
|
|
952
933
|
this.name = "file";
|
|
953
934
|
this.batch = [];
|
|
954
935
|
this.lastRotation = /* @__PURE__ */ new Date();
|
|
955
|
-
this.
|
|
936
|
+
this.bytesWritten = 0;
|
|
937
|
+
this.rotateRequested = false;
|
|
938
|
+
this.rotationWaiters = [];
|
|
939
|
+
this.enqueued = 0;
|
|
940
|
+
this.settled = 0;
|
|
941
|
+
this.flushWaiters = [];
|
|
942
|
+
this.spaceWaiters = [];
|
|
943
|
+
this.inFlight = 0;
|
|
944
|
+
this.dropped = 0;
|
|
945
|
+
this.lastDropWarning = 0;
|
|
946
|
+
this.housekeeping = Promise.resolve();
|
|
956
947
|
this.config = {
|
|
957
948
|
format: "json",
|
|
958
949
|
batchSize: 100,
|
|
@@ -963,100 +954,257 @@ var FileTransport = class {
|
|
|
963
954
|
this.batchSize = this.config.batchSize || 100;
|
|
964
955
|
this.flushInterval = this.config.flushInterval || 5e3;
|
|
965
956
|
if (config.filter) this.filter = config.filter;
|
|
966
|
-
|
|
967
|
-
|
|
957
|
+
const rotation = config.rotation;
|
|
958
|
+
const rawMaxSize = (rotation === null || rotation === void 0 ? void 0 : rotation.maxSize) ?? config.maxSize;
|
|
959
|
+
this.maxBytes = parseSize(rawMaxSize);
|
|
960
|
+
if (rawMaxSize !== void 0 && this.maxBytes === void 0) require_internal_log.internalWarn(`FileTransport: maxSize ${JSON.stringify(rawMaxSize)} is not a valid size (try '50MB'); size rotation is off`);
|
|
961
|
+
const maxQueue = config.maxQueue;
|
|
962
|
+
if (maxQueue !== void 0 && !(Number.isInteger(maxQueue) && maxQueue > 0)) require_internal_log.internalWarn(`FileTransport: maxQueue ${String(maxQueue)} is not a positive integer; ignored`);
|
|
963
|
+
else this.maxQueue = maxQueue;
|
|
964
|
+
this.queuePolicy = config.queuePolicy ?? "drop-oldest";
|
|
965
|
+
this.maxFiles = (rotation === null || rotation === void 0 ? void 0 : rotation.maxFiles) ?? config.maxFiles;
|
|
966
|
+
this.compress = (rotation === null || rotation === void 0 ? void 0 : rotation.compress) ?? config.zippedArchive ?? false;
|
|
967
|
+
this.intervalMs = (rotation === null || rotation === void 0 ? void 0 : rotation.interval) ? this.parseInterval(rotation.interval) : void 0;
|
|
968
|
+
this.timestampedActive = rotation !== void 0;
|
|
969
|
+
this.dir = this.resolveDir();
|
|
970
|
+
this.ext = node_path.extname(config.filename);
|
|
971
|
+
this.base = node_path.basename(config.filename, this.ext);
|
|
972
|
+
try {
|
|
973
|
+
node_fs.mkdirSync(this.dir, { recursive: true });
|
|
974
|
+
} catch (error) {
|
|
975
|
+
require_internal_log.internalError(`FileTransport could not create ${this.dir}`, error);
|
|
976
|
+
}
|
|
977
|
+
this.currentFilePath = this.timestampedActive ? this.uniquePath(this.timestamp(/* @__PURE__ */ new Date())) : node_path.join(this.dir, `${this.base}${this.ext}`);
|
|
978
|
+
let existing;
|
|
979
|
+
try {
|
|
980
|
+
existing = node_fs.statSync(this.currentFilePath);
|
|
981
|
+
} catch {
|
|
982
|
+
existing = void 0;
|
|
983
|
+
}
|
|
984
|
+
this.bytesWritten = (existing === null || existing === void 0 ? void 0 : existing.size) ?? 0;
|
|
985
|
+
if (config.datePattern) this.period = formatDatePattern((existing === null || existing === void 0 ? void 0 : existing.mtime) ?? /* @__PURE__ */ new Date(), config.datePattern);
|
|
968
986
|
}
|
|
969
987
|
async write(entry) {
|
|
970
988
|
try {
|
|
971
|
-
|
|
972
|
-
this.isRotating = true;
|
|
973
|
-
try {
|
|
974
|
-
await this.rotate();
|
|
975
|
-
} finally {
|
|
976
|
-
this.isRotating = false;
|
|
977
|
-
}
|
|
978
|
-
}
|
|
989
|
+
while (this.queuePolicy === "block" && this.queueFull()) await this.roomAvailable();
|
|
979
990
|
if (this.config.batchSize && this.config.batchSize > 1) this.addToBatch(entry);
|
|
980
|
-
else
|
|
991
|
+
else {
|
|
992
|
+
this.enqueue(entry);
|
|
993
|
+
await this.flush();
|
|
994
|
+
}
|
|
981
995
|
} catch (error) {
|
|
982
996
|
throw new Error(`File transport write failed: ${error.message}`, { cause: error });
|
|
983
997
|
}
|
|
984
998
|
}
|
|
999
|
+
/**
|
|
1000
|
+
* Resolves once every entry queued before the call is on disk. It does not
|
|
1001
|
+
* wait for entries queued afterwards, so under steady traffic it still returns
|
|
1002
|
+
* instead of waiting for a quiet moment that never comes.
|
|
1003
|
+
*/
|
|
985
1004
|
async flush() {
|
|
986
1005
|
if (this.batchTimer) {
|
|
987
1006
|
clearTimeout(this.batchTimer);
|
|
988
1007
|
this.batchTimer = void 0;
|
|
989
1008
|
}
|
|
990
|
-
if (
|
|
991
|
-
|
|
1009
|
+
if (this.settled >= this.enqueued) return;
|
|
1010
|
+
const done = new Promise((resolve, reject) => {
|
|
1011
|
+
this.flushWaiters.push({
|
|
1012
|
+
upTo: this.enqueued,
|
|
1013
|
+
resolve,
|
|
1014
|
+
reject
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
this.startDrain();
|
|
1018
|
+
await done;
|
|
1019
|
+
}
|
|
1020
|
+
/** Writes out anything pending, then starts a new file. */
|
|
1021
|
+
async rotate() {
|
|
1022
|
+
await this.flush();
|
|
1023
|
+
const done = new Promise((resolve) => this.rotationWaiters.push(resolve));
|
|
1024
|
+
this.rotateRequested = true;
|
|
1025
|
+
this.startDrain();
|
|
1026
|
+
await done;
|
|
1027
|
+
}
|
|
1028
|
+
enqueue(entry) {
|
|
1029
|
+
if (this.queueFull()) {
|
|
1030
|
+
if (this.queuePolicy === "drop-oldest" && this.batch.length > 0) {
|
|
1031
|
+
this.batch.shift();
|
|
1032
|
+
this.batch.push(entry);
|
|
1033
|
+
}
|
|
1034
|
+
this.noteDropped();
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
this.batch.push(entry);
|
|
1038
|
+
this.enqueued += 1;
|
|
1039
|
+
}
|
|
1040
|
+
queueFull() {
|
|
1041
|
+
return this.maxQueue !== void 0 && this.batch.length + this.inFlight >= this.maxQueue;
|
|
1042
|
+
}
|
|
1043
|
+
roomAvailable() {
|
|
1044
|
+
const room = new Promise((resolve) => this.spaceWaiters.push(resolve));
|
|
1045
|
+
this.startDrain();
|
|
1046
|
+
return room;
|
|
1047
|
+
}
|
|
1048
|
+
releaseWaiters() {
|
|
1049
|
+
const waiting = this.spaceWaiters;
|
|
1050
|
+
this.spaceWaiters = [];
|
|
1051
|
+
for (const resolve of waiting) resolve();
|
|
1052
|
+
}
|
|
1053
|
+
noteDropped() {
|
|
1054
|
+
this.dropped += 1;
|
|
1055
|
+
this.reportDropped(DROP_WARN_INTERVAL_MS);
|
|
1056
|
+
}
|
|
1057
|
+
reportDropped(minGapMs) {
|
|
1058
|
+
const now = Date.now();
|
|
1059
|
+
if (this.dropped === 0 || now - this.lastDropWarning < minGapMs) return;
|
|
1060
|
+
require_internal_log.internalWarn(`FileTransport: dropped ${this.dropped} log line${this.dropped === 1 ? "" : "s"} (queue full at maxQueue ${this.maxQueue}, policy ${this.queuePolicy})`);
|
|
1061
|
+
this.dropped = 0;
|
|
1062
|
+
this.lastDropWarning = now;
|
|
1063
|
+
}
|
|
1064
|
+
startDrain() {
|
|
1065
|
+
if (this.draining) return;
|
|
1066
|
+
this.draining = this.drain().finally(() => {
|
|
1067
|
+
this.draining = void 0;
|
|
992
1068
|
});
|
|
993
|
-
await this.flushPromise;
|
|
994
1069
|
}
|
|
995
1070
|
/**
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
*
|
|
1071
|
+
* Writes the batch one snapshot at a time. Entries queued while a write is in
|
|
1072
|
+
* flight are picked up by the next iteration, so one drain empties the batch
|
|
1073
|
+
* however much is logged meanwhile.
|
|
999
1074
|
*/
|
|
1000
1075
|
async drain() {
|
|
1001
|
-
while (this.batch.length > 0) {
|
|
1076
|
+
while (this.batch.length > 0 || this.rotateRequested) {
|
|
1077
|
+
if (this.rotateRequested) {
|
|
1078
|
+
this.rotateRequested = false;
|
|
1079
|
+
const waiting = this.rotationWaiters;
|
|
1080
|
+
this.rotationWaiters = [];
|
|
1081
|
+
try {
|
|
1082
|
+
await this.rotateFile();
|
|
1083
|
+
} catch (error) {
|
|
1084
|
+
require_internal_log.internalError("FileTransport rotation failed", error);
|
|
1085
|
+
}
|
|
1086
|
+
for (const resolve of waiting) resolve();
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1002
1089
|
const pending = this.batch;
|
|
1003
1090
|
this.batch = [];
|
|
1004
|
-
|
|
1091
|
+
this.inFlight = pending.length;
|
|
1092
|
+
let failure;
|
|
1093
|
+
try {
|
|
1094
|
+
await this.writeBatch(pending);
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
failure = error;
|
|
1097
|
+
}
|
|
1098
|
+
this.inFlight = 0;
|
|
1099
|
+
this.settled += pending.length;
|
|
1100
|
+
this.settle(failure);
|
|
1101
|
+
this.releaseWaiters();
|
|
1005
1102
|
}
|
|
1006
1103
|
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Resolves the flush() calls whose entries are now written. A failed batch
|
|
1106
|
+
* fails every flush still waiting, since each one covers that batch.
|
|
1107
|
+
*/
|
|
1108
|
+
settle(failure) {
|
|
1109
|
+
if (failure !== void 0) {
|
|
1110
|
+
if (this.flushWaiters.length === 0) require_internal_log.internalError("FileTransport write failed", failure);
|
|
1111
|
+
for (const waiter of this.flushWaiters) waiter.error ??= failure;
|
|
1112
|
+
}
|
|
1113
|
+
const waiting = [];
|
|
1114
|
+
for (const waiter of this.flushWaiters) if (waiter.upTo > this.settled) waiting.push(waiter);
|
|
1115
|
+
else if (waiter.error === void 0) waiter.resolve();
|
|
1116
|
+
else waiter.reject(waiter.error);
|
|
1117
|
+
this.flushWaiters = waiting;
|
|
1118
|
+
}
|
|
1007
1119
|
formatEntry(entry) {
|
|
1008
1120
|
switch (this.config.format) {
|
|
1009
|
-
case "json": return
|
|
1121
|
+
case "json": return require_safe_stringify.stringifyForLog({
|
|
1010
1122
|
timestamp: entry.timestamp.toISOString(),
|
|
1011
1123
|
level: entry.level,
|
|
1012
1124
|
message: entry.message,
|
|
1013
1125
|
...entry.data || {}
|
|
1014
1126
|
});
|
|
1015
1127
|
case "csv": {
|
|
1016
|
-
const safeMessage = safeToString(entry.message);
|
|
1128
|
+
const safeMessage = require_coerce_utils.safeToString(entry.message);
|
|
1017
1129
|
return [
|
|
1018
1130
|
entry.timestamp.toISOString(),
|
|
1019
1131
|
entry.level,
|
|
1020
1132
|
`"${safeMessage.replace(/"/g, "\"\"")}"`,
|
|
1021
|
-
safeToString(entry.context),
|
|
1022
|
-
safeToString(entry.traceId),
|
|
1023
|
-
|
|
1133
|
+
require_coerce_utils.safeToString(entry.context),
|
|
1134
|
+
require_coerce_utils.safeToString(entry.traceId),
|
|
1135
|
+
require_safe_stringify.stringifyForLog(entry.data || {})
|
|
1024
1136
|
].join(",");
|
|
1025
1137
|
}
|
|
1026
1138
|
case "text":
|
|
1027
|
-
default: return `${entry.timestamp.toISOString()} [${entry.level.toUpperCase()}] ${safeToString(entry.message)}${entry.data ? " " +
|
|
1139
|
+
default: return `${entry.timestamp.toISOString()} [${entry.level.toUpperCase()}] ${require_coerce_utils.safeToString(entry.message)}${entry.data ? " " + require_safe_stringify.stringifyForLog(entry.data) : ""}`;
|
|
1028
1140
|
}
|
|
1029
1141
|
}
|
|
1030
1142
|
addToBatch(entry) {
|
|
1031
|
-
this.
|
|
1032
|
-
|
|
1143
|
+
this.enqueue(entry);
|
|
1144
|
+
const threshold = Math.min(this.config.batchSize || 100, this.maxQueue ?? Infinity);
|
|
1145
|
+
if (this.batch.length >= threshold && !this.draining) {
|
|
1033
1146
|
if (this.batchTimer) {
|
|
1034
1147
|
clearTimeout(this.batchTimer);
|
|
1035
1148
|
this.batchTimer = void 0;
|
|
1036
1149
|
}
|
|
1037
|
-
this.
|
|
1150
|
+
this.startDrain();
|
|
1038
1151
|
} else if (!this.batchTimer && this.config.flushInterval) this.batchTimer = setTimeout(() => {
|
|
1039
|
-
this.flush().catch((err) => internalError("FileTransport interval flush failed", err));
|
|
1152
|
+
this.flush().catch((err) => require_internal_log.internalError("FileTransport interval flush failed", err));
|
|
1040
1153
|
}, this.config.flushInterval);
|
|
1041
1154
|
}
|
|
1155
|
+
/** Only ever called from drain(), so writes and rotations never overlap. */
|
|
1042
1156
|
async writeBatch(entries) {
|
|
1043
1157
|
if (entries.length === 0) return;
|
|
1044
|
-
|
|
1045
|
-
if (this.
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1158
|
+
if (this.timeToRotate()) await this.rotateFile();
|
|
1159
|
+
if (this.maxBytes === void 0) {
|
|
1160
|
+
const content = entries.map((entry) => this.formatEntry(entry)).join("\n") + "\n";
|
|
1161
|
+
await this.append(content);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
let chunk$1 = "";
|
|
1165
|
+
let chunkBytes = 0;
|
|
1166
|
+
for (const entry of entries) {
|
|
1167
|
+
const line = this.formatEntry(entry) + "\n";
|
|
1168
|
+
const lineBytes = Buffer.byteLength(line);
|
|
1169
|
+
const used = this.bytesWritten + chunkBytes;
|
|
1170
|
+
if (used > 0 && used + lineBytes > this.maxBytes) {
|
|
1171
|
+
if (chunk$1) await this.append(chunk$1, chunkBytes);
|
|
1172
|
+
chunk$1 = "";
|
|
1173
|
+
chunkBytes = 0;
|
|
1174
|
+
await this.rotateFile();
|
|
1175
|
+
}
|
|
1176
|
+
chunk$1 += line;
|
|
1177
|
+
chunkBytes += lineBytes;
|
|
1178
|
+
}
|
|
1179
|
+
if (chunk$1) await this.append(chunk$1, chunkBytes);
|
|
1052
1180
|
}
|
|
1053
|
-
|
|
1181
|
+
async append(content, bytes = Buffer.byteLength(content)) {
|
|
1182
|
+
await appendFile(this.currentFilePath, content);
|
|
1183
|
+
this.bytesWritten += bytes;
|
|
1184
|
+
}
|
|
1185
|
+
timeToRotate() {
|
|
1054
1186
|
var _this$config$rotation;
|
|
1055
|
-
if (
|
|
1056
|
-
|
|
1187
|
+
if (this.intervalMs !== void 0 && Date.now() - this.lastRotation.getTime() >= this.intervalMs) return true;
|
|
1188
|
+
if (this.config.datePattern && this.period !== void 0) {
|
|
1189
|
+
if (formatDatePattern(/* @__PURE__ */ new Date(), this.config.datePattern) !== this.period) return true;
|
|
1190
|
+
}
|
|
1191
|
+
const shouldRotate = (_this$config$rotation = this.config.rotation) === null || _this$config$rotation === void 0 ? void 0 : _this$config$rotation.shouldRotate;
|
|
1192
|
+
if (shouldRotate) {
|
|
1193
|
+
const stats = {
|
|
1194
|
+
size: this.bytesWritten,
|
|
1195
|
+
created: this.lastRotation,
|
|
1196
|
+
modified: /* @__PURE__ */ new Date()
|
|
1197
|
+
};
|
|
1198
|
+
try {
|
|
1199
|
+
return shouldRotate(this.currentFilePath, stats);
|
|
1200
|
+
} catch (error) {
|
|
1201
|
+
require_internal_log.internalError("FileTransport rotation.shouldRotate threw", error);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return false;
|
|
1057
1205
|
}
|
|
1058
1206
|
parseInterval(interval) {
|
|
1059
|
-
const match = (
|
|
1207
|
+
const match = /^(\d{1,6})([hdwmy])$/i.exec(interval.trim());
|
|
1060
1208
|
if (!match) return 1440 * 60 * 1e3;
|
|
1061
1209
|
const value = Number.parseInt(match[1] || "1", 10);
|
|
1062
1210
|
switch ((match[2] || "h").toLowerCase()) {
|
|
@@ -1068,40 +1216,54 @@ var FileTransport = class {
|
|
|
1068
1216
|
default: return value * 60 * 60 * 1e3;
|
|
1069
1217
|
}
|
|
1070
1218
|
}
|
|
1071
|
-
async
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
if (this.
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
this.
|
|
1219
|
+
async rotateFile() {
|
|
1220
|
+
const now = /* @__PURE__ */ new Date();
|
|
1221
|
+
let archived;
|
|
1222
|
+
if (this.timestampedActive) {
|
|
1223
|
+
archived = this.currentFilePath;
|
|
1224
|
+
this.currentFilePath = this.uniquePath(this.timestamp(now));
|
|
1225
|
+
} else {
|
|
1226
|
+
archived = this.uniquePath(this.period ?? this.timestamp(now));
|
|
1227
|
+
try {
|
|
1228
|
+
await rename(this.currentFilePath, archived);
|
|
1229
|
+
} catch (error) {
|
|
1230
|
+
if (error.code !== "ENOENT") {
|
|
1231
|
+
require_internal_log.internalError(`FileTransport could not rotate ${this.currentFilePath}`, error);
|
|
1232
|
+
this.bytesWritten = 0;
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
archived = void 0;
|
|
1236
|
+
}
|
|
1079
1237
|
}
|
|
1080
|
-
|
|
1081
|
-
this.
|
|
1082
|
-
this.
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
1238
|
+
this.bytesWritten = 0;
|
|
1239
|
+
this.lastRotation = now;
|
|
1240
|
+
if (this.config.datePattern) this.period = formatDatePattern(now, this.config.datePattern);
|
|
1241
|
+
if (archived === void 0 || !node_fs.existsSync(archived)) return;
|
|
1242
|
+
const file = archived;
|
|
1243
|
+
this.housekeeping = this.housekeeping.then(async () => {
|
|
1244
|
+
if (this.compress) await this.compressFile(file);
|
|
1245
|
+
if (this.maxFiles) await this.cleanupOldFiles();
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
timestamp(date) {
|
|
1249
|
+
return date.toISOString().replace(/[:.]/g, "-").slice(0, 23);
|
|
1250
|
+
}
|
|
1251
|
+
/** `<base>-<stamp><ext>`, with `.1`, `.2`… added if that name (or its .gz) is taken. */
|
|
1252
|
+
uniquePath(stamp) {
|
|
1253
|
+
const taken = (p) => node_fs.existsSync(p) || node_fs.existsSync(`${p}.gz`);
|
|
1254
|
+
let candidate = node_path.join(this.dir, `${this.base}-${stamp}${this.ext}`);
|
|
1255
|
+
let n = 0;
|
|
1256
|
+
while (taken(candidate) || candidate === this.currentFilePath) {
|
|
1257
|
+
n += 1;
|
|
1258
|
+
candidate = node_path.join(this.dir, `${this.base}-${stamp}.${n}${this.ext}`);
|
|
1259
|
+
}
|
|
1260
|
+
return candidate;
|
|
1085
1261
|
}
|
|
1086
1262
|
resolveDir() {
|
|
1087
1263
|
if (this.config.dirname) return this.config.dirname;
|
|
1088
1264
|
const fromFilename = node_path.dirname(this.config.filename);
|
|
1089
1265
|
return fromFilename === "." ? process.cwd() : fromFilename;
|
|
1090
1266
|
}
|
|
1091
|
-
generateFilePath() {
|
|
1092
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
1093
|
-
const dir = this.resolveDir();
|
|
1094
|
-
const ext = node_path.extname(this.config.filename);
|
|
1095
|
-
const base = node_path.basename(this.config.filename, ext);
|
|
1096
|
-
if (this.config.rotation) return node_path.join(dir, `${base}-${timestamp}${ext}`);
|
|
1097
|
-
return node_path.join(dir, `${base}${ext}`);
|
|
1098
|
-
}
|
|
1099
|
-
async ensureDirectoryExists() {
|
|
1100
|
-
const dir = this.resolveDir();
|
|
1101
|
-
try {
|
|
1102
|
-
await mkdir(dir, { recursive: true });
|
|
1103
|
-
} catch {}
|
|
1104
|
-
}
|
|
1105
1267
|
/**
|
|
1106
1268
|
* Gzip the rotated file to `<file>.gz` and remove the original. Streams the
|
|
1107
1269
|
* data so large log files don't have to be buffered in memory. Best-effort:
|
|
@@ -1114,39 +1276,48 @@ var FileTransport = class {
|
|
|
1114
1276
|
await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath));
|
|
1115
1277
|
await unlink(filePath);
|
|
1116
1278
|
} catch (error) {
|
|
1117
|
-
internalError("Failed to compress rotated log file", error);
|
|
1279
|
+
require_internal_log.internalError("Failed to compress rotated log file", error);
|
|
1118
1280
|
try {
|
|
1119
1281
|
await unlink(gzPath);
|
|
1120
1282
|
} catch {}
|
|
1121
1283
|
}
|
|
1122
1284
|
}
|
|
1285
|
+
/**
|
|
1286
|
+
* True for this transport's rotated files only: `<base>-<stamp><ext>` where the
|
|
1287
|
+
* stamp is digits and separators, optionally `.gz`. Another transport's
|
|
1288
|
+
* `app-error.log` must not count as one of `app.log`'s rotations.
|
|
1289
|
+
*/
|
|
1290
|
+
isOwnRotatedFile(file) {
|
|
1291
|
+
const name = file.endsWith(".gz") ? file.slice(0, -3) : file;
|
|
1292
|
+
if (!name.startsWith(`${this.base}-`) || !name.endsWith(this.ext)) return false;
|
|
1293
|
+
const stamp = name.slice(this.base.length + 1, name.length - this.ext.length);
|
|
1294
|
+
return /^\d[\d\-_.T]*$/.test(stamp);
|
|
1295
|
+
}
|
|
1123
1296
|
async cleanupOldFiles() {
|
|
1124
|
-
|
|
1125
|
-
if (!((_this$config$rotation4 = this.config.rotation) === null || _this$config$rotation4 === void 0 ? void 0 : _this$config$rotation4.maxFiles)) return;
|
|
1297
|
+
if (!this.maxFiles) return;
|
|
1126
1298
|
try {
|
|
1127
|
-
const
|
|
1128
|
-
const
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1131
|
-
const isOwnRotatedFile = (file) => file.startsWith(`${base}-`) && (file.endsWith(ext) || file.endsWith(`${ext}.gz`));
|
|
1132
|
-
const logFiles = files.filter(isOwnRotatedFile).map(async (file) => {
|
|
1133
|
-
const filePath = node_path.join(dir, file);
|
|
1299
|
+
const files = await readdir(this.dir);
|
|
1300
|
+
const active = node_path.basename(this.currentFilePath);
|
|
1301
|
+
const newestFirst = (await Promise.all(files.filter((file) => file !== active && this.isOwnRotatedFile(file)).map(async (file) => {
|
|
1302
|
+
const filePath = node_path.join(this.dir, file);
|
|
1134
1303
|
return {
|
|
1135
1304
|
path: filePath,
|
|
1136
|
-
mtime: (await stat(filePath)).
|
|
1305
|
+
mtime: (await stat(filePath)).mtimeMs
|
|
1137
1306
|
};
|
|
1138
|
-
});
|
|
1139
|
-
const
|
|
1140
|
-
for (const file of filesToDelete) await unlink(file.path);
|
|
1307
|
+
}))).sort((a, b) => b.mtime - a.mtime || b.path.localeCompare(a.path));
|
|
1308
|
+
for (const file of newestFirst.slice(this.maxFiles)) await unlink(file.path);
|
|
1141
1309
|
} catch (error) {
|
|
1142
|
-
internalError("Failed to cleanup old log files", error);
|
|
1310
|
+
require_internal_log.internalError("Failed to cleanup old log files", error);
|
|
1143
1311
|
}
|
|
1144
1312
|
}
|
|
1145
1313
|
async close() {
|
|
1314
|
+
if (this.batchTimer) {
|
|
1315
|
+
clearTimeout(this.batchTimer);
|
|
1316
|
+
this.batchTimer = void 0;
|
|
1317
|
+
}
|
|
1146
1318
|
await this.flush();
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
});
|
|
1319
|
+
await this.housekeeping;
|
|
1320
|
+
this.reportDropped(0);
|
|
1150
1321
|
}
|
|
1151
1322
|
};
|
|
1152
1323
|
|
|
@@ -1171,10 +1342,9 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1171
1342
|
try {
|
|
1172
1343
|
if (!this.gaConfig.measurementId) throw new Error("Google Analytics Measurement ID is required");
|
|
1173
1344
|
if (!this.gaConfig.apiSecret) throw new Error("Google Analytics API Secret is required");
|
|
1174
|
-
await this.testConnection();
|
|
1175
1345
|
this.isReady = true;
|
|
1176
1346
|
} catch (error) {
|
|
1177
|
-
internalError("Google Analytics transport initialization failed", error);
|
|
1347
|
+
require_internal_log.internalError("Google Analytics transport initialization failed", error);
|
|
1178
1348
|
throw error;
|
|
1179
1349
|
}
|
|
1180
1350
|
}
|
|
@@ -1240,10 +1410,10 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1240
1410
|
}
|
|
1241
1411
|
async sendEvents(events) {
|
|
1242
1412
|
const chunks = this.chunkArray(events, 25);
|
|
1243
|
-
for (const chunk of chunks) {
|
|
1413
|
+
for (const chunk$1 of chunks) {
|
|
1244
1414
|
const payload = {
|
|
1245
1415
|
client_id: this.gaConfig.clientId || this.generateClientId(),
|
|
1246
|
-
events: chunk
|
|
1416
|
+
events: chunk$1
|
|
1247
1417
|
};
|
|
1248
1418
|
await this.makeRequest(payload);
|
|
1249
1419
|
}
|
|
@@ -1258,7 +1428,7 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1258
1428
|
const response = await fetch(`${url}?${params}`, {
|
|
1259
1429
|
method: "POST",
|
|
1260
1430
|
headers: { "Content-Type": "application/json" },
|
|
1261
|
-
body:
|
|
1431
|
+
body: require_safe_stringify.stringifyForLog(payload)
|
|
1262
1432
|
});
|
|
1263
1433
|
if (!response.ok) {
|
|
1264
1434
|
const errorText = await response.text();
|
|
@@ -1266,28 +1436,12 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1266
1436
|
}
|
|
1267
1437
|
if (debug) {
|
|
1268
1438
|
const result = await response.json();
|
|
1269
|
-
internalLog(`GA4 Debug Response: ${JSON.stringify(result)}`);
|
|
1439
|
+
require_internal_log.internalLog(`GA4 Debug Response: ${JSON.stringify(result)}`);
|
|
1270
1440
|
}
|
|
1271
1441
|
} catch (error) {
|
|
1272
1442
|
throw new Error(`Failed to send data to Google Analytics: ${error.message}`, { cause: error });
|
|
1273
1443
|
}
|
|
1274
1444
|
}
|
|
1275
|
-
async testConnection() {
|
|
1276
|
-
const testEvent = {
|
|
1277
|
-
name: "logitron_test",
|
|
1278
|
-
params: {
|
|
1279
|
-
event_category: "Test",
|
|
1280
|
-
event_label: "Connection Test",
|
|
1281
|
-
test: true,
|
|
1282
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
1285
|
-
const payload = {
|
|
1286
|
-
client_id: this.gaConfig.clientId || this.generateClientId(),
|
|
1287
|
-
events: [testEvent]
|
|
1288
|
-
};
|
|
1289
|
-
await this.makeRequest(payload, true);
|
|
1290
|
-
}
|
|
1291
1445
|
generateClientId() {
|
|
1292
1446
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
1293
1447
|
const r = Math.random() * 16 | 0;
|
|
@@ -1398,10 +1552,9 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1398
1552
|
async initialize() {
|
|
1399
1553
|
try {
|
|
1400
1554
|
if (!this.mixpanelConfig.token) throw new Error("Mixpanel token is required");
|
|
1401
|
-
await this.testConnection();
|
|
1402
1555
|
this.isReady = true;
|
|
1403
1556
|
} catch (error) {
|
|
1404
|
-
internalError("Mixpanel transport initialization failed", error);
|
|
1557
|
+
require_internal_log.internalError("Mixpanel transport initialization failed", error);
|
|
1405
1558
|
throw error;
|
|
1406
1559
|
}
|
|
1407
1560
|
}
|
|
@@ -1457,7 +1610,7 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1457
1610
|
"Content-Type": "application/json",
|
|
1458
1611
|
Accept: "text/plain"
|
|
1459
1612
|
},
|
|
1460
|
-
body:
|
|
1613
|
+
body: require_safe_stringify.stringifyForLog(data)
|
|
1461
1614
|
});
|
|
1462
1615
|
if (!response.ok) throw new Error(`Mixpanel API error: ${response.status} ${response.statusText}`);
|
|
1463
1616
|
const result = await response.text();
|
|
@@ -1466,18 +1619,6 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1466
1619
|
throw new Error(`Failed to send data to Mixpanel: ${error.message}`, { cause: error });
|
|
1467
1620
|
}
|
|
1468
1621
|
}
|
|
1469
|
-
async testConnection() {
|
|
1470
|
-
const testEvent = {
|
|
1471
|
-
event: "logitron_test",
|
|
1472
|
-
properties: {
|
|
1473
|
-
token: this.mixpanelConfig.token,
|
|
1474
|
-
distinct_id: "test_user",
|
|
1475
|
-
test: true,
|
|
1476
|
-
time: Date.now()
|
|
1477
|
-
}
|
|
1478
|
-
};
|
|
1479
|
-
await this.makeRequest("/track", [testEvent]);
|
|
1480
|
-
}
|
|
1481
1622
|
generateInsertId(entry) {
|
|
1482
1623
|
return `${entry.timestamp.getTime()}_${this.simpleHash(entry.message + (entry.traceId || ""))}`;
|
|
1483
1624
|
}
|
|
@@ -1524,6 +1665,17 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1524
1665
|
}
|
|
1525
1666
|
};
|
|
1526
1667
|
|
|
1668
|
+
//#endregion
|
|
1669
|
+
//#region src/version.ts
|
|
1670
|
+
/**
|
|
1671
|
+
* The published version of this package.
|
|
1672
|
+
*
|
|
1673
|
+
* Kept in sync with `version` in package.json by the release process. Importing
|
|
1674
|
+
* from here (instead of reading package.json at runtime) keeps the built `dist`
|
|
1675
|
+
* free of a JSON import that bundlers and consumers would have to resolve.
|
|
1676
|
+
*/
|
|
1677
|
+
const LOGIXIA_VERSION = "1.12.0";
|
|
1678
|
+
|
|
1527
1679
|
//#endregion
|
|
1528
1680
|
//#region src/transports/segment.transport.ts
|
|
1529
1681
|
/**
|
|
@@ -1547,10 +1699,9 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1547
1699
|
async initialize() {
|
|
1548
1700
|
try {
|
|
1549
1701
|
if (!this.segmentConfig.writeKey) throw new Error("Segment Write Key is required");
|
|
1550
|
-
await this.testConnection();
|
|
1551
1702
|
this.isReady = true;
|
|
1552
1703
|
} catch (error) {
|
|
1553
|
-
internalError("Segment transport initialization failed", error);
|
|
1704
|
+
require_internal_log.internalError("Segment transport initialization failed", error);
|
|
1554
1705
|
throw error;
|
|
1555
1706
|
}
|
|
1556
1707
|
}
|
|
@@ -1588,7 +1739,7 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1588
1739
|
context: {
|
|
1589
1740
|
library: {
|
|
1590
1741
|
name: "logixia",
|
|
1591
|
-
version:
|
|
1742
|
+
version: LOGIXIA_VERSION
|
|
1592
1743
|
},
|
|
1593
1744
|
app: {
|
|
1594
1745
|
name: entry.appName || "unknown",
|
|
@@ -1608,8 +1759,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1608
1759
|
}
|
|
1609
1760
|
async batchTrack(events) {
|
|
1610
1761
|
const chunks = this.chunkArray(events, this.segmentConfig.maxBatchSize || 100);
|
|
1611
|
-
for (const chunk of chunks) {
|
|
1612
|
-
const payload = { batch: chunk };
|
|
1762
|
+
for (const chunk$1 of chunks) {
|
|
1763
|
+
const payload = { batch: chunk$1 };
|
|
1613
1764
|
await this.makeRequest("/v1/batch", payload);
|
|
1614
1765
|
}
|
|
1615
1766
|
}
|
|
@@ -1622,9 +1773,9 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1622
1773
|
headers: {
|
|
1623
1774
|
"Content-Type": "application/json",
|
|
1624
1775
|
Authorization: `Basic ${auth}`,
|
|
1625
|
-
"User-Agent":
|
|
1776
|
+
"User-Agent": `logixia/${LOGIXIA_VERSION}`
|
|
1626
1777
|
},
|
|
1627
|
-
body:
|
|
1778
|
+
body: require_safe_stringify.stringifyForLog(data)
|
|
1628
1779
|
});
|
|
1629
1780
|
if (!response.ok) {
|
|
1630
1781
|
const errorText = await response.text();
|
|
@@ -1634,24 +1785,6 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1634
1785
|
throw new Error(`Failed to send data to Segment: ${error.message}`, { cause: error });
|
|
1635
1786
|
}
|
|
1636
1787
|
}
|
|
1637
|
-
async testConnection() {
|
|
1638
|
-
const testEvent = {
|
|
1639
|
-
type: "track",
|
|
1640
|
-
event: "Logixia Test",
|
|
1641
|
-
userId: "test-user",
|
|
1642
|
-
anonymousId: this.generateAnonymousId(),
|
|
1643
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1644
|
-
properties: {
|
|
1645
|
-
test: true,
|
|
1646
|
-
source: "logixia"
|
|
1647
|
-
},
|
|
1648
|
-
context: { library: {
|
|
1649
|
-
name: "logixia",
|
|
1650
|
-
version: "1.0.0"
|
|
1651
|
-
} }
|
|
1652
|
-
};
|
|
1653
|
-
await this.makeRequest("/v1/track", testEvent);
|
|
1654
|
-
}
|
|
1655
1788
|
extractUserId(entry) {
|
|
1656
1789
|
if (entry.data) {
|
|
1657
1790
|
const d = entry.data;
|
|
@@ -1681,8 +1814,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1681
1814
|
...user.traits
|
|
1682
1815
|
},
|
|
1683
1816
|
context: { library: {
|
|
1684
|
-
name: "
|
|
1685
|
-
version:
|
|
1817
|
+
name: "logixia",
|
|
1818
|
+
version: LOGIXIA_VERSION
|
|
1686
1819
|
} }
|
|
1687
1820
|
};
|
|
1688
1821
|
await this.makeRequest("/v1/identify", payload);
|
|
@@ -1700,8 +1833,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1700
1833
|
},
|
|
1701
1834
|
context: {
|
|
1702
1835
|
library: {
|
|
1703
|
-
name: "
|
|
1704
|
-
version:
|
|
1836
|
+
name: "logixia",
|
|
1837
|
+
version: LOGIXIA_VERSION
|
|
1705
1838
|
},
|
|
1706
1839
|
page: {
|
|
1707
1840
|
url: properties.url || `/${name.toLowerCase().replace(/\s+/g, "-")}`,
|
|
@@ -1720,8 +1853,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1720
1853
|
properties: { ...properties },
|
|
1721
1854
|
context: {
|
|
1722
1855
|
library: {
|
|
1723
|
-
name: "
|
|
1724
|
-
version:
|
|
1856
|
+
name: "logixia",
|
|
1857
|
+
version: LOGIXIA_VERSION
|
|
1725
1858
|
},
|
|
1726
1859
|
screen: { name }
|
|
1727
1860
|
}
|
|
@@ -1737,8 +1870,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1737
1870
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1738
1871
|
traits,
|
|
1739
1872
|
context: { library: {
|
|
1740
|
-
name: "
|
|
1741
|
-
version:
|
|
1873
|
+
name: "logixia",
|
|
1874
|
+
version: LOGIXIA_VERSION
|
|
1742
1875
|
} }
|
|
1743
1876
|
};
|
|
1744
1877
|
await this.makeRequest("/v1/group", payload);
|
|
@@ -1750,8 +1883,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1750
1883
|
previousId,
|
|
1751
1884
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1752
1885
|
context: { library: {
|
|
1753
|
-
name: "
|
|
1754
|
-
version:
|
|
1886
|
+
name: "logixia",
|
|
1887
|
+
version: LOGIXIA_VERSION
|
|
1755
1888
|
} }
|
|
1756
1889
|
};
|
|
1757
1890
|
await this.makeRequest("/v1/alias", payload);
|
|
@@ -1765,8 +1898,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1765
1898
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1766
1899
|
properties,
|
|
1767
1900
|
context: { library: {
|
|
1768
|
-
name: "
|
|
1769
|
-
version:
|
|
1901
|
+
name: "logixia",
|
|
1902
|
+
version: LOGIXIA_VERSION
|
|
1770
1903
|
} }
|
|
1771
1904
|
};
|
|
1772
1905
|
await this.makeRequest("/v1/track", payload);
|
|
@@ -1784,8 +1917,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1784
1917
|
products
|
|
1785
1918
|
},
|
|
1786
1919
|
context: { library: {
|
|
1787
|
-
name: "
|
|
1788
|
-
version:
|
|
1920
|
+
name: "logixia",
|
|
1921
|
+
version: LOGIXIA_VERSION
|
|
1789
1922
|
} }
|
|
1790
1923
|
};
|
|
1791
1924
|
await this.makeRequest("/v1/track", payload);
|
|
@@ -1798,8 +1931,8 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1798
1931
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1799
1932
|
properties: product,
|
|
1800
1933
|
context: { library: {
|
|
1801
|
-
name: "
|
|
1802
|
-
version:
|
|
1934
|
+
name: "logixia",
|
|
1935
|
+
version: LOGIXIA_VERSION
|
|
1803
1936
|
} }
|
|
1804
1937
|
};
|
|
1805
1938
|
await this.makeRequest("/v1/track", payload);
|
|
@@ -1818,7 +1951,7 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
1818
1951
|
this.metrics = /* @__PURE__ */ new Map();
|
|
1819
1952
|
this.isShuttingDown = false;
|
|
1820
1953
|
this.transportLevelPreferences = /* @__PURE__ */ new Map();
|
|
1821
|
-
this.
|
|
1954
|
+
this.warnedPromptDeprecated = false;
|
|
1822
1955
|
this.setupTransports(config);
|
|
1823
1956
|
}
|
|
1824
1957
|
setupTransports(config) {
|
|
@@ -1918,17 +2051,24 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
1918
2051
|
if (entry.context !== void 0) transportEntry.context = entry.context;
|
|
1919
2052
|
if (entry.traceId !== void 0) transportEntry.traceId = entry.traceId;
|
|
1920
2053
|
if (entry.environment !== void 0) transportEntry.environment = entry.environment;
|
|
1921
|
-
if (this.promptForLevels) return this._writeAsyncWithPrompt(transportEntry);
|
|
1922
2054
|
let pending;
|
|
2055
|
+
let syncFailure;
|
|
1923
2056
|
for (const [id, transport] of this.transports) {
|
|
1924
2057
|
if (!this.shouldTransportHandle(transport, transportEntry.level, id)) continue;
|
|
1925
2058
|
if (transport.filter && !transport.filter(transportEntry)) continue;
|
|
1926
|
-
|
|
2059
|
+
let result;
|
|
2060
|
+
try {
|
|
2061
|
+
result = this.writeToTransport(id, transport, transportEntry);
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
syncFailure ??= { error };
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
1927
2066
|
if (result && typeof result.then === "function") {
|
|
1928
2067
|
if (pending === void 0) pending = [];
|
|
1929
2068
|
pending.push(result);
|
|
1930
2069
|
}
|
|
1931
2070
|
}
|
|
2071
|
+
if (syncFailure) throw syncFailure.error;
|
|
1932
2072
|
if (pending === void 0) return;
|
|
1933
2073
|
return Promise.allSettled(pending).then((results) => {
|
|
1934
2074
|
const failures = results.filter((r) => r.status === "rejected");
|
|
@@ -1938,22 +2078,6 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
1938
2078
|
}
|
|
1939
2079
|
});
|
|
1940
2080
|
}
|
|
1941
|
-
/** Slow path used only when interactive level-prompting is enabled. */
|
|
1942
|
-
async _writeAsyncWithPrompt(transportEntry) {
|
|
1943
|
-
const writePromises = [];
|
|
1944
|
-
for (const [id, transport] of this.transports) {
|
|
1945
|
-
if (!this.transportLevelPreferences.has(id)) await this.configureTransportLevels(id);
|
|
1946
|
-
if (!this.shouldTransportHandle(transport, transportEntry.level, id)) continue;
|
|
1947
|
-
if (transport.filter && !transport.filter(transportEntry)) continue;
|
|
1948
|
-
const result = this.writeToTransport(id, transport, transportEntry);
|
|
1949
|
-
if (result && typeof result.then === "function") writePromises.push(result);
|
|
1950
|
-
}
|
|
1951
|
-
const failures = (await Promise.allSettled(writePromises)).filter((r) => r.status === "rejected");
|
|
1952
|
-
if (failures.length > 0) {
|
|
1953
|
-
const errors = failures.map((f) => f.reason);
|
|
1954
|
-
this.emit("error", /* @__PURE__ */ new Error(`Transport write failures: ${errors.join(", ")}`), "multiple");
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
2081
|
writeToTransport(id, transport, entry) {
|
|
1958
2082
|
const startTime = Date.now();
|
|
1959
2083
|
const metrics = this.metrics.get(id);
|
|
@@ -2140,63 +2264,29 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2140
2264
|
details
|
|
2141
2265
|
};
|
|
2142
2266
|
}
|
|
2267
|
+
/** @deprecated Library code never prompts on stdin. Use setTransportLevels(). No-op. */
|
|
2143
2268
|
enableLevelPrompting() {
|
|
2144
|
-
this.
|
|
2145
|
-
internalLog("Transport level prompting enabled");
|
|
2269
|
+
this.warnPromptingRemoved();
|
|
2146
2270
|
}
|
|
2271
|
+
/** @deprecated Library code never prompts on stdin. No-op. */
|
|
2147
2272
|
disableLevelPrompting() {
|
|
2148
|
-
this.
|
|
2149
|
-
internalLog("Transport level prompting disabled");
|
|
2150
|
-
}
|
|
2151
|
-
async promptUserForTransportLevels(transportId) {
|
|
2152
|
-
const availableLevels = [
|
|
2153
|
-
"error",
|
|
2154
|
-
"warn",
|
|
2155
|
-
"info",
|
|
2156
|
-
"debug",
|
|
2157
|
-
"trace",
|
|
2158
|
-
"verbose"
|
|
2159
|
-
];
|
|
2160
|
-
return new Promise((resolve) => {
|
|
2161
|
-
const rl = node_readline.createInterface({
|
|
2162
|
-
input: process.stdin,
|
|
2163
|
-
output: process.stdout
|
|
2164
|
-
});
|
|
2165
|
-
process.stdout.write(`\nConfigure log levels for transport '${transportId}'\n`);
|
|
2166
|
-
process.stdout.write(`Available levels: ${availableLevels.join(", ")}\n`);
|
|
2167
|
-
process.stdout.write("Enter levels separated by commas (e.g., error,warn,info) or \"all\" for all levels:\n");
|
|
2168
|
-
rl.question("> ", (answer) => {
|
|
2169
|
-
rl.close();
|
|
2170
|
-
if (answer.toLowerCase().trim() === "all") resolve(availableLevels);
|
|
2171
|
-
else {
|
|
2172
|
-
const selectedLevels = answer.split(",").map((level) => level.trim().toLowerCase()).filter((level) => availableLevels.includes(level));
|
|
2173
|
-
if (selectedLevels.length === 0) {
|
|
2174
|
-
internalWarn("No valid levels selected, using all levels");
|
|
2175
|
-
resolve(availableLevels);
|
|
2176
|
-
} else {
|
|
2177
|
-
internalLog(`Selected levels for ${transportId}: ${selectedLevels.join(", ")}`);
|
|
2178
|
-
resolve(selectedLevels);
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
});
|
|
2182
|
-
});
|
|
2273
|
+
this.warnPromptingRemoved();
|
|
2183
2274
|
}
|
|
2184
|
-
|
|
2185
|
-
if (this.
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
}
|
|
2275
|
+
warnPromptingRemoved() {
|
|
2276
|
+
if (this.warnedPromptDeprecated) return;
|
|
2277
|
+
this.warnedPromptDeprecated = true;
|
|
2278
|
+
require_internal_log.internalWarn("Transport level prompting was removed: logixia never reads stdin. Use setTransportLevels(id, levels) instead.");
|
|
2189
2279
|
}
|
|
2190
2280
|
setTransportLevels(transportId, levels) {
|
|
2191
2281
|
this.transportLevelPreferences.set(transportId, levels);
|
|
2192
|
-
internalLog(`Transport '${transportId}' configured for levels: ${levels.join(", ")}`);
|
|
2282
|
+
require_internal_log.internalLog(`Transport '${transportId}' configured for levels: ${levels.join(", ")}`);
|
|
2193
2283
|
}
|
|
2194
2284
|
getTransportLevels(transportId) {
|
|
2195
2285
|
return this.transportLevelPreferences.get(transportId);
|
|
2196
2286
|
}
|
|
2197
2287
|
clearTransportLevelPreferences() {
|
|
2198
2288
|
this.transportLevelPreferences.clear();
|
|
2199
|
-
internalLog("Transport level preferences cleared");
|
|
2289
|
+
require_internal_log.internalLog("Transport level preferences cleared");
|
|
2200
2290
|
}
|
|
2201
2291
|
};
|
|
2202
2292
|
|
|
@@ -2255,34 +2345,4 @@ Object.defineProperty(exports, 'TransportManager', {
|
|
|
2255
2345
|
return TransportManager;
|
|
2256
2346
|
}
|
|
2257
2347
|
});
|
|
2258
|
-
|
|
2259
|
-
enumerable: true,
|
|
2260
|
-
get: function () {
|
|
2261
|
-
return __toESM;
|
|
2262
|
-
}
|
|
2263
|
-
});
|
|
2264
|
-
Object.defineProperty(exports, 'internalError', {
|
|
2265
|
-
enumerable: true,
|
|
2266
|
-
get: function () {
|
|
2267
|
-
return internalError;
|
|
2268
|
-
}
|
|
2269
|
-
});
|
|
2270
|
-
Object.defineProperty(exports, 'internalLog', {
|
|
2271
|
-
enumerable: true,
|
|
2272
|
-
get: function () {
|
|
2273
|
-
return internalLog;
|
|
2274
|
-
}
|
|
2275
|
-
});
|
|
2276
|
-
Object.defineProperty(exports, 'internalWarn', {
|
|
2277
|
-
enumerable: true,
|
|
2278
|
-
get: function () {
|
|
2279
|
-
return internalWarn;
|
|
2280
|
-
}
|
|
2281
|
-
});
|
|
2282
|
-
Object.defineProperty(exports, 'safeToString', {
|
|
2283
|
-
enumerable: true,
|
|
2284
|
-
get: function () {
|
|
2285
|
-
return safeToString;
|
|
2286
|
-
}
|
|
2287
|
-
});
|
|
2288
|
-
//# sourceMappingURL=transport.manager-ciG4r5uz.js.map
|
|
2348
|
+
//# sourceMappingURL=transport.manager-BivyUTtU.js.map
|