logixia 1.12.6 → 1.13.3
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 +19 -4
- package/dist/{async-context-CwBNMm2E.mjs → async-context-BzJrbfQs.mjs} +8 -4
- package/dist/async-context-BzJrbfQs.mjs.map +1 -0
- package/dist/{async-context-CSHWoHMB.js → async-context-DyQQYq3I.js} +8 -4
- package/dist/async-context-DyQQYq3I.js.map +1 -0
- package/dist/{azure-monitor.transport-CG7ClkYj.d.ts → azure-monitor.transport-BDFO4F-i.d.ts} +2 -2
- package/dist/{azure-monitor.transport-CG7ClkYj.d.ts.map → azure-monitor.transport-BDFO4F-i.d.ts.map} +1 -1
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts → azure-monitor.transport-D5wQEH04.d.mts} +2 -2
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts.map → azure-monitor.transport-D5wQEH04.d.mts.map} +1 -1
- package/dist/azure.d.mts +2 -2
- package/dist/azure.d.ts +2 -2
- package/dist/cli/index.js +98 -52
- package/dist/cloudwatch.d.mts +2 -2
- package/dist/cloudwatch.d.ts +2 -2
- package/dist/cloudwatch.js +2 -1
- package/dist/cloudwatch.mjs +2 -1
- package/dist/{cloudwatch.transport-CGHY4buE.d.mts → cloudwatch.transport-B00st6Xv.d.ts} +9 -2
- package/dist/cloudwatch.transport-B00st6Xv.d.ts.map +1 -0
- package/dist/{cloudwatch.transport-pNBNWJLt.js → cloudwatch.transport-BO1ahxw-.js} +26 -19
- package/dist/cloudwatch.transport-BO1ahxw-.js.map +1 -0
- package/dist/{cloudwatch.transport-DK_8cKd3.d.ts → cloudwatch.transport-Blc7Gtxt.d.mts} +9 -2
- package/dist/cloudwatch.transport-Blc7Gtxt.d.mts.map +1 -0
- package/dist/{cloudwatch.transport-yBwm4OeO.mjs → cloudwatch.transport-DZ6ies7g.mjs} +26 -19
- package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +1 -0
- package/dist/{coerce.utils-BN980Y9V.js → coerce.utils-B-LilukN.js} +1 -1
- package/dist/{coerce.utils-BN980Y9V.js.map → coerce.utils-B-LilukN.js.map} +1 -1
- package/dist/{coerce.utils-Dxv4_ikC.mjs → coerce.utils-Cu6IUTgX.mjs} +1 -1
- package/dist/{coerce.utils-Dxv4_ikC.mjs.map → coerce.utils-Cu6IUTgX.mjs.map} +1 -1
- package/dist/correlation.d.mts +31 -6
- package/dist/correlation.d.mts.map +1 -1
- package/dist/correlation.d.ts +31 -6
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +45 -20
- package/dist/correlation.js.map +1 -1
- package/dist/correlation.mjs +45 -20
- package/dist/correlation.mjs.map +1 -1
- package/dist/entry-fields-BJkuPnIg.mjs +30 -0
- package/dist/entry-fields-BJkuPnIg.mjs.map +1 -0
- package/dist/entry-fields-BvOLFlJ4.js +36 -0
- package/dist/entry-fields-BvOLFlJ4.js.map +1 -0
- package/dist/gcp.d.mts +2 -2
- package/dist/gcp.d.ts +2 -2
- package/dist/gcp.js +2 -1
- package/dist/gcp.mjs +2 -1
- package/dist/{gcp.transport-SHdtc1n0.js → gcp.transport-CHV8MGgz.js} +5 -5
- package/dist/gcp.transport-CHV8MGgz.js.map +1 -0
- package/dist/{gcp.transport-BJuNRFe_.mjs → gcp.transport-DBX5TPIy.mjs} +5 -5
- package/dist/gcp.transport-DBX5TPIy.mjs.map +1 -0
- package/dist/{gcp.transport-BOhkVKlI.d.ts → gcp.transport-m4fVw0b1.d.ts} +2 -2
- package/dist/gcp.transport-m4fVw0b1.d.ts.map +1 -0
- package/dist/{gcp.transport-Bi6CUqZR.d.mts → gcp.transport-zzNyIoih.d.mts} +2 -2
- package/dist/gcp.transport-zzNyIoih.d.mts.map +1 -0
- package/dist/{index-BPKwwERo.d.mts → index-BPwEisy4.d.mts} +2 -2
- package/dist/{index-BPKwwERo.d.mts.map → index-BPwEisy4.d.mts.map} +1 -1
- package/dist/{index-C1X-TE5I.d.ts → index-nZEeCr3X.d.ts} +2 -2
- package/dist/{index-C1X-TE5I.d.ts.map → index-nZEeCr3X.d.ts.map} +1 -1
- package/dist/index.d.mts +63 -98
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +63 -98
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -443
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -377
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +11 -4
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +11 -4
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +148 -24
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +148 -24
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +4 -4
- package/dist/nest.d.ts +4 -4
- package/dist/nest.js +20 -11
- package/dist/nest.mjs +7 -5
- package/dist/{logitron-logger.module-BsDZR5BH.js → nestjs-extras-DnJ6vrIC.js} +562 -444
- package/dist/nestjs-extras-DnJ6vrIC.js.map +1 -0
- package/dist/{logitron-logger.module-Bs3XYZgF.mjs → nestjs-extras-ImbuDhs1.mjs} +505 -349
- package/dist/nestjs-extras-ImbuDhs1.mjs.map +1 -0
- package/dist/{logitron-logger.module-zDKVd_o0.d.mts → nestjs-extras-OkC796py.d.mts} +113 -6
- package/dist/nestjs-extras-OkC796py.d.mts.map +1 -0
- package/dist/{logitron-logger.module-CxT1F6Cm.d.ts → nestjs-extras-mKrHE9S6.d.ts} +113 -6
- package/dist/nestjs-extras-mKrHE9S6.d.ts.map +1 -0
- package/dist/{search-njTI2hdo.js → search-B0MH1SJJ.js} +23 -10
- package/dist/search-B0MH1SJJ.js.map +1 -0
- package/dist/{search-DujhR94O.d.ts → search-BfBzDIT9.d.mts} +2 -3
- package/dist/search-BfBzDIT9.d.mts.map +1 -0
- package/dist/{search-CQOo-Iq6.d.mts → search-CHUZPl0h.d.ts} +2 -3
- package/dist/search-CHUZPl0h.d.ts.map +1 -0
- package/dist/{search-CFQRISUv.mjs → search-DjXSn6v5.mjs} +23 -10
- package/dist/search-DjXSn6v5.mjs.map +1 -0
- package/dist/search.d.mts +3 -3
- package/dist/search.d.ts +3 -3
- package/dist/search.js +2 -2
- package/dist/search.mjs +2 -2
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/trace.utils-CvXgaiQT.mjs +278 -0
- package/dist/trace.utils-CvXgaiQT.mjs.map +1 -0
- package/dist/trace.utils-DpBOLDtq.js +358 -0
- package/dist/trace.utils-DpBOLDtq.js.map +1 -0
- package/dist/{transport.manager-D6KL3t9V.mjs → transport.manager-CpdVHEGP.mjs} +365 -86
- package/dist/transport.manager-CpdVHEGP.mjs.map +1 -0
- package/dist/{transport.manager-BivyUTtU.js → transport.manager-Crau3Rle.js} +370 -85
- package/dist/transport.manager-Crau3Rle.js.map +1 -0
- package/dist/{transport.types-B5vcyv2k.d.mts → transport.types-CtNr3D7S.d.mts} +19 -2
- package/dist/transport.types-CtNr3D7S.d.mts.map +1 -0
- package/dist/{transport.types-BuY84TwO.d.ts → transport.types-DqVLZTyf.d.ts} +19 -2
- package/dist/transport.types-DqVLZTyf.d.ts.map +1 -0
- package/dist/transports.d.mts +38 -13
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +38 -13
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +6 -5
- package/dist/transports.mjs +6 -5
- package/dist/worker-entry.js +307 -55
- package/dist/worker.d.mts +2 -2
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +1 -1
- package/dist/worker.mjs +1 -1
- package/dist/{worker.transport-BP8Q28Z2.d.mts → worker.transport-Bgv9heDI.d.mts} +2 -2
- package/dist/{worker.transport-BP8Q28Z2.d.mts.map → worker.transport-Bgv9heDI.d.mts.map} +1 -1
- package/dist/{worker.transport-mKXgNK0L.d.ts → worker.transport-Bj-i0P9V.d.ts} +2 -2
- package/dist/{worker.transport-mKXgNK0L.d.ts.map → worker.transport-Bj-i0P9V.d.ts.map} +1 -1
- package/dist/{worker.transport-CfH6z37Z.js → worker.transport-JP8YHBuU.js} +1 -1
- package/dist/{worker.transport-CfH6z37Z.js.map → worker.transport-JP8YHBuU.js.map} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs → worker.transport-otwhJ_Et.mjs} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs.map → worker.transport-otwhJ_Et.mjs.map} +1 -1
- package/package.json +10 -6
- package/dist/.tsbuildinfo +0 -1
- package/dist/async-context-CSHWoHMB.js.map +0 -1
- package/dist/async-context-CwBNMm2E.mjs.map +0 -1
- package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +0 -1
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +0 -1
- package/dist/cloudwatch.transport-pNBNWJLt.js.map +0 -1
- package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +0 -1
- package/dist/gcp.transport-BJuNRFe_.mjs.map +0 -1
- package/dist/gcp.transport-BOhkVKlI.d.ts.map +0 -1
- package/dist/gcp.transport-Bi6CUqZR.d.mts.map +0 -1
- package/dist/gcp.transport-SHdtc1n0.js.map +0 -1
- package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +0 -1
- package/dist/logitron-logger.module-BsDZR5BH.js.map +0 -1
- package/dist/logitron-logger.module-CxT1F6Cm.d.ts.map +0 -1
- package/dist/logitron-logger.module-zDKVd_o0.d.mts.map +0 -1
- package/dist/search-CFQRISUv.mjs.map +0 -1
- package/dist/search-CQOo-Iq6.d.mts.map +0 -1
- package/dist/search-DujhR94O.d.ts.map +0 -1
- package/dist/search-njTI2hdo.js.map +0 -1
- package/dist/transport.manager-BivyUTtU.js.map +0 -1
- package/dist/transport.manager-D6KL3t9V.mjs.map +0 -1
- package/dist/transport.types-B5vcyv2k.d.mts.map +0 -1
- package/dist/transport.types-BuY84TwO.d.ts.map +0 -1
- package/scripts/postinstall.js +0 -61
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-nOFOJqeH.js');
|
|
2
2
|
const require_internal_log = require('./internal-log-BUJYMZbE.js');
|
|
3
3
|
const require_safe_stringify = require('./safe-stringify-DWo3aZp_.js');
|
|
4
|
-
const
|
|
4
|
+
const require_entry_fields = require('./entry-fields-BvOLFlJ4.js');
|
|
5
|
+
const require_coerce_utils = require('./coerce.utils-B-LilukN.js');
|
|
5
6
|
let node_fs = require("node:fs");
|
|
6
7
|
node_fs = require_chunk.__toESM(node_fs);
|
|
7
8
|
let node_path = require("node:path");
|
|
@@ -15,6 +16,24 @@ node_util = require_chunk.__toESM(node_util);
|
|
|
15
16
|
let node_zlib = require("node:zlib");
|
|
16
17
|
node_zlib = require_chunk.__toESM(node_zlib);
|
|
17
18
|
|
|
19
|
+
//#region src/utils/sanitize.utils.ts
|
|
20
|
+
/**
|
|
21
|
+
* Control-character stripping for text-mode log output.
|
|
22
|
+
*
|
|
23
|
+
* Line breaks become the visible escapes `\\n` / `\\r`; other C0 characters
|
|
24
|
+
* (except tab), DEL and C1 characters are removed, so user-supplied text cannot
|
|
25
|
+
* inject ANSI escapes, overwrite lines, or forge extra log entries.
|
|
26
|
+
*/
|
|
27
|
+
const CONTROL_CHARS_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]/g;
|
|
28
|
+
const VISIBLE_ESCAPES = {
|
|
29
|
+
"\n": "\\n",
|
|
30
|
+
"\r": "\\r"
|
|
31
|
+
};
|
|
32
|
+
function stripControlChars(value) {
|
|
33
|
+
return value.replace(CONTROL_CHARS_RE, (ch) => VISIBLE_ESCAPES[ch] ?? "");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
18
37
|
//#region src/transports/console.transport.ts
|
|
19
38
|
/**
|
|
20
39
|
* Writes log entries to stdout (info/debug/verbose) and stderr (error/warn).
|
|
@@ -45,9 +64,8 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
45
64
|
["brightwhite", "\x1B[97m"],
|
|
46
65
|
["reset", "\x1B[0m"]
|
|
47
66
|
]);
|
|
48
|
-
static #_2 = this.CONTROL_CHARS_RE = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
|
|
49
67
|
static sanitize(value) {
|
|
50
|
-
return require_coerce_utils.safeToString(value)
|
|
68
|
+
return stripControlChars(require_coerce_utils.safeToString(value));
|
|
51
69
|
}
|
|
52
70
|
constructor(config = {}) {
|
|
53
71
|
this.config = config;
|
|
@@ -60,16 +78,15 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
60
78
|
(lvl === "error" || lvl === "warn" ? process.stderr : process.stdout).write(formatted);
|
|
61
79
|
}
|
|
62
80
|
formatEntry(entry) {
|
|
63
|
-
if (this.config.format === "json") return require_safe_stringify.stringifyForLog({
|
|
81
|
+
if (this.config.format === "json") return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
|
|
64
82
|
timestamp: this.config.timestamp !== false ? entry.timestamp.toISOString() : void 0,
|
|
65
83
|
level: entry.level,
|
|
66
84
|
message: entry.message,
|
|
67
|
-
...entry.data || {},
|
|
68
85
|
context: entry.context,
|
|
69
86
|
traceId: entry.traceId,
|
|
70
87
|
appName: entry.appName,
|
|
71
88
|
environment: entry.environment
|
|
72
|
-
});
|
|
89
|
+
}, entry.data));
|
|
73
90
|
const parts = [];
|
|
74
91
|
if (this.config.timestamp !== false) {
|
|
75
92
|
const timestamp = entry.timestamp.toISOString();
|
|
@@ -117,6 +134,47 @@ var ConsoleTransport = class ConsoleTransport {
|
|
|
117
134
|
}
|
|
118
135
|
};
|
|
119
136
|
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/transports/buffer-cap.ts
|
|
139
|
+
const DEFAULT_BUFFER_CAP = 1e4;
|
|
140
|
+
const DROP_WARN_INTERVAL_MS$1 = 5e3;
|
|
141
|
+
/**
|
|
142
|
+
* Keeps an in-memory retry buffer bounded. Past `max` the oldest items are
|
|
143
|
+
* dropped, counted, and reported through internalWarn at most every few seconds.
|
|
144
|
+
*
|
|
145
|
+
* `requested` must be an integer of at least 1, otherwise the default is used.
|
|
146
|
+
* A cap below `batchSize` is raised to `batchSize` so one batch always fits.
|
|
147
|
+
*/
|
|
148
|
+
var BufferCap = class {
|
|
149
|
+
constructor(name, requested, batchSize, fallback = DEFAULT_BUFFER_CAP) {
|
|
150
|
+
this.name = name;
|
|
151
|
+
this.dropped = 0;
|
|
152
|
+
this.lastWarning = 0;
|
|
153
|
+
let max = fallback;
|
|
154
|
+
if (requested !== void 0) if (Number.isInteger(requested) && requested >= 1) max = requested;
|
|
155
|
+
else require_internal_log.internalWarn(`${name}: maxBufferSize ${String(requested)} is not a positive integer; using ${fallback}`);
|
|
156
|
+
this.max = Math.max(max, batchSize);
|
|
157
|
+
}
|
|
158
|
+
/** Drops the oldest items beyond the cap, in place. */
|
|
159
|
+
enforce(items) {
|
|
160
|
+
const excess = items.length - this.max;
|
|
161
|
+
if (excess <= 0) return;
|
|
162
|
+
items.splice(0, excess);
|
|
163
|
+
this.note(excess);
|
|
164
|
+
}
|
|
165
|
+
note(count) {
|
|
166
|
+
this.dropped += count;
|
|
167
|
+
this.report(DROP_WARN_INTERVAL_MS$1);
|
|
168
|
+
}
|
|
169
|
+
report(minGapMs) {
|
|
170
|
+
const now = Date.now();
|
|
171
|
+
if (this.dropped === 0 || now - this.lastWarning < minGapMs) return;
|
|
172
|
+
require_internal_log.internalWarn(`${this.name}: buffer full (${this.max}), dropped ${this.dropped} oldest entr${this.dropped === 1 ? "y" : "ies"}`);
|
|
173
|
+
this.dropped = 0;
|
|
174
|
+
this.lastWarning = now;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
120
178
|
//#endregion
|
|
121
179
|
//#region src/transports/database.transport.ts
|
|
122
180
|
/**
|
|
@@ -127,6 +185,80 @@ const POSTGRES_MAX_PARAMS = 65535;
|
|
|
127
185
|
const POSTGRES_COLUMNS = 8;
|
|
128
186
|
const POSTGRES_ROWS_PER_INSERT = Math.floor(POSTGRES_MAX_PARAMS / POSTGRES_COLUMNS);
|
|
129
187
|
const MYSQL_ROWS_PER_INSERT = 5e3;
|
|
188
|
+
/** Postgres rejects NUL in TEXT and JSONB. */
|
|
189
|
+
function stripNul(value) {
|
|
190
|
+
return typeof value === "string" ? value.split("\0").join("") : value;
|
|
191
|
+
}
|
|
192
|
+
/** JSONB also rejects the \u0000 escape, which JSON.stringify writes for a NUL. */
|
|
193
|
+
function stripJsonNulEscape(value) {
|
|
194
|
+
if (typeof value !== "string") return value;
|
|
195
|
+
return value.replace(/(?<!\\)((?:\\\\)*)\\u0000/g, "$1");
|
|
196
|
+
}
|
|
197
|
+
const PG_DATA_CLASSES = [
|
|
198
|
+
"22",
|
|
199
|
+
"23",
|
|
200
|
+
"54"
|
|
201
|
+
];
|
|
202
|
+
const MYSQL_DATA_CODES = new Set([
|
|
203
|
+
"ER_DATA_TOO_LONG",
|
|
204
|
+
"ER_TRUNCATED_WRONG_VALUE",
|
|
205
|
+
"ER_TRUNCATED_WRONG_VALUE_FOR_FIELD",
|
|
206
|
+
"ER_BAD_NULL_ERROR",
|
|
207
|
+
"ER_WARN_DATA_OUT_OF_RANGE",
|
|
208
|
+
"ER_DUP_ENTRY",
|
|
209
|
+
"ER_INVALID_JSON_TEXT",
|
|
210
|
+
"ER_INVALID_CHARACTER_STRING"
|
|
211
|
+
]);
|
|
212
|
+
const MYSQL_DATA_ERRNOS = new Set([
|
|
213
|
+
1048,
|
|
214
|
+
1062,
|
|
215
|
+
1264,
|
|
216
|
+
1292,
|
|
217
|
+
1366,
|
|
218
|
+
1406,
|
|
219
|
+
3140
|
|
220
|
+
]);
|
|
221
|
+
const SQLITE_DATA_CODES = new Set([
|
|
222
|
+
"SQLITE_CONSTRAINT",
|
|
223
|
+
"SQLITE_TOOBIG",
|
|
224
|
+
"SQLITE_MISMATCH"
|
|
225
|
+
]);
|
|
226
|
+
const MONGO_DATA_CODES = new Set([
|
|
227
|
+
2,
|
|
228
|
+
121,
|
|
229
|
+
10334,
|
|
230
|
+
11e3
|
|
231
|
+
]);
|
|
232
|
+
function isDataErrorLayer(type, e) {
|
|
233
|
+
const code = e.code;
|
|
234
|
+
switch (type) {
|
|
235
|
+
case "postgresql": return typeof code === "string" && PG_DATA_CLASSES.includes(code.slice(0, 2));
|
|
236
|
+
case "mysql": return typeof code === "string" && MYSQL_DATA_CODES.has(code) || typeof e.errno === "number" && MYSQL_DATA_ERRNOS.has(e.errno);
|
|
237
|
+
case "sqlite": return typeof code === "string" && (SQLITE_DATA_CODES.has(code) || code.startsWith("SQLITE_CONSTRAINT_"));
|
|
238
|
+
case "mongodb": return e.name === "BSONObjectTooLarge" || typeof code === "number" && MONGO_DATA_CODES.has(code);
|
|
239
|
+
default: return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* True when the database refused the data itself (bad value, constraint, size),
|
|
244
|
+
* which retrying cannot fix. Connection, timeout, auth and unknown errors are
|
|
245
|
+
* not data errors and must be retried, never dropped.
|
|
246
|
+
*/
|
|
247
|
+
function isDataError(type, error) {
|
|
248
|
+
let current = error;
|
|
249
|
+
for (let depth = 0; depth < 3 && current && typeof current === "object"; depth += 1) {
|
|
250
|
+
if (isDataErrorLayer(type, current)) return true;
|
|
251
|
+
current = current.cause;
|
|
252
|
+
}
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
/** A write that stored part of a batch: only `remaining` still needs to be written. */
|
|
256
|
+
var PartialWriteError = class extends Error {
|
|
257
|
+
constructor(message, remaining, cause) {
|
|
258
|
+
super(message, { cause });
|
|
259
|
+
this.remaining = remaining;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
130
262
|
function chunk(items, size) {
|
|
131
263
|
const chunks = [];
|
|
132
264
|
for (let i = 0; i < items.length; i += size) chunks.push(items.slice(i, i + size));
|
|
@@ -155,6 +287,7 @@ var DatabaseTransport = class {
|
|
|
155
287
|
this.isConnected = false;
|
|
156
288
|
this.batchSize = config.batchSize || 100;
|
|
157
289
|
this.flushInterval = config.flushInterval || 5e3;
|
|
290
|
+
this.cap = new BufferCap("DatabaseTransport", config.maxBufferSize, this.batchSize);
|
|
158
291
|
if (config.filter) this.filter = config.filter;
|
|
159
292
|
if (config.table) validateSqlIdentifier(config.table, "table");
|
|
160
293
|
this.setupFlushTimer();
|
|
@@ -166,6 +299,7 @@ var DatabaseTransport = class {
|
|
|
166
299
|
}
|
|
167
300
|
addToBatch(entry) {
|
|
168
301
|
this.batch.push(entry);
|
|
302
|
+
this.cap.enforce(this.batch);
|
|
169
303
|
}
|
|
170
304
|
async flush() {
|
|
171
305
|
if (!this.flushPromise) this.flushPromise = this.drain().finally(() => {
|
|
@@ -174,37 +308,97 @@ var DatabaseTransport = class {
|
|
|
174
308
|
await this.flushPromise;
|
|
175
309
|
}
|
|
176
310
|
/**
|
|
177
|
-
* Drains the
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
311
|
+
* Drains the buffer to the database one batch at a time. A batch is detached
|
|
312
|
+
* SYNCHRONOUSLY before awaiting the write, so entries appended by concurrent
|
|
313
|
+
* write() calls land in a fresh array and are never written twice.
|
|
314
|
+
*
|
|
315
|
+
* A failure that is not a data error (connection, timeout, auth, unknown) puts
|
|
316
|
+
* the batch back at the front of the buffer, bounded by `maxBufferSize`, and
|
|
317
|
+
* stops the loop so a down database is not hammered. A data error means the
|
|
318
|
+
* database refused some entry itself, so that batch alone is split to find and
|
|
319
|
+
* drop the refused entries; see isolate().
|
|
183
320
|
*/
|
|
184
321
|
async drain() {
|
|
185
322
|
while (this.batch.length > 0) {
|
|
186
|
-
const
|
|
187
|
-
this.batch = [];
|
|
323
|
+
const entries = this.batch.splice(0, this.batchSize);
|
|
188
324
|
try {
|
|
189
|
-
|
|
190
|
-
case "mongodb":
|
|
191
|
-
await this.flushToMongoDB(entriesToFlush);
|
|
192
|
-
break;
|
|
193
|
-
case "postgresql":
|
|
194
|
-
await this.flushToPostgreSQL(entriesToFlush);
|
|
195
|
-
break;
|
|
196
|
-
case "mysql":
|
|
197
|
-
await this.flushToMySQL(entriesToFlush);
|
|
198
|
-
break;
|
|
199
|
-
case "sqlite":
|
|
200
|
-
await this.flushToSQLite(entriesToFlush);
|
|
201
|
-
break;
|
|
202
|
-
default: throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
203
|
-
}
|
|
325
|
+
await this.writeEntries(entries);
|
|
204
326
|
} catch (error) {
|
|
205
327
|
require_internal_log.internalError("Database flush error", error);
|
|
206
|
-
|
|
207
|
-
|
|
328
|
+
if (error instanceof PartialWriteError) {
|
|
329
|
+
this.requeue(error.remaining);
|
|
330
|
+
throw error.cause;
|
|
331
|
+
}
|
|
332
|
+
if (!isDataError(this.config.type, error)) {
|
|
333
|
+
this.requeue(entries);
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
const state = {
|
|
337
|
+
budget: 2 * this.batchSize,
|
|
338
|
+
rejected: 0,
|
|
339
|
+
requeue: [],
|
|
340
|
+
stopped: false
|
|
341
|
+
};
|
|
342
|
+
await this.isolate(entries, state);
|
|
343
|
+
if (state.rejected > 0) require_internal_log.internalWarn(`DatabaseTransport: dropped ${state.rejected} log entr${state.rejected === 1 ? "y" : "ies"} the database rejected`);
|
|
344
|
+
this.requeue(state.requeue);
|
|
345
|
+
if (state.stopped) throw state.error;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
requeue(entries) {
|
|
350
|
+
if (entries.length === 0) return;
|
|
351
|
+
this.batch = entries.concat(this.batch);
|
|
352
|
+
this.cap.enforce(this.batch);
|
|
353
|
+
}
|
|
354
|
+
async writeEntries(entries) {
|
|
355
|
+
switch (this.config.type) {
|
|
356
|
+
case "mongodb":
|
|
357
|
+
await this.flushToMongoDB(entries);
|
|
358
|
+
break;
|
|
359
|
+
case "postgresql":
|
|
360
|
+
await this.flushToPostgreSQL(entries);
|
|
361
|
+
break;
|
|
362
|
+
case "mysql":
|
|
363
|
+
await this.flushToMySQL(entries);
|
|
364
|
+
break;
|
|
365
|
+
case "sqlite":
|
|
366
|
+
await this.flushToSQLite(entries);
|
|
367
|
+
break;
|
|
368
|
+
default: throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* `entries` failed with a data error. Splits them in half until the refused
|
|
373
|
+
* entries are alone and drops those. A write that fails with anything but a
|
|
374
|
+
* data error, or running out of the per-flush write budget, stops the search:
|
|
375
|
+
* the entries not yet written go back to the buffer.
|
|
376
|
+
*/
|
|
377
|
+
async isolate(entries, state) {
|
|
378
|
+
if (entries.length === 1) {
|
|
379
|
+
state.rejected += 1;
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const mid = Math.ceil(entries.length / 2);
|
|
383
|
+
for (const half of [entries.slice(0, mid), entries.slice(mid)]) {
|
|
384
|
+
if (state.stopped || state.budget <= 0) {
|
|
385
|
+
state.requeue.push(...half);
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
state.budget -= 1;
|
|
389
|
+
try {
|
|
390
|
+
await this.writeEntries(half);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
if (error instanceof PartialWriteError) {
|
|
393
|
+
state.requeue.push(...error.remaining);
|
|
394
|
+
state.stopped = true;
|
|
395
|
+
state.error = error.cause;
|
|
396
|
+
} else if (isDataError(this.config.type, error)) await this.isolate(half, state);
|
|
397
|
+
else {
|
|
398
|
+
state.requeue.push(...half);
|
|
399
|
+
state.stopped = true;
|
|
400
|
+
state.error = error;
|
|
401
|
+
}
|
|
208
402
|
}
|
|
209
403
|
}
|
|
210
404
|
}
|
|
@@ -329,7 +523,26 @@ var DatabaseTransport = class {
|
|
|
329
523
|
appName: entry.appName,
|
|
330
524
|
environment: entry.environment
|
|
331
525
|
}));
|
|
332
|
-
|
|
526
|
+
try {
|
|
527
|
+
await collection.insertMany(documents, { ordered: false });
|
|
528
|
+
} catch (error) {
|
|
529
|
+
const raw = error.writeErrors;
|
|
530
|
+
let list = [];
|
|
531
|
+
if (Array.isArray(raw)) list = raw;
|
|
532
|
+
else if (raw) list = [raw];
|
|
533
|
+
const writeErrors = list;
|
|
534
|
+
if (writeErrors.length === 0) throw error;
|
|
535
|
+
const remaining = [];
|
|
536
|
+
let rejected = 0;
|
|
537
|
+
for (const writeError of writeErrors) {
|
|
538
|
+
const entry = typeof writeError.index === "number" ? entries[writeError.index] : void 0;
|
|
539
|
+
if (!entry) throw error;
|
|
540
|
+
if (isDataError("mongodb", writeError)) rejected += 1;
|
|
541
|
+
else remaining.push(entry);
|
|
542
|
+
}
|
|
543
|
+
if (rejected > 0) require_internal_log.internalWarn(`DatabaseTransport: dropped ${rejected} log entr${rejected === 1 ? "y" : "ies"} the database rejected`);
|
|
544
|
+
if (remaining.length > 0) throw new PartialWriteError("MongoDB insert partially failed", remaining, error);
|
|
545
|
+
}
|
|
333
546
|
}
|
|
334
547
|
async flushToPostgreSQL(entries) {
|
|
335
548
|
const tableName = this.config.table || "logs";
|
|
@@ -342,7 +555,7 @@ var DatabaseTransport = class {
|
|
|
342
555
|
entry.traceId,
|
|
343
556
|
entry.appName,
|
|
344
557
|
entry.environment
|
|
345
|
-
]), POSTGRES_ROWS_PER_INSERT);
|
|
558
|
+
].map((value, column) => stripNul(column === 3 ? stripJsonNulEscape(value) : value))), POSTGRES_ROWS_PER_INSERT);
|
|
346
559
|
const insertChunk = async (rows) => {
|
|
347
560
|
const query = `
|
|
348
561
|
INSERT INTO ${tableName}
|
|
@@ -502,6 +715,7 @@ var DatabaseTransport = class {
|
|
|
502
715
|
require_internal_log.internalError("Database flush during close failed; entries remain buffered", error);
|
|
503
716
|
}
|
|
504
717
|
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`);
|
|
718
|
+
this.cap.report(0);
|
|
505
719
|
if (this.connection) switch (this.config.type) {
|
|
506
720
|
case "mongodb":
|
|
507
721
|
await this.connection.close();
|
|
@@ -573,6 +787,7 @@ var AnalyticsTransport = class {
|
|
|
573
787
|
this.level = config.level;
|
|
574
788
|
this.batchSize = this.config.batchSize || 50;
|
|
575
789
|
this.flushInterval = this.config.flushInterval || 1e4;
|
|
790
|
+
this.cap = new BufferCap(name, config.maxBufferSize, this.batchSize);
|
|
576
791
|
}
|
|
577
792
|
async write(entry) {
|
|
578
793
|
if (!this.isReady) await this.ensureReady();
|
|
@@ -582,6 +797,7 @@ var AnalyticsTransport = class {
|
|
|
582
797
|
}
|
|
583
798
|
addToBatch(entry) {
|
|
584
799
|
this.batch.push(entry);
|
|
800
|
+
this.cap.enforce(this.batch);
|
|
585
801
|
if (this.batch.length >= (this.config.batchSize || 50)) this.flush().catch((err) => require_internal_log.internalError(`${this.name} batch flush failed`, err));
|
|
586
802
|
else if (!this.batchTimer && this.config.flushInterval) {
|
|
587
803
|
var _this$batchTimer$unre, _this$batchTimer;
|
|
@@ -617,6 +833,7 @@ var AnalyticsTransport = class {
|
|
|
617
833
|
} catch (error) {
|
|
618
834
|
require_internal_log.internalError(`Analytics transport ${this.name} flush failed`, error);
|
|
619
835
|
this.batch.unshift(...entriesToSend);
|
|
836
|
+
this.cap.enforce(this.batch);
|
|
620
837
|
return;
|
|
621
838
|
}
|
|
622
839
|
}
|
|
@@ -629,25 +846,36 @@ var AnalyticsTransport = class {
|
|
|
629
846
|
const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
|
|
630
847
|
for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) await this.flush();
|
|
631
848
|
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`);
|
|
849
|
+
this.cap.report(0);
|
|
632
850
|
await this.cleanup();
|
|
633
851
|
}
|
|
634
852
|
shouldSkipEntry(entry) {
|
|
635
853
|
return ["debug", "trace"].includes(entry.level.toLowerCase());
|
|
636
854
|
}
|
|
637
855
|
transformEntry(entry) {
|
|
638
|
-
const
|
|
856
|
+
const core = {
|
|
639
857
|
timestamp: entry.timestamp.toISOString(),
|
|
640
858
|
level: entry.level,
|
|
641
859
|
message: entry.message,
|
|
642
|
-
|
|
860
|
+
context: entry.context,
|
|
861
|
+
traceId: entry.traceId,
|
|
862
|
+
appName: entry.appName,
|
|
863
|
+
environment: entry.environment
|
|
643
864
|
};
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
865
|
+
const transformed = require_entry_fields.mergeCoreFields(core, entry.data, this.reservedKeys());
|
|
866
|
+
for (const key of [
|
|
867
|
+
"context",
|
|
868
|
+
"traceId",
|
|
869
|
+
"appName",
|
|
870
|
+
"environment"
|
|
871
|
+
]) if (!core[key]) delete transformed[key];
|
|
648
872
|
if (this.config.customProperties) Object.assign(transformed, this.config.customProperties);
|
|
649
873
|
return transformed;
|
|
650
874
|
}
|
|
875
|
+
/** Provider-specific field names a payload key must not replace. */
|
|
876
|
+
reservedKeys() {
|
|
877
|
+
return [];
|
|
878
|
+
}
|
|
651
879
|
/**
|
|
652
880
|
* Runs initialize() once. A bad config (say, a missing API key) fails every
|
|
653
881
|
* write with the same error instead of an unhandled rejection at startup.
|
|
@@ -732,8 +960,12 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
732
960
|
await this.sendLogBatch(entries);
|
|
733
961
|
}
|
|
734
962
|
transformToDataDogLog(entry) {
|
|
735
|
-
const transformed = this.transformEntry(entry);
|
|
736
963
|
return {
|
|
964
|
+
...this.transformEntry(entry),
|
|
965
|
+
"dd.trace_id": entry.traceId,
|
|
966
|
+
"dd.span_id": this.generateSpanId(),
|
|
967
|
+
host: this.getHostname(),
|
|
968
|
+
source: "nodejs",
|
|
737
969
|
timestamp: entry.timestamp.toISOString(),
|
|
738
970
|
level: this.mapLogLevel(entry.level),
|
|
739
971
|
message: entry.message,
|
|
@@ -743,14 +975,25 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
743
975
|
logger: {
|
|
744
976
|
name: "logixia",
|
|
745
977
|
thread_name: "main"
|
|
746
|
-
}
|
|
747
|
-
...transformed,
|
|
748
|
-
"dd.trace_id": entry.traceId,
|
|
749
|
-
"dd.span_id": this.generateSpanId(),
|
|
750
|
-
host: this.getHostname(),
|
|
751
|
-
source: "nodejs"
|
|
978
|
+
}
|
|
752
979
|
};
|
|
753
980
|
}
|
|
981
|
+
reservedKeys() {
|
|
982
|
+
return [
|
|
983
|
+
"status",
|
|
984
|
+
"ddtags",
|
|
985
|
+
"ddsource",
|
|
986
|
+
"hostname",
|
|
987
|
+
"service",
|
|
988
|
+
"version",
|
|
989
|
+
"env",
|
|
990
|
+
"logger",
|
|
991
|
+
"host",
|
|
992
|
+
"source",
|
|
993
|
+
"dd.trace_id",
|
|
994
|
+
"dd.span_id"
|
|
995
|
+
];
|
|
996
|
+
}
|
|
754
997
|
transformToDataDogMetric(entry) {
|
|
755
998
|
return {
|
|
756
999
|
metric: `logitron.logs.${entry.level}`,
|
|
@@ -890,6 +1133,12 @@ const unlink = (0, node_util.promisify)(node_fs.unlink);
|
|
|
890
1133
|
const readdir = (0, node_util.promisify)(node_fs.readdir);
|
|
891
1134
|
const stat = (0, node_util.promisify)(node_fs.stat);
|
|
892
1135
|
const DROP_WARN_INTERVAL_MS = 5e3;
|
|
1136
|
+
const DEFAULT_MAX_QUEUE = 1e4;
|
|
1137
|
+
const DEFAULT_FILE_MODE = 384;
|
|
1138
|
+
const DEFAULT_DIR_MODE = 448;
|
|
1139
|
+
function csvField(value) {
|
|
1140
|
+
return `"${stripControlChars(require_coerce_utils.safeToString(value)).replace(/"/g, "\"\"")}"`;
|
|
1141
|
+
}
|
|
893
1142
|
const SIZE_UNITS = {
|
|
894
1143
|
"": 1,
|
|
895
1144
|
k: 1024,
|
|
@@ -925,6 +1174,10 @@ function formatDatePattern(date, pattern) {
|
|
|
925
1174
|
* rotated files are renamed beside it (`app-2026-10-22T09-30-00-000.log`).
|
|
926
1175
|
* With a `rotation` block every file, the live one included, is timestamped.
|
|
927
1176
|
*
|
|
1177
|
+
* Files are created with mode 0o600 and directories with 0o700; override with
|
|
1178
|
+
* `fileMode` and `dirMode`. At most `maxQueue` (default 10000) entries wait in
|
|
1179
|
+
* memory; the rest are dropped per `queuePolicy` and counted in a warning.
|
|
1180
|
+
*
|
|
928
1181
|
* @example
|
|
929
1182
|
* transports: { file: { filename: 'app.log', dirname: './logs', maxSize: '50MB' } }
|
|
930
1183
|
*/
|
|
@@ -959,8 +1212,10 @@ var FileTransport = class {
|
|
|
959
1212
|
this.maxBytes = parseSize(rawMaxSize);
|
|
960
1213
|
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
1214
|
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;
|
|
963
|
-
|
|
1215
|
+
if (maxQueue !== void 0 && !(Number.isInteger(maxQueue) && maxQueue > 0)) require_internal_log.internalWarn(`FileTransport: maxQueue ${String(maxQueue)} is not a positive integer; using ${DEFAULT_MAX_QUEUE}`);
|
|
1216
|
+
this.maxQueue = maxQueue !== void 0 && Number.isInteger(maxQueue) && maxQueue > 0 ? maxQueue : DEFAULT_MAX_QUEUE;
|
|
1217
|
+
this.fileMode = config.fileMode ?? DEFAULT_FILE_MODE;
|
|
1218
|
+
this.dirMode = config.dirMode ?? DEFAULT_DIR_MODE;
|
|
964
1219
|
this.queuePolicy = config.queuePolicy ?? "drop-oldest";
|
|
965
1220
|
this.maxFiles = (rotation === null || rotation === void 0 ? void 0 : rotation.maxFiles) ?? config.maxFiles;
|
|
966
1221
|
this.compress = (rotation === null || rotation === void 0 ? void 0 : rotation.compress) ?? config.zippedArchive ?? false;
|
|
@@ -970,7 +1225,10 @@ var FileTransport = class {
|
|
|
970
1225
|
this.ext = node_path.extname(config.filename);
|
|
971
1226
|
this.base = node_path.basename(config.filename, this.ext);
|
|
972
1227
|
try {
|
|
973
|
-
node_fs.mkdirSync(this.dir, {
|
|
1228
|
+
node_fs.mkdirSync(this.dir, {
|
|
1229
|
+
recursive: true,
|
|
1230
|
+
mode: this.dirMode
|
|
1231
|
+
});
|
|
974
1232
|
} catch (error) {
|
|
975
1233
|
require_internal_log.internalError(`FileTransport could not create ${this.dir}`, error);
|
|
976
1234
|
}
|
|
@@ -1038,7 +1296,7 @@ var FileTransport = class {
|
|
|
1038
1296
|
this.enqueued += 1;
|
|
1039
1297
|
}
|
|
1040
1298
|
queueFull() {
|
|
1041
|
-
return this.
|
|
1299
|
+
return this.batch.length + this.inFlight >= this.maxQueue;
|
|
1042
1300
|
}
|
|
1043
1301
|
roomAvailable() {
|
|
1044
1302
|
const room = new Promise((resolve) => this.spaceWaiters.push(resolve));
|
|
@@ -1118,30 +1376,26 @@ var FileTransport = class {
|
|
|
1118
1376
|
}
|
|
1119
1377
|
formatEntry(entry) {
|
|
1120
1378
|
switch (this.config.format) {
|
|
1121
|
-
case "json": return require_safe_stringify.stringifyForLog({
|
|
1379
|
+
case "json": return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
|
|
1122
1380
|
timestamp: entry.timestamp.toISOString(),
|
|
1123
1381
|
level: entry.level,
|
|
1124
|
-
message: entry.message
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
require_coerce_utils.safeToString(entry.traceId),
|
|
1135
|
-
require_safe_stringify.stringifyForLog(entry.data || {})
|
|
1136
|
-
].join(",");
|
|
1137
|
-
}
|
|
1382
|
+
message: entry.message
|
|
1383
|
+
}, entry.data));
|
|
1384
|
+
case "csv": return [
|
|
1385
|
+
entry.timestamp.toISOString(),
|
|
1386
|
+
csvField(entry.level),
|
|
1387
|
+
csvField(entry.message),
|
|
1388
|
+
csvField(entry.context),
|
|
1389
|
+
csvField(entry.traceId),
|
|
1390
|
+
csvField(require_safe_stringify.stringifyForLog(entry.data || {}))
|
|
1391
|
+
].join(",");
|
|
1138
1392
|
case "text":
|
|
1139
|
-
default: return `${entry.timestamp.toISOString()} [${entry.level.toUpperCase()}] ${require_coerce_utils.safeToString(entry.message)}${entry.data ? " " + require_safe_stringify.stringifyForLog(entry.data) : ""}`;
|
|
1393
|
+
default: return `${entry.timestamp.toISOString()} [${stripControlChars(require_coerce_utils.safeToString(entry.level)).toUpperCase()}] ${stripControlChars(require_coerce_utils.safeToString(entry.message))}${entry.data ? " " + require_safe_stringify.stringifyForLog(entry.data) : ""}`;
|
|
1140
1394
|
}
|
|
1141
1395
|
}
|
|
1142
1396
|
addToBatch(entry) {
|
|
1143
1397
|
this.enqueue(entry);
|
|
1144
|
-
const threshold = Math.min(this.config.batchSize || 100, this.maxQueue
|
|
1398
|
+
const threshold = Math.min(this.config.batchSize || 100, this.maxQueue);
|
|
1145
1399
|
if (this.batch.length >= threshold && !this.draining) {
|
|
1146
1400
|
if (this.batchTimer) {
|
|
1147
1401
|
clearTimeout(this.batchTimer);
|
|
@@ -1179,7 +1433,7 @@ var FileTransport = class {
|
|
|
1179
1433
|
if (chunk$1) await this.append(chunk$1, chunkBytes);
|
|
1180
1434
|
}
|
|
1181
1435
|
async append(content, bytes = Buffer.byteLength(content)) {
|
|
1182
|
-
await appendFile(this.currentFilePath, content);
|
|
1436
|
+
await appendFile(this.currentFilePath, content, { mode: this.fileMode });
|
|
1183
1437
|
this.bytesWritten += bytes;
|
|
1184
1438
|
}
|
|
1185
1439
|
timeToRotate() {
|
|
@@ -1273,7 +1527,7 @@ var FileTransport = class {
|
|
|
1273
1527
|
async compressFile(filePath) {
|
|
1274
1528
|
const gzPath = `${filePath}.gz`;
|
|
1275
1529
|
try {
|
|
1276
|
-
await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath));
|
|
1530
|
+
await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath, { mode: this.fileMode }));
|
|
1277
1531
|
await unlink(filePath);
|
|
1278
1532
|
} catch (error) {
|
|
1279
1533
|
require_internal_log.internalError("Failed to compress rotated log file", error);
|
|
@@ -1357,12 +1611,27 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1357
1611
|
await this.sendEvents(events);
|
|
1358
1612
|
}
|
|
1359
1613
|
async cleanup() {}
|
|
1614
|
+
reservedKeys() {
|
|
1615
|
+
return [
|
|
1616
|
+
"event_category",
|
|
1617
|
+
"event_label",
|
|
1618
|
+
"log_level",
|
|
1619
|
+
"log_message",
|
|
1620
|
+
"trace_id",
|
|
1621
|
+
"app_name",
|
|
1622
|
+
"custom_dimension_1",
|
|
1623
|
+
"custom_dimension_2",
|
|
1624
|
+
"custom_dimension_3"
|
|
1625
|
+
];
|
|
1626
|
+
}
|
|
1360
1627
|
transformToGAEvent(entry) {
|
|
1361
1628
|
const transformed = this.transformEntry(entry);
|
|
1629
|
+
const eventCategory = this.mapLogLevelToCategory(entry.level);
|
|
1362
1630
|
return {
|
|
1363
1631
|
name: "log_event",
|
|
1364
1632
|
params: {
|
|
1365
|
-
|
|
1633
|
+
...this.flattenData(transformed),
|
|
1634
|
+
event_category: eventCategory,
|
|
1366
1635
|
event_label: entry.message,
|
|
1367
1636
|
log_level: entry.level,
|
|
1368
1637
|
log_message: entry.message,
|
|
@@ -1371,7 +1640,6 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1371
1640
|
...entry.traceId && { trace_id: entry.traceId },
|
|
1372
1641
|
...entry.appName && { app_name: entry.appName },
|
|
1373
1642
|
...entry.environment && { environment: entry.environment },
|
|
1374
|
-
...this.flattenData(transformed),
|
|
1375
1643
|
custom_dimension_1: entry.level,
|
|
1376
1644
|
custom_dimension_2: entry.context || "default",
|
|
1377
1645
|
custom_dimension_3: entry.environment || "production"
|
|
@@ -1567,12 +1835,21 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1567
1835
|
await this.trackEvents(events);
|
|
1568
1836
|
}
|
|
1569
1837
|
async cleanup() {}
|
|
1838
|
+
reservedKeys() {
|
|
1839
|
+
return [
|
|
1840
|
+
"token",
|
|
1841
|
+
"distinct_id",
|
|
1842
|
+
"time",
|
|
1843
|
+
"$insert_id"
|
|
1844
|
+
];
|
|
1845
|
+
}
|
|
1570
1846
|
transformToMixpanelEvent(entry) {
|
|
1571
1847
|
const transformed = this.transformEntry(entry);
|
|
1572
1848
|
return {
|
|
1573
1849
|
name: `log_${entry.level}`,
|
|
1574
1850
|
properties: {
|
|
1575
1851
|
...transformed,
|
|
1852
|
+
token: this.mixpanelConfig.token,
|
|
1576
1853
|
distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
|
|
1577
1854
|
time: entry.timestamp.getTime(),
|
|
1578
1855
|
$insert_id: this.generateInsertId(entry),
|
|
@@ -1585,8 +1862,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1585
1862
|
const payload = {
|
|
1586
1863
|
event: event.name,
|
|
1587
1864
|
properties: {
|
|
1588
|
-
|
|
1589
|
-
|
|
1865
|
+
...event.properties,
|
|
1866
|
+
token: this.mixpanelConfig.token
|
|
1590
1867
|
}
|
|
1591
1868
|
};
|
|
1592
1869
|
await this.makeRequest("/track", [payload]);
|
|
@@ -1595,8 +1872,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1595
1872
|
const payload = events.map((event) => ({
|
|
1596
1873
|
event: event.name,
|
|
1597
1874
|
properties: {
|
|
1598
|
-
|
|
1599
|
-
|
|
1875
|
+
...event.properties,
|
|
1876
|
+
token: this.mixpanelConfig.token
|
|
1600
1877
|
}
|
|
1601
1878
|
}));
|
|
1602
1879
|
await this.makeRequest("/track", payload);
|
|
@@ -1654,11 +1931,11 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1654
1931
|
const payload = {
|
|
1655
1932
|
event: eventName,
|
|
1656
1933
|
properties: {
|
|
1934
|
+
...properties,
|
|
1935
|
+
...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {},
|
|
1657
1936
|
token: this.mixpanelConfig.token,
|
|
1658
1937
|
distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
|
|
1659
|
-
time: Date.now()
|
|
1660
|
-
...properties,
|
|
1661
|
-
...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {}
|
|
1938
|
+
time: Date.now()
|
|
1662
1939
|
}
|
|
1663
1940
|
};
|
|
1664
1941
|
await this.makeRequest("/track", [payload]);
|
|
@@ -1718,6 +1995,9 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1718
1995
|
await this.batchTrack(segmentEvents);
|
|
1719
1996
|
}
|
|
1720
1997
|
async cleanup() {}
|
|
1998
|
+
reservedKeys() {
|
|
1999
|
+
return ["logger"];
|
|
2000
|
+
}
|
|
1721
2001
|
transformToSegmentEvent(entry) {
|
|
1722
2002
|
const transformed = this.transformEntry(entry);
|
|
1723
2003
|
return {
|
|
@@ -1727,10 +2007,10 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1727
2007
|
anonymousId: this.generateAnonymousId(),
|
|
1728
2008
|
timestamp: entry.timestamp.toISOString(),
|
|
1729
2009
|
properties: {
|
|
2010
|
+
...transformed,
|
|
1730
2011
|
level: entry.level,
|
|
1731
2012
|
message: entry.message,
|
|
1732
2013
|
logger: "logixia",
|
|
1733
|
-
...transformed,
|
|
1734
2014
|
...entry.context && { context: entry.context },
|
|
1735
2015
|
...entry.traceId && { traceId: entry.traceId },
|
|
1736
2016
|
...entry.appName && { appName: entry.appName },
|
|
@@ -1786,11 +2066,10 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1786
2066
|
}
|
|
1787
2067
|
}
|
|
1788
2068
|
extractUserId(entry) {
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
}
|
|
2069
|
+
var _entry$data;
|
|
2070
|
+
const field = this.segmentConfig.userIdField ?? "userId";
|
|
2071
|
+
const id = (_entry$data = entry.data) === null || _entry$data === void 0 ? void 0 : _entry$data[field];
|
|
2072
|
+
return typeof id === "string" ? id : void 0;
|
|
1794
2073
|
}
|
|
1795
2074
|
generateAnonymousId() {
|
|
1796
2075
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
@@ -2345,4 +2624,10 @@ Object.defineProperty(exports, 'TransportManager', {
|
|
|
2345
2624
|
return TransportManager;
|
|
2346
2625
|
}
|
|
2347
2626
|
});
|
|
2348
|
-
|
|
2627
|
+
Object.defineProperty(exports, 'stripControlChars', {
|
|
2628
|
+
enumerable: true,
|
|
2629
|
+
get: function () {
|
|
2630
|
+
return stripControlChars;
|
|
2631
|
+
}
|
|
2632
|
+
});
|
|
2633
|
+
//# sourceMappingURL=transport.manager-Crau3Rle.js.map
|