logixia 1.13.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -16
- 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-Cn_3Usvu.d.ts} +2 -2
- package/dist/{azure-monitor.transport-CG7ClkYj.d.ts.map → azure-monitor.transport-Cn_3Usvu.d.ts.map} +1 -1
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts → azure-monitor.transport-D7Da4RAb.d.mts} +2 -2
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts.map → azure-monitor.transport-D7Da4RAb.d.mts.map} +1 -1
- package/dist/azure.d.mts +2 -2
- package/dist/azure.d.ts +2 -2
- package/dist/browser.d.mts +9 -0
- package/dist/browser.d.mts.map +1 -1
- package/dist/browser.d.ts +9 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +43 -12
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +43 -12
- package/dist/browser.mjs.map +1 -1
- package/dist/{logitron-logger.module-Bs3XYZgF.mjs → builder-0gEzRopq.mjs} +383 -1021
- package/dist/builder-0gEzRopq.mjs.map +1 -0
- package/dist/{logitron-logger.module-BsDZR5BH.js → builder-D44QktIo.js} +411 -1155
- package/dist/builder-D44QktIo.js.map +1 -0
- package/dist/cli/index.js +130 -65
- 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-pNBNWJLt.js → cloudwatch.transport-BO1ahxw-.js} +26 -19
- package/dist/cloudwatch.transport-BO1ahxw-.js.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/{cloudwatch.transport-CGHY4buE.d.mts → cloudwatch.transport-DsEq633o.d.ts} +9 -2
- package/dist/cloudwatch.transport-DsEq633o.d.ts.map +1 -0
- package/dist/{cloudwatch.transport-DK_8cKd3.d.ts → cloudwatch.transport-UlyZFWMn.d.mts} +9 -2
- package/dist/cloudwatch.transport-UlyZFWMn.d.mts.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 +24 -6
- package/dist/correlation.d.mts.map +1 -1
- package/dist/correlation.d.ts +24 -6
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +41 -16
- package/dist/correlation.js.map +1 -1
- package/dist/correlation.mjs +41 -16
- 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-BOhkVKlI.d.ts → gcp.transport-B7oc97sG.d.ts} +2 -2
- package/dist/gcp.transport-B7oc97sG.d.ts.map +1 -0
- 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-Bi6CUqZR.d.mts → gcp.transport-GrJurKo8.d.mts} +2 -2
- package/dist/gcp.transport-GrJurKo8.d.mts.map +1 -0
- package/dist/{index-BPKwwERo.d.mts → index-3mw5gaCw.d.mts} +2 -2
- package/dist/{index-BPKwwERo.d.mts.map → index-3mw5gaCw.d.mts.map} +1 -1
- package/dist/{index-C1X-TE5I.d.ts → index-DhIoploR.d.ts} +2 -2
- package/dist/{index-C1X-TE5I.d.ts.map → index-DhIoploR.d.ts.map} +1 -1
- package/dist/index.d.mts +99 -137
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +99 -137
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -510
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +99 -431
- package/dist/index.mjs.map +1 -1
- package/dist/logitron-logger-BFDSO8Io.d.mts +257 -0
- package/dist/logitron-logger-BFDSO8Io.d.mts.map +1 -0
- package/dist/logitron-logger-UVeN-mQm.d.ts +257 -0
- package/dist/logitron-logger-UVeN-mQm.d.ts.map +1 -0
- 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 +481 -6
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +481 -6
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +884 -13
- package/dist/nest.js.map +1 -0
- package/dist/nest.mjs +863 -6
- package/dist/nest.mjs.map +1 -0
- package/dist/{search-CFQRISUv.mjs → search-BFbu_oVn.mjs} +35 -12
- package/dist/search-BFbu_oVn.mjs.map +1 -0
- package/dist/{search-njTI2hdo.js → search-C4V0OMEn.js} +35 -12
- package/dist/search-C4V0OMEn.js.map +1 -0
- package/dist/{search-DujhR94O.d.ts → search-CNh9uVwR.d.ts} +2 -3
- package/dist/search-CNh9uVwR.d.ts.map +1 -0
- package/dist/{search-CQOo-Iq6.d.mts → search-DXANsQ2n.d.mts} +2 -3
- package/dist/search-DXANsQ2n.d.mts.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/slack.transport-BZzoXDPn.d.mts +112 -0
- package/dist/slack.transport-BZzoXDPn.d.mts.map +1 -0
- package/dist/slack.transport-BfJRouB2.js +654 -0
- package/dist/slack.transport-BfJRouB2.js.map +1 -0
- package/dist/slack.transport-Bzw7sucI.mjs +643 -0
- package/dist/slack.transport-Bzw7sucI.mjs.map +1 -0
- package/dist/slack.transport-CXjQYOes.d.ts +112 -0
- package/dist/slack.transport-CXjQYOes.d.ts.map +1 -0
- 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-BiuCAJd2.mjs} +526 -160
- package/dist/transport.manager-BiuCAJd2.mjs.map +1 -0
- package/dist/{transport.manager-BivyUTtU.js → transport.manager-CXbKKdVE.js} +537 -159
- package/dist/transport.manager-CXbKKdVE.js.map +1 -0
- package/dist/{transport.types-B5vcyv2k.d.mts → transport.types-BMnurPcc.d.mts} +23 -3
- package/dist/transport.types-BMnurPcc.d.mts.map +1 -0
- package/dist/{transport.types-BuY84TwO.d.ts → transport.types-CGoHpWQR.d.ts} +23 -3
- package/dist/transport.types-CGoHpWQR.d.ts.map +1 -0
- package/dist/transports.d.mts +50 -20
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +50 -20
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +9 -5
- package/dist/transports.mjs +8 -6
- 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-CfH6z37Z.js → worker.transport-BdPxu3PN.js} +1 -1
- package/dist/{worker.transport-CfH6z37Z.js.map → worker.transport-BdPxu3PN.js.map} +1 -1
- package/dist/{worker.transport-mKXgNK0L.d.ts → worker.transport-CdzSZJmw.d.ts} +2 -2
- package/dist/{worker.transport-mKXgNK0L.d.ts.map → worker.transport-CdzSZJmw.d.ts.map} +1 -1
- package/dist/{worker.transport-BP8Q28Z2.d.mts → worker.transport-JvGPog3C.d.mts} +2 -2
- package/dist/{worker.transport-BP8Q28Z2.d.mts.map → worker.transport-JvGPog3C.d.mts.map} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs → worker.transport-lPxO2MVL.mjs} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs.map → worker.transport-lPxO2MVL.mjs.map} +1 -1
- package/package.json +27 -14
- 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-BdG1Jnpk.d.mts +0 -618
- package/dist/logitron-logger.module-BdG1Jnpk.d.mts.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-CbXy2gfW.d.ts +0 -618
- package/dist/logitron-logger.module-CbXy2gfW.d.ts.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,20 +1,39 @@
|
|
|
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");
|
|
8
9
|
node_path = require_chunk.__toESM(node_path);
|
|
9
10
|
let node_events = require("node:events");
|
|
10
11
|
node_events = require_chunk.__toESM(node_events);
|
|
11
|
-
let node_stream_promises = require("node:stream/promises");
|
|
12
|
-
node_stream_promises = require_chunk.__toESM(node_stream_promises);
|
|
13
12
|
let node_util = require("node:util");
|
|
14
13
|
node_util = require_chunk.__toESM(node_util);
|
|
15
14
|
let node_zlib = require("node:zlib");
|
|
16
15
|
node_zlib = require_chunk.__toESM(node_zlib);
|
|
16
|
+
let node_stream_promises = require("node:stream/promises");
|
|
17
|
+
node_stream_promises = require_chunk.__toESM(node_stream_promises);
|
|
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
|
+
}
|
|
17
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();
|
|
@@ -558,6 +772,17 @@ var DatabaseTransport = class {
|
|
|
558
772
|
|
|
559
773
|
//#endregion
|
|
560
774
|
//#region src/transports/analytics.transport.ts
|
|
775
|
+
/**
|
|
776
|
+
* Thrown by sendBatch() when part of a batch was already delivered. drain()
|
|
777
|
+
* requeues only `unsent`, so delivered entries are not sent twice.
|
|
778
|
+
*/
|
|
779
|
+
var PartialBatchError = class extends Error {
|
|
780
|
+
constructor(message, unsent, options) {
|
|
781
|
+
super(message, options);
|
|
782
|
+
this.unsent = unsent;
|
|
783
|
+
this.name = "PartialBatchError";
|
|
784
|
+
}
|
|
785
|
+
};
|
|
561
786
|
var AnalyticsTransport = class {
|
|
562
787
|
constructor(name, config) {
|
|
563
788
|
this.batch = [];
|
|
@@ -573,6 +798,7 @@ var AnalyticsTransport = class {
|
|
|
573
798
|
this.level = config.level;
|
|
574
799
|
this.batchSize = this.config.batchSize || 50;
|
|
575
800
|
this.flushInterval = this.config.flushInterval || 1e4;
|
|
801
|
+
this.cap = new BufferCap(name, config.maxBufferSize, this.batchSize);
|
|
576
802
|
}
|
|
577
803
|
async write(entry) {
|
|
578
804
|
if (!this.isReady) await this.ensureReady();
|
|
@@ -582,6 +808,7 @@ var AnalyticsTransport = class {
|
|
|
582
808
|
}
|
|
583
809
|
addToBatch(entry) {
|
|
584
810
|
this.batch.push(entry);
|
|
811
|
+
this.cap.enforce(this.batch);
|
|
585
812
|
if (this.batch.length >= (this.config.batchSize || 50)) this.flush().catch((err) => require_internal_log.internalError(`${this.name} batch flush failed`, err));
|
|
586
813
|
else if (!this.batchTimer && this.config.flushInterval) {
|
|
587
814
|
var _this$batchTimer$unre, _this$batchTimer;
|
|
@@ -616,7 +843,8 @@ var AnalyticsTransport = class {
|
|
|
616
843
|
await this.sendBatch(entriesToSend);
|
|
617
844
|
} catch (error) {
|
|
618
845
|
require_internal_log.internalError(`Analytics transport ${this.name} flush failed`, error);
|
|
619
|
-
this.batch.unshift(...entriesToSend);
|
|
846
|
+
this.batch.unshift(...error instanceof PartialBatchError ? error.unsent : entriesToSend);
|
|
847
|
+
this.cap.enforce(this.batch);
|
|
620
848
|
return;
|
|
621
849
|
}
|
|
622
850
|
}
|
|
@@ -629,25 +857,36 @@ var AnalyticsTransport = class {
|
|
|
629
857
|
const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
|
|
630
858
|
for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) await this.flush();
|
|
631
859
|
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`);
|
|
860
|
+
this.cap.report(0);
|
|
632
861
|
await this.cleanup();
|
|
633
862
|
}
|
|
634
863
|
shouldSkipEntry(entry) {
|
|
635
864
|
return ["debug", "trace"].includes(entry.level.toLowerCase());
|
|
636
865
|
}
|
|
637
866
|
transformEntry(entry) {
|
|
638
|
-
const
|
|
867
|
+
const core = {
|
|
639
868
|
timestamp: entry.timestamp.toISOString(),
|
|
640
869
|
level: entry.level,
|
|
641
870
|
message: entry.message,
|
|
642
|
-
|
|
871
|
+
context: entry.context,
|
|
872
|
+
traceId: entry.traceId,
|
|
873
|
+
appName: entry.appName,
|
|
874
|
+
environment: entry.environment
|
|
643
875
|
};
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
876
|
+
const transformed = require_entry_fields.mergeCoreFields(core, entry.data, this.reservedKeys());
|
|
877
|
+
for (const key of [
|
|
878
|
+
"context",
|
|
879
|
+
"traceId",
|
|
880
|
+
"appName",
|
|
881
|
+
"environment"
|
|
882
|
+
]) if (!core[key]) delete transformed[key];
|
|
648
883
|
if (this.config.customProperties) Object.assign(transformed, this.config.customProperties);
|
|
649
884
|
return transformed;
|
|
650
885
|
}
|
|
886
|
+
/** Provider-specific field names a payload key must not replace. */
|
|
887
|
+
reservedKeys() {
|
|
888
|
+
return [];
|
|
889
|
+
}
|
|
651
890
|
/**
|
|
652
891
|
* Runs initialize() once. A bad config (say, a missing API key) fails every
|
|
653
892
|
* write with the same error instead of an unhandled rejection at startup.
|
|
@@ -667,8 +906,71 @@ var AnalyticsTransport = class {
|
|
|
667
906
|
|
|
668
907
|
//#endregion
|
|
669
908
|
//#region src/transports/datadog.transport.ts
|
|
909
|
+
const gzipAsync = (0, node_util.promisify)(node_zlib.gzip);
|
|
910
|
+
const MAX_LOGS_PER_REQUEST = 1e3;
|
|
911
|
+
const MAX_LOGS_PAYLOAD_BYTES = 5e6;
|
|
912
|
+
const MAX_LOG_BYTES = 1e6;
|
|
913
|
+
const MAX_TRUNCATED_MESSAGE_CHARS = 15e4;
|
|
914
|
+
const TRUNCATED_LOG_KEYS = [
|
|
915
|
+
"ddsource",
|
|
916
|
+
"ddtags",
|
|
917
|
+
"hostname",
|
|
918
|
+
"service",
|
|
919
|
+
"status",
|
|
920
|
+
"timestamp",
|
|
921
|
+
"level",
|
|
922
|
+
"context",
|
|
923
|
+
"traceId",
|
|
924
|
+
"appName",
|
|
925
|
+
"environment",
|
|
926
|
+
"env",
|
|
927
|
+
"version",
|
|
928
|
+
"logger",
|
|
929
|
+
"dd.trace_id",
|
|
930
|
+
"dd.span_id"
|
|
931
|
+
];
|
|
932
|
+
const STATUS_MAP = {
|
|
933
|
+
fatal: "critical",
|
|
934
|
+
critical: "critical",
|
|
935
|
+
error: "error",
|
|
936
|
+
warn: "warn",
|
|
937
|
+
warning: "warn",
|
|
938
|
+
info: "info",
|
|
939
|
+
debug: "debug",
|
|
940
|
+
trace: "debug",
|
|
941
|
+
verbose: "debug"
|
|
942
|
+
};
|
|
943
|
+
const MAX_UINT64 = (1n << 64n) - 1n;
|
|
944
|
+
const DASHED_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
945
|
+
const HEX = /^[0-9a-f]+$/i;
|
|
946
|
+
const DIGITS = /^\d+$/;
|
|
947
|
+
/**
|
|
948
|
+
* Datadog correlates on a decimal 64-bit id. Accepts:
|
|
949
|
+
* - a dashed UUID (logixia's default trace id): dashes stripped, then 32-hex;
|
|
950
|
+
* - 32 hex chars (W3C trace id) or 16 hex chars containing a-f: low 64 bits as decimal;
|
|
951
|
+
* - an all-digit string: already decimal (dd-trace's native format), passed through.
|
|
952
|
+
* An all-digit string is ambiguous when it is 16 or 32 long: 32 is read as hex (a
|
|
953
|
+
* decimal id has at most 20 digits), 16 is read as decimal.
|
|
954
|
+
* Anything else yields the raw string for trace ids (`passthrough`) and nothing for span ids.
|
|
955
|
+
*/
|
|
956
|
+
function toDatadogId(id, passthrough) {
|
|
957
|
+
if (typeof id !== "string" || id === "") return void 0;
|
|
958
|
+
const fallback = passthrough ? id : void 0;
|
|
959
|
+
const compact = DASHED_UUID.test(id) ? id.replaceAll("-", "") : id;
|
|
960
|
+
const isHexId = HEX.test(compact) && (compact.length === 32 || compact.length === 16);
|
|
961
|
+
if (DIGITS.test(compact) && compact.length !== 32) {
|
|
962
|
+
const value = BigInt(compact);
|
|
963
|
+
return value <= MAX_UINT64 ? value.toString() : fallback;
|
|
964
|
+
}
|
|
965
|
+
if (isHexId) return BigInt(`0x${compact.slice(-16)}`).toString();
|
|
966
|
+
return fallback;
|
|
967
|
+
}
|
|
968
|
+
/** Datadog tags: no commas or whitespace, lowercase, at most 200 chars. */
|
|
969
|
+
function tag(key, value) {
|
|
970
|
+
return `${key}:${value}`.replaceAll(/[\s,]+/g, "_").toLowerCase().slice(0, 200);
|
|
971
|
+
}
|
|
670
972
|
/**
|
|
671
|
-
* Sends log entries and metrics to Datadog via the Logs and Metrics HTTP APIs.
|
|
973
|
+
* Sends log entries and metrics to Datadog via the Logs (v2) and Metrics HTTP APIs.
|
|
672
974
|
*
|
|
673
975
|
* The API key is transmitted via the `DD-API-KEY` request header — never in the URL.
|
|
674
976
|
*
|
|
@@ -694,29 +996,68 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
694
996
|
}
|
|
695
997
|
}
|
|
696
998
|
async sendEntry(entry) {
|
|
697
|
-
|
|
698
|
-
if (this.datadogConfig.enableLogs !== false) promises.push(this.sendLog(entry));
|
|
699
|
-
if (this.datadogConfig.enableMetrics) promises.push(this.sendMetric(entry));
|
|
700
|
-
if (this.datadogConfig.enableTraces && entry.traceId) promises.push(this.sendTrace(entry));
|
|
701
|
-
await Promise.all(promises);
|
|
999
|
+
await this.sendBatch([entry]);
|
|
702
1000
|
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Logs go first, chunk by chunk; metrics follow once every log chunk is out.
|
|
1003
|
+
* A failure part-way throws PartialBatchError naming only the entries that were
|
|
1004
|
+
* not delivered, so a retry never re-posts a chunk Datadog already accepted.
|
|
1005
|
+
*/
|
|
703
1006
|
async sendBatch(entries) {
|
|
704
|
-
|
|
705
|
-
if (this.datadogConfig.
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
1007
|
+
if (this.datadogConfig.enableLogs !== false) await this.sendLogBatch(entries);
|
|
1008
|
+
if (this.datadogConfig.enableMetrics) try {
|
|
1009
|
+
await this.sendMetricBatch(entries);
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
if (this.datadogConfig.enableLogs === false) throw error;
|
|
1012
|
+
throw new PartialBatchError(error.message, [], { cause: error });
|
|
710
1013
|
}
|
|
711
|
-
await Promise.all(promises);
|
|
712
1014
|
}
|
|
713
1015
|
async cleanup() {}
|
|
714
|
-
async sendLog(entry) {
|
|
715
|
-
await this.sendLogBatch([entry]);
|
|
716
|
-
}
|
|
717
1016
|
async sendLogBatch(entries) {
|
|
718
|
-
const
|
|
719
|
-
|
|
1017
|
+
const items = entries.map((entry) => ({
|
|
1018
|
+
entry,
|
|
1019
|
+
json: this.serializeLog(entry)
|
|
1020
|
+
}));
|
|
1021
|
+
const chunks = this.chunkLogs(items);
|
|
1022
|
+
for (let i = 0; i < chunks.length; i += 1) {
|
|
1023
|
+
const chunk$1 = chunks[i];
|
|
1024
|
+
try {
|
|
1025
|
+
await this.makeLogsRequest("/api/v2/logs", `[${chunk$1.map((item) => item.json).join(",")}]`);
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
if (i === 0) throw error;
|
|
1028
|
+
const unsent = chunks.slice(i).flatMap((c) => c.map((item) => item.entry));
|
|
1029
|
+
throw new PartialBatchError(error.message, unsent, { cause: error });
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
/** Splits into requests of at most 1000 entries and about 5MB of JSON. */
|
|
1034
|
+
chunkLogs(items) {
|
|
1035
|
+
const chunks = [];
|
|
1036
|
+
let current = [];
|
|
1037
|
+
let currentBytes = 2;
|
|
1038
|
+
for (const item of items) {
|
|
1039
|
+
const bytes = Buffer.byteLength(item.json) + 1;
|
|
1040
|
+
if (current.length > 0 && (current.length >= MAX_LOGS_PER_REQUEST || currentBytes + bytes > MAX_LOGS_PAYLOAD_BYTES)) {
|
|
1041
|
+
chunks.push(current);
|
|
1042
|
+
current = [];
|
|
1043
|
+
currentBytes = 2;
|
|
1044
|
+
}
|
|
1045
|
+
current.push(item);
|
|
1046
|
+
currentBytes += bytes;
|
|
1047
|
+
}
|
|
1048
|
+
if (current.length > 0) chunks.push(current);
|
|
1049
|
+
return chunks;
|
|
1050
|
+
}
|
|
1051
|
+
/** Serializes once. A log over 1MB keeps its identity and correlation fields but loses its attributes and most of its message. */
|
|
1052
|
+
serializeLog(entry) {
|
|
1053
|
+
const log = this.transformToDataDogLog(entry);
|
|
1054
|
+
const json = require_safe_stringify.stringifyForLog(log);
|
|
1055
|
+
if (Buffer.byteLength(json) <= MAX_LOG_BYTES) return json;
|
|
1056
|
+
const kept = {};
|
|
1057
|
+
for (const key of TRUNCATED_LOG_KEYS) if (log[key] !== void 0) kept[key] = log[key];
|
|
1058
|
+
kept["message"] = String(log["message"]).slice(0, MAX_TRUNCATED_MESSAGE_CHARS);
|
|
1059
|
+
kept["truncated"] = true;
|
|
1060
|
+
return require_safe_stringify.stringifyForLog(kept);
|
|
720
1061
|
}
|
|
721
1062
|
async sendMetric(entry) {
|
|
722
1063
|
await this.sendMetricBatch([entry]);
|
|
@@ -725,32 +1066,53 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
725
1066
|
const payload = { series: entries.map((entry) => this.transformToDataDogMetric(entry)) };
|
|
726
1067
|
await this.makeMetricsRequest("/api/v1/series", payload);
|
|
727
1068
|
}
|
|
728
|
-
async sendTrace(entry) {
|
|
729
|
-
await this.sendLog(entry);
|
|
730
|
-
}
|
|
731
|
-
async sendTraceBatch(entries) {
|
|
732
|
-
await this.sendLogBatch(entries);
|
|
733
|
-
}
|
|
734
1069
|
transformToDataDogLog(entry) {
|
|
1070
|
+
var _entry$data, _entry$data2;
|
|
735
1071
|
const transformed = this.transformEntry(entry);
|
|
1072
|
+
const service = this.datadogConfig.service || "logixia";
|
|
1073
|
+
const env = this.datadogConfig.env || "production";
|
|
1074
|
+
const version = this.datadogConfig.version;
|
|
1075
|
+
const tags = [
|
|
1076
|
+
tag("env", env),
|
|
1077
|
+
tag("service", service),
|
|
1078
|
+
...version ? [tag("version", version)] : []
|
|
1079
|
+
];
|
|
1080
|
+
const spanId = toDatadogId(((_entry$data = entry.data) === null || _entry$data === void 0 ? void 0 : _entry$data["spanId"]) ?? ((_entry$data2 = entry.data) === null || _entry$data2 === void 0 ? void 0 : _entry$data2["span_id"]), false);
|
|
1081
|
+
const traceId = toDatadogId(entry.traceId, true);
|
|
736
1082
|
return {
|
|
737
|
-
|
|
738
|
-
|
|
1083
|
+
...transformed,
|
|
1084
|
+
ddsource: "nodejs",
|
|
1085
|
+
ddtags: tags.join(","),
|
|
1086
|
+
hostname: this.getHostname(),
|
|
1087
|
+
service,
|
|
1088
|
+
status: this.mapLogLevel(entry.level),
|
|
739
1089
|
message: entry.message,
|
|
740
|
-
|
|
741
|
-
version
|
|
742
|
-
env: this.datadogConfig.env || "production",
|
|
1090
|
+
env,
|
|
1091
|
+
version,
|
|
743
1092
|
logger: {
|
|
744
1093
|
name: "logixia",
|
|
745
1094
|
thread_name: "main"
|
|
746
1095
|
},
|
|
747
|
-
...
|
|
748
|
-
"dd.
|
|
749
|
-
"dd.span_id": this.generateSpanId(),
|
|
750
|
-
host: this.getHostname(),
|
|
751
|
-
source: "nodejs"
|
|
1096
|
+
...traceId && { "dd.trace_id": traceId },
|
|
1097
|
+
...traceId && spanId && { "dd.span_id": spanId }
|
|
752
1098
|
};
|
|
753
1099
|
}
|
|
1100
|
+
reservedKeys() {
|
|
1101
|
+
return [
|
|
1102
|
+
"status",
|
|
1103
|
+
"ddtags",
|
|
1104
|
+
"ddsource",
|
|
1105
|
+
"hostname",
|
|
1106
|
+
"service",
|
|
1107
|
+
"version",
|
|
1108
|
+
"env",
|
|
1109
|
+
"logger",
|
|
1110
|
+
"host",
|
|
1111
|
+
"source",
|
|
1112
|
+
"dd.trace_id",
|
|
1113
|
+
"dd.span_id"
|
|
1114
|
+
];
|
|
1115
|
+
}
|
|
754
1116
|
transformToDataDogMetric(entry) {
|
|
755
1117
|
return {
|
|
756
1118
|
metric: `logitron.logs.${entry.level}`,
|
|
@@ -758,58 +1120,29 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
758
1120
|
type: "count",
|
|
759
1121
|
host: this.getHostname(),
|
|
760
1122
|
tags: [
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
...entry.context ? [
|
|
765
|
-
...entry.appName ? [
|
|
1123
|
+
tag("level", entry.level),
|
|
1124
|
+
tag("service", this.datadogConfig.service || "logixia"),
|
|
1125
|
+
tag("env", this.datadogConfig.env || "production"),
|
|
1126
|
+
...entry.context ? [tag("context", entry.context)] : [],
|
|
1127
|
+
...entry.appName ? [tag("app", entry.appName)] : []
|
|
766
1128
|
]
|
|
767
1129
|
};
|
|
768
1130
|
}
|
|
769
|
-
transformToDataDogTrace(entry) {
|
|
770
|
-
return {
|
|
771
|
-
trace_id: entry.traceId,
|
|
772
|
-
span_id: this.generateSpanId(),
|
|
773
|
-
parent_id: null,
|
|
774
|
-
name: "log.entry",
|
|
775
|
-
service: this.datadogConfig.service || "logixia",
|
|
776
|
-
resource: entry.message,
|
|
777
|
-
type: "log",
|
|
778
|
-
start: entry.timestamp.getTime() * 1e6,
|
|
779
|
-
duration: 1e6,
|
|
780
|
-
meta: {
|
|
781
|
-
"log.level": entry.level,
|
|
782
|
-
"log.message": entry.message,
|
|
783
|
-
...entry.context && { "log.context": entry.context },
|
|
784
|
-
...entry.data && Object.keys(entry.data).reduce((acc, key) => {
|
|
785
|
-
acc[`log.${key}`] = String(entry.data[key]);
|
|
786
|
-
return acc;
|
|
787
|
-
}, {})
|
|
788
|
-
},
|
|
789
|
-
metrics: { _sampling_priority_v1: 1 }
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
1131
|
mapLogLevel(level) {
|
|
793
|
-
return
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
warning: "warn",
|
|
797
|
-
info: "info",
|
|
798
|
-
debug: "debug",
|
|
799
|
-
trace: "trace",
|
|
800
|
-
verbose: "debug"
|
|
801
|
-
}[level.toLowerCase()] || "info";
|
|
802
|
-
}
|
|
803
|
-
async makeLogsRequest(endpoint, data) {
|
|
1132
|
+
return STATUS_MAP[level.toLowerCase()] || "info";
|
|
1133
|
+
}
|
|
1134
|
+
async makeLogsRequest(endpoint, json) {
|
|
804
1135
|
const url = `${this.logsUrl}${endpoint}`;
|
|
805
1136
|
try {
|
|
1137
|
+
const compress = this.datadogConfig.compress === true;
|
|
806
1138
|
const response = await fetch(url, {
|
|
807
1139
|
method: "POST",
|
|
808
1140
|
headers: {
|
|
809
1141
|
"Content-Type": "application/json",
|
|
810
|
-
"DD-API-KEY": this.datadogConfig.apiKey
|
|
1142
|
+
"DD-API-KEY": this.datadogConfig.apiKey,
|
|
1143
|
+
...compress && { "Content-Encoding": "gzip" }
|
|
811
1144
|
},
|
|
812
|
-
body:
|
|
1145
|
+
body: compress ? await gzipAsync(json) : json
|
|
813
1146
|
});
|
|
814
1147
|
if (!response.ok) throw new Error(`DataDog Logs API error: ${response.status} ${response.statusText}`);
|
|
815
1148
|
} catch (error) {
|
|
@@ -832,9 +1165,6 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
832
1165
|
throw new Error(`Failed to send metrics to DataDog: ${error.message}`, { cause: error });
|
|
833
1166
|
}
|
|
834
1167
|
}
|
|
835
|
-
generateSpanId() {
|
|
836
|
-
return Math.floor(Math.random() * 0xffffffffffff).toString(16);
|
|
837
|
-
}
|
|
838
1168
|
getHostname() {
|
|
839
1169
|
try {
|
|
840
1170
|
return require("node:os").hostname();
|
|
@@ -890,6 +1220,12 @@ const unlink = (0, node_util.promisify)(node_fs.unlink);
|
|
|
890
1220
|
const readdir = (0, node_util.promisify)(node_fs.readdir);
|
|
891
1221
|
const stat = (0, node_util.promisify)(node_fs.stat);
|
|
892
1222
|
const DROP_WARN_INTERVAL_MS = 5e3;
|
|
1223
|
+
const DEFAULT_MAX_QUEUE = 1e4;
|
|
1224
|
+
const DEFAULT_FILE_MODE = 384;
|
|
1225
|
+
const DEFAULT_DIR_MODE = 448;
|
|
1226
|
+
function csvField(value) {
|
|
1227
|
+
return `"${stripControlChars(require_coerce_utils.safeToString(value)).replace(/"/g, "\"\"")}"`;
|
|
1228
|
+
}
|
|
893
1229
|
const SIZE_UNITS = {
|
|
894
1230
|
"": 1,
|
|
895
1231
|
k: 1024,
|
|
@@ -925,6 +1261,10 @@ function formatDatePattern(date, pattern) {
|
|
|
925
1261
|
* rotated files are renamed beside it (`app-2026-10-22T09-30-00-000.log`).
|
|
926
1262
|
* With a `rotation` block every file, the live one included, is timestamped.
|
|
927
1263
|
*
|
|
1264
|
+
* Files are created with mode 0o600 and directories with 0o700; override with
|
|
1265
|
+
* `fileMode` and `dirMode`. At most `maxQueue` (default 10000) entries wait in
|
|
1266
|
+
* memory; the rest are dropped per `queuePolicy` and counted in a warning.
|
|
1267
|
+
*
|
|
928
1268
|
* @example
|
|
929
1269
|
* transports: { file: { filename: 'app.log', dirname: './logs', maxSize: '50MB' } }
|
|
930
1270
|
*/
|
|
@@ -959,8 +1299,10 @@ var FileTransport = class {
|
|
|
959
1299
|
this.maxBytes = parseSize(rawMaxSize);
|
|
960
1300
|
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
1301
|
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
|
-
|
|
1302
|
+
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}`);
|
|
1303
|
+
this.maxQueue = maxQueue !== void 0 && Number.isInteger(maxQueue) && maxQueue > 0 ? maxQueue : DEFAULT_MAX_QUEUE;
|
|
1304
|
+
this.fileMode = config.fileMode ?? DEFAULT_FILE_MODE;
|
|
1305
|
+
this.dirMode = config.dirMode ?? DEFAULT_DIR_MODE;
|
|
964
1306
|
this.queuePolicy = config.queuePolicy ?? "drop-oldest";
|
|
965
1307
|
this.maxFiles = (rotation === null || rotation === void 0 ? void 0 : rotation.maxFiles) ?? config.maxFiles;
|
|
966
1308
|
this.compress = (rotation === null || rotation === void 0 ? void 0 : rotation.compress) ?? config.zippedArchive ?? false;
|
|
@@ -970,7 +1312,10 @@ var FileTransport = class {
|
|
|
970
1312
|
this.ext = node_path.extname(config.filename);
|
|
971
1313
|
this.base = node_path.basename(config.filename, this.ext);
|
|
972
1314
|
try {
|
|
973
|
-
node_fs.mkdirSync(this.dir, {
|
|
1315
|
+
node_fs.mkdirSync(this.dir, {
|
|
1316
|
+
recursive: true,
|
|
1317
|
+
mode: this.dirMode
|
|
1318
|
+
});
|
|
974
1319
|
} catch (error) {
|
|
975
1320
|
require_internal_log.internalError(`FileTransport could not create ${this.dir}`, error);
|
|
976
1321
|
}
|
|
@@ -1038,7 +1383,7 @@ var FileTransport = class {
|
|
|
1038
1383
|
this.enqueued += 1;
|
|
1039
1384
|
}
|
|
1040
1385
|
queueFull() {
|
|
1041
|
-
return this.
|
|
1386
|
+
return this.batch.length + this.inFlight >= this.maxQueue;
|
|
1042
1387
|
}
|
|
1043
1388
|
roomAvailable() {
|
|
1044
1389
|
const room = new Promise((resolve) => this.spaceWaiters.push(resolve));
|
|
@@ -1118,30 +1463,26 @@ var FileTransport = class {
|
|
|
1118
1463
|
}
|
|
1119
1464
|
formatEntry(entry) {
|
|
1120
1465
|
switch (this.config.format) {
|
|
1121
|
-
case "json": return require_safe_stringify.stringifyForLog({
|
|
1466
|
+
case "json": return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
|
|
1122
1467
|
timestamp: entry.timestamp.toISOString(),
|
|
1123
1468
|
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
|
-
}
|
|
1469
|
+
message: entry.message
|
|
1470
|
+
}, entry.data));
|
|
1471
|
+
case "csv": return [
|
|
1472
|
+
entry.timestamp.toISOString(),
|
|
1473
|
+
csvField(entry.level),
|
|
1474
|
+
csvField(entry.message),
|
|
1475
|
+
csvField(entry.context),
|
|
1476
|
+
csvField(entry.traceId),
|
|
1477
|
+
csvField(require_safe_stringify.stringifyForLog(entry.data || {}))
|
|
1478
|
+
].join(",");
|
|
1138
1479
|
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) : ""}`;
|
|
1480
|
+
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
1481
|
}
|
|
1141
1482
|
}
|
|
1142
1483
|
addToBatch(entry) {
|
|
1143
1484
|
this.enqueue(entry);
|
|
1144
|
-
const threshold = Math.min(this.config.batchSize || 100, this.maxQueue
|
|
1485
|
+
const threshold = Math.min(this.config.batchSize || 100, this.maxQueue);
|
|
1145
1486
|
if (this.batch.length >= threshold && !this.draining) {
|
|
1146
1487
|
if (this.batchTimer) {
|
|
1147
1488
|
clearTimeout(this.batchTimer);
|
|
@@ -1179,7 +1520,7 @@ var FileTransport = class {
|
|
|
1179
1520
|
if (chunk$1) await this.append(chunk$1, chunkBytes);
|
|
1180
1521
|
}
|
|
1181
1522
|
async append(content, bytes = Buffer.byteLength(content)) {
|
|
1182
|
-
await appendFile(this.currentFilePath, content);
|
|
1523
|
+
await appendFile(this.currentFilePath, content, { mode: this.fileMode });
|
|
1183
1524
|
this.bytesWritten += bytes;
|
|
1184
1525
|
}
|
|
1185
1526
|
timeToRotate() {
|
|
@@ -1273,7 +1614,7 @@ var FileTransport = class {
|
|
|
1273
1614
|
async compressFile(filePath) {
|
|
1274
1615
|
const gzPath = `${filePath}.gz`;
|
|
1275
1616
|
try {
|
|
1276
|
-
await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath));
|
|
1617
|
+
await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath, { mode: this.fileMode }));
|
|
1277
1618
|
await unlink(filePath);
|
|
1278
1619
|
} catch (error) {
|
|
1279
1620
|
require_internal_log.internalError("Failed to compress rotated log file", error);
|
|
@@ -1357,12 +1698,27 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1357
1698
|
await this.sendEvents(events);
|
|
1358
1699
|
}
|
|
1359
1700
|
async cleanup() {}
|
|
1701
|
+
reservedKeys() {
|
|
1702
|
+
return [
|
|
1703
|
+
"event_category",
|
|
1704
|
+
"event_label",
|
|
1705
|
+
"log_level",
|
|
1706
|
+
"log_message",
|
|
1707
|
+
"trace_id",
|
|
1708
|
+
"app_name",
|
|
1709
|
+
"custom_dimension_1",
|
|
1710
|
+
"custom_dimension_2",
|
|
1711
|
+
"custom_dimension_3"
|
|
1712
|
+
];
|
|
1713
|
+
}
|
|
1360
1714
|
transformToGAEvent(entry) {
|
|
1361
1715
|
const transformed = this.transformEntry(entry);
|
|
1716
|
+
const eventCategory = this.mapLogLevelToCategory(entry.level);
|
|
1362
1717
|
return {
|
|
1363
1718
|
name: "log_event",
|
|
1364
1719
|
params: {
|
|
1365
|
-
|
|
1720
|
+
...this.flattenData(transformed),
|
|
1721
|
+
event_category: eventCategory,
|
|
1366
1722
|
event_label: entry.message,
|
|
1367
1723
|
log_level: entry.level,
|
|
1368
1724
|
log_message: entry.message,
|
|
@@ -1371,7 +1727,6 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1371
1727
|
...entry.traceId && { trace_id: entry.traceId },
|
|
1372
1728
|
...entry.appName && { app_name: entry.appName },
|
|
1373
1729
|
...entry.environment && { environment: entry.environment },
|
|
1374
|
-
...this.flattenData(transformed),
|
|
1375
1730
|
custom_dimension_1: entry.level,
|
|
1376
1731
|
custom_dimension_2: entry.context || "default",
|
|
1377
1732
|
custom_dimension_3: entry.environment || "production"
|
|
@@ -1567,12 +1922,21 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1567
1922
|
await this.trackEvents(events);
|
|
1568
1923
|
}
|
|
1569
1924
|
async cleanup() {}
|
|
1925
|
+
reservedKeys() {
|
|
1926
|
+
return [
|
|
1927
|
+
"token",
|
|
1928
|
+
"distinct_id",
|
|
1929
|
+
"time",
|
|
1930
|
+
"$insert_id"
|
|
1931
|
+
];
|
|
1932
|
+
}
|
|
1570
1933
|
transformToMixpanelEvent(entry) {
|
|
1571
1934
|
const transformed = this.transformEntry(entry);
|
|
1572
1935
|
return {
|
|
1573
1936
|
name: `log_${entry.level}`,
|
|
1574
1937
|
properties: {
|
|
1575
1938
|
...transformed,
|
|
1939
|
+
token: this.mixpanelConfig.token,
|
|
1576
1940
|
distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
|
|
1577
1941
|
time: entry.timestamp.getTime(),
|
|
1578
1942
|
$insert_id: this.generateInsertId(entry),
|
|
@@ -1585,8 +1949,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1585
1949
|
const payload = {
|
|
1586
1950
|
event: event.name,
|
|
1587
1951
|
properties: {
|
|
1588
|
-
|
|
1589
|
-
|
|
1952
|
+
...event.properties,
|
|
1953
|
+
token: this.mixpanelConfig.token
|
|
1590
1954
|
}
|
|
1591
1955
|
};
|
|
1592
1956
|
await this.makeRequest("/track", [payload]);
|
|
@@ -1595,8 +1959,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1595
1959
|
const payload = events.map((event) => ({
|
|
1596
1960
|
event: event.name,
|
|
1597
1961
|
properties: {
|
|
1598
|
-
|
|
1599
|
-
|
|
1962
|
+
...event.properties,
|
|
1963
|
+
token: this.mixpanelConfig.token
|
|
1600
1964
|
}
|
|
1601
1965
|
}));
|
|
1602
1966
|
await this.makeRequest("/track", payload);
|
|
@@ -1654,11 +2018,11 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
1654
2018
|
const payload = {
|
|
1655
2019
|
event: eventName,
|
|
1656
2020
|
properties: {
|
|
2021
|
+
...properties,
|
|
2022
|
+
...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {},
|
|
1657
2023
|
token: this.mixpanelConfig.token,
|
|
1658
2024
|
distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
|
|
1659
|
-
time: Date.now()
|
|
1660
|
-
...properties,
|
|
1661
|
-
...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {}
|
|
2025
|
+
time: Date.now()
|
|
1662
2026
|
}
|
|
1663
2027
|
};
|
|
1664
2028
|
await this.makeRequest("/track", [payload]);
|
|
@@ -1718,6 +2082,9 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1718
2082
|
await this.batchTrack(segmentEvents);
|
|
1719
2083
|
}
|
|
1720
2084
|
async cleanup() {}
|
|
2085
|
+
reservedKeys() {
|
|
2086
|
+
return ["logger"];
|
|
2087
|
+
}
|
|
1721
2088
|
transformToSegmentEvent(entry) {
|
|
1722
2089
|
const transformed = this.transformEntry(entry);
|
|
1723
2090
|
return {
|
|
@@ -1727,10 +2094,10 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1727
2094
|
anonymousId: this.generateAnonymousId(),
|
|
1728
2095
|
timestamp: entry.timestamp.toISOString(),
|
|
1729
2096
|
properties: {
|
|
2097
|
+
...transformed,
|
|
1730
2098
|
level: entry.level,
|
|
1731
2099
|
message: entry.message,
|
|
1732
2100
|
logger: "logixia",
|
|
1733
|
-
...transformed,
|
|
1734
2101
|
...entry.context && { context: entry.context },
|
|
1735
2102
|
...entry.traceId && { traceId: entry.traceId },
|
|
1736
2103
|
...entry.appName && { appName: entry.appName },
|
|
@@ -1786,11 +2153,10 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
1786
2153
|
}
|
|
1787
2154
|
}
|
|
1788
2155
|
extractUserId(entry) {
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
}
|
|
2156
|
+
var _entry$data;
|
|
2157
|
+
const field = this.segmentConfig.userIdField ?? "userId";
|
|
2158
|
+
const id = (_entry$data = entry.data) === null || _entry$data === void 0 ? void 0 : _entry$data[field];
|
|
2159
|
+
return typeof id === "string" ? id : void 0;
|
|
1794
2160
|
}
|
|
1795
2161
|
generateAnonymousId() {
|
|
1796
2162
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
@@ -2297,6 +2663,12 @@ Object.defineProperty(exports, 'AnalyticsTransport', {
|
|
|
2297
2663
|
return AnalyticsTransport;
|
|
2298
2664
|
}
|
|
2299
2665
|
});
|
|
2666
|
+
Object.defineProperty(exports, 'BufferCap', {
|
|
2667
|
+
enumerable: true,
|
|
2668
|
+
get: function () {
|
|
2669
|
+
return BufferCap;
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2300
2672
|
Object.defineProperty(exports, 'ConsoleTransport', {
|
|
2301
2673
|
enumerable: true,
|
|
2302
2674
|
get: function () {
|
|
@@ -2345,4 +2717,10 @@ Object.defineProperty(exports, 'TransportManager', {
|
|
|
2345
2717
|
return TransportManager;
|
|
2346
2718
|
}
|
|
2347
2719
|
});
|
|
2348
|
-
|
|
2720
|
+
Object.defineProperty(exports, 'stripControlChars', {
|
|
2721
|
+
enumerable: true,
|
|
2722
|
+
get: function () {
|
|
2723
|
+
return stripControlChars;
|
|
2724
|
+
}
|
|
2725
|
+
});
|
|
2726
|
+
//# sourceMappingURL=transport.manager-CXbKKdVE.js.map
|