logixia 2.0.11 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/{async-context-D8um9I5V.js → async-context-Dgl3ZLyb.js} +3 -3
- package/dist/{async-context-D8um9I5V.js.map → async-context-Dgl3ZLyb.js.map} +1 -1
- package/dist/{async-context-BGUCdYAa.mjs → async-context-fBqC5lNc.mjs} +2 -2
- package/dist/{async-context-BGUCdYAa.mjs.map → async-context-fBqC5lNc.mjs.map} +1 -1
- package/dist/{azure-monitor.transport-CbSHOnNX.d.mts → azure-monitor.transport-C5VjvREZ.d.mts} +2 -2
- package/dist/{azure-monitor.transport-CbSHOnNX.d.mts.map → azure-monitor.transport-C5VjvREZ.d.mts.map} +1 -1
- package/dist/{azure-monitor.transport-Bvf7Xegt.d.ts → azure-monitor.transport-CyHDjHS-.d.ts} +2 -2
- package/dist/{azure-monitor.transport-Bvf7Xegt.d.ts.map → azure-monitor.transport-CyHDjHS-.d.ts.map} +1 -1
- package/dist/{azure-monitor.transport-CTnfwA0F.mjs → azure-monitor.transport-DGiacfvT.mjs} +4 -4
- package/dist/{azure-monitor.transport-CTnfwA0F.mjs.map → azure-monitor.transport-DGiacfvT.mjs.map} +1 -1
- package/dist/{azure-monitor.transport-C8KdmsSw.js → azure-monitor.transport-DX3fuK2t.js} +4 -4
- package/dist/{azure-monitor.transport-C8KdmsSw.js.map → azure-monitor.transport-DX3fuK2t.js.map} +1 -1
- package/dist/azure.d.mts +1 -1
- package/dist/azure.d.ts +1 -1
- package/dist/azure.js +1 -1
- package/dist/azure.mjs +1 -1
- package/dist/{batch-buffer-BTQdAXwC.js → batch-buffer-BLmVvJAZ.js} +2 -2
- package/dist/{batch-buffer-BTQdAXwC.js.map → batch-buffer-BLmVvJAZ.js.map} +1 -1
- package/dist/{batch-buffer-BJqzpfpT.mjs → batch-buffer-CM-lK_Qy.mjs} +2 -2
- package/dist/{batch-buffer-BJqzpfpT.mjs.map → batch-buffer-CM-lK_Qy.mjs.map} +1 -1
- package/dist/browser.d.mts +2 -0
- package/dist/browser.d.mts.map +1 -1
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +18 -4
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +18 -4
- package/dist/browser.mjs.map +1 -1
- package/dist/{builder-C6kKEVrU.mjs → builder-CA_dokb4.mjs} +108 -61
- package/dist/builder-CA_dokb4.mjs.map +1 -0
- package/dist/{builder-Up4YxX7l.js → builder-jMlVYaQa.js} +114 -67
- package/dist/builder-jMlVYaQa.js.map +1 -0
- package/dist/cloudwatch.d.mts +1 -1
- package/dist/cloudwatch.d.ts +1 -1
- package/dist/cloudwatch.js +1 -1
- package/dist/cloudwatch.mjs +1 -1
- package/dist/{cloudwatch.transport-Bl1qzdBx.mjs → cloudwatch.transport-Cr0fEpko.mjs} +5 -5
- package/dist/{cloudwatch.transport-Bl1qzdBx.mjs.map → cloudwatch.transport-Cr0fEpko.mjs.map} +1 -1
- package/dist/{cloudwatch.transport-CQyT6U91.d.ts → cloudwatch.transport-DdSjUWvu.d.ts} +2 -2
- package/dist/{cloudwatch.transport-CQyT6U91.d.ts.map → cloudwatch.transport-DdSjUWvu.d.ts.map} +1 -1
- package/dist/{cloudwatch.transport-BoCyxNKO.js → cloudwatch.transport-Lst1Bbmr.js} +5 -5
- package/dist/{cloudwatch.transport-BoCyxNKO.js.map → cloudwatch.transport-Lst1Bbmr.js.map} +1 -1
- package/dist/{cloudwatch.transport-CjVrI6S4.d.mts → cloudwatch.transport-_hS7Mcc5.d.mts} +2 -2
- package/dist/{cloudwatch.transport-CjVrI6S4.d.mts.map → cloudwatch.transport-_hS7Mcc5.d.mts.map} +1 -1
- package/dist/correlation.js +2 -2
- package/dist/correlation.mjs +2 -2
- package/dist/{entry-fields-CJbeaoBs.js → entry-fields-BSLkzw18.js} +3 -3
- package/dist/{entry-fields-CJbeaoBs.js.map → entry-fields-BSLkzw18.js.map} +1 -1
- package/dist/{entry-fields-D_aNnjg0.mjs → entry-fields-J1OBi24o.mjs} +2 -2
- package/dist/{entry-fields-D_aNnjg0.mjs.map → entry-fields-J1OBi24o.mjs.map} +1 -1
- package/dist/gcp.d.mts +1 -1
- package/dist/gcp.d.ts +1 -1
- package/dist/gcp.js +1 -1
- package/dist/gcp.mjs +1 -1
- package/dist/{gcp.transport-D_NHVZrw.js → gcp.transport-5-ZIjN8r.js} +5 -5
- package/dist/{gcp.transport-D_NHVZrw.js.map → gcp.transport-5-ZIjN8r.js.map} +1 -1
- package/dist/{gcp.transport-D9SdLPwP.d.mts → gcp.transport-C8VJiEM7.d.mts} +2 -2
- package/dist/{gcp.transport-D9SdLPwP.d.mts.map → gcp.transport-C8VJiEM7.d.mts.map} +1 -1
- package/dist/{gcp.transport-BCIvdFV-.d.ts → gcp.transport-Ct0BtKFo.d.ts} +2 -2
- package/dist/{gcp.transport-BCIvdFV-.d.ts.map → gcp.transport-Ct0BtKFo.d.ts.map} +1 -1
- package/dist/{gcp.transport-DOH4bpWM.mjs → gcp.transport-Cw3Qke85.mjs} +5 -5
- package/dist/{gcp.transport-DOH4bpWM.mjs.map → gcp.transport-Cw3Qke85.mjs.map} +1 -1
- package/dist/{index-BAkPHp5D.d.mts → index-B3ajtXJd.d.mts} +2 -2
- package/dist/{index-BAkPHp5D.d.mts.map → index-B3ajtXJd.d.mts.map} +1 -1
- package/dist/{index-e7LowmAu.d.ts → index-oqD3WNxf.d.ts} +2 -2
- package/dist/{index-e7LowmAu.d.ts.map → index-oqD3WNxf.d.ts.map} +1 -1
- package/dist/index.d.mts +8 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -8
- package/dist/index.mjs.map +1 -1
- package/dist/{logitron-logger-DVUdgmBY.d.ts → logitron-logger-Csn3e6Qu.d.ts} +2 -2
- package/dist/{logitron-logger-DVUdgmBY.d.ts.map → logitron-logger-Csn3e6Qu.d.ts.map} +1 -1
- package/dist/{logitron-logger-DoWmMjYB.d.mts → logitron-logger-fMOkXr8H.d.mts} +2 -2
- package/dist/{logitron-logger-DoWmMjYB.d.mts.map → logitron-logger-fMOkXr8H.d.mts.map} +1 -1
- package/dist/middleware.d.mts +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +5 -4
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +3 -2
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +47 -15
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +47 -15
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +169 -48
- package/dist/nest.js.map +1 -1
- package/dist/nest.mjs +166 -45
- package/dist/nest.mjs.map +1 -1
- package/dist/{otel-DH6-G6DR.js → otel-8ypFGG19.js} +319 -66
- package/dist/otel-8ypFGG19.js.map +1 -0
- package/dist/{otel-DAVxpArV.mjs → otel-b-s2QbY4.mjs} +319 -66
- package/dist/otel-b-s2QbY4.mjs.map +1 -0
- package/dist/own-property-BWkibepN.js +40 -0
- package/dist/own-property-BWkibepN.js.map +1 -0
- package/dist/own-property-CjFw9qwZ.mjs +29 -0
- package/dist/own-property-CjFw9qwZ.mjs.map +1 -0
- package/dist/{safe-stringify-pZOnzGRJ.mjs → safe-stringify-B5p5ktFe.mjs} +2 -2
- package/dist/{safe-stringify-pZOnzGRJ.mjs.map → safe-stringify-B5p5ktFe.mjs.map} +1 -1
- package/dist/{safe-stringify-CJisLyZ3.js → safe-stringify-J3sh-7YM.js} +5 -5
- package/dist/{safe-stringify-CJisLyZ3.js.map → safe-stringify-J3sh-7YM.js.map} +1 -1
- package/dist/{search-Crf2IEoA.d.mts → search-B-hJe2N-.d.mts} +7 -3
- package/dist/{search-Crf2IEoA.d.mts.map → search-B-hJe2N-.d.mts.map} +1 -1
- package/dist/{search-B4eEzrhM.d.ts → search-BlKBLm5D.d.ts} +7 -3
- package/dist/{search-B4eEzrhM.d.ts.map → search-BlKBLm5D.d.ts.map} +1 -1
- package/dist/{search-CjYl-mo5.mjs → search-CTR4XNHq.mjs} +52 -14
- package/dist/search-CTR4XNHq.mjs.map +1 -0
- package/dist/{search-CJw_xoQl.js → search-_qx4YzRP.js} +52 -14
- package/dist/search-_qx4YzRP.js.map +1 -0
- package/dist/search.d.mts +1 -1
- package/dist/search.d.ts +1 -1
- package/dist/search.js +1 -1
- package/dist/search.mjs +1 -1
- package/dist/{secret-config-6hdODxBb.js → secret-config--cVTOWwp.js} +6 -5
- package/dist/{secret-config-6hdODxBb.js.map → secret-config--cVTOWwp.js.map} +1 -1
- package/dist/{secret-config-D1F4MW69.mjs → secret-config-GKmb15Me.mjs} +3 -2
- package/dist/{secret-config-D1F4MW69.mjs.map → secret-config-GKmb15Me.mjs.map} +1 -1
- package/dist/{sensitive-names-wv27qBQC.mjs → sensitive-names-BiBM6R1X.mjs} +2 -28
- package/dist/sensitive-names-BiBM6R1X.mjs.map +1 -0
- package/dist/{sensitive-names-CNgHaqv9.js → sensitive-names-NiKIRhp5.js} +1 -39
- package/dist/sensitive-names-NiKIRhp5.js.map +1 -0
- package/dist/{slack.transport-C6E0l4kw.d.ts → slack.transport-5OPL7H3u.d.mts} +76 -3
- package/dist/slack.transport-5OPL7H3u.d.mts.map +1 -0
- package/dist/{slack.transport-BDyENuR0.d.mts → slack.transport-BFpBD_Ri.d.ts} +76 -3
- package/dist/slack.transport-BFpBD_Ri.d.ts.map +1 -0
- package/dist/{slack.transport-CEYBVzUj.js → slack.transport-Cpx5fKga.js} +231 -8
- package/dist/slack.transport-Cpx5fKga.js.map +1 -0
- package/dist/{slack.transport-YvaLJxNv.mjs → slack.transport-Qwj9WkrJ.mjs} +226 -9
- package/dist/slack.transport-Qwj9WkrJ.mjs.map +1 -0
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{transport.types-CzJq4IrF.d.ts → transport.types-B1ejJJP6.d.mts} +6 -1
- package/dist/transport.types-B1ejJJP6.d.mts.map +1 -0
- package/dist/{transport.types-CzJq4IrF.d.mts → transport.types-B1ejJJP6.d.ts} +6 -1
- package/dist/transport.types-B1ejJJP6.d.ts.map +1 -0
- package/dist/transports.d.mts +61 -11
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +61 -11
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +7 -6
- package/dist/transports.mjs +7 -7
- package/dist/worker-entry.js +91 -11
- package/dist/worker.d.mts +1 -1
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.mjs +1 -1
- package/dist/{worker.transport-B9mCQSM1.d.ts → worker.transport-B7olL1Uh.d.ts} +12 -2
- package/dist/worker.transport-B7olL1Uh.d.ts.map +1 -0
- package/dist/{worker.transport-DgK_ZXlB.mjs → worker.transport-BHnWDXPH.mjs} +40 -2
- package/dist/worker.transport-BHnWDXPH.mjs.map +1 -0
- package/dist/{worker.transport-CwNpH98o.js → worker.transport-C7jNGhev.js} +40 -2
- package/dist/worker.transport-C7jNGhev.js.map +1 -0
- package/dist/{worker.transport-Bl8lFRck.d.mts → worker.transport-DnU0_9Bd.d.mts} +12 -2
- package/dist/worker.transport-DnU0_9Bd.d.mts.map +1 -0
- package/package.json +1 -1
- package/dist/builder-C6kKEVrU.mjs.map +0 -1
- package/dist/builder-Up4YxX7l.js.map +0 -1
- package/dist/otel-DAVxpArV.mjs.map +0 -1
- package/dist/otel-DH6-G6DR.js.map +0 -1
- package/dist/search-CJw_xoQl.js.map +0 -1
- package/dist/search-CjYl-mo5.mjs.map +0 -1
- package/dist/sensitive-names-CNgHaqv9.js.map +0 -1
- package/dist/sensitive-names-wv27qBQC.mjs.map +0 -1
- package/dist/slack.transport-BDyENuR0.d.mts.map +0 -1
- package/dist/slack.transport-C6E0l4kw.d.ts.map +0 -1
- package/dist/slack.transport-CEYBVzUj.js.map +0 -1
- package/dist/slack.transport-YvaLJxNv.mjs.map +0 -1
- package/dist/transport.types-CzJq4IrF.d.mts.map +0 -1
- package/dist/transport.types-CzJq4IrF.d.ts.map +0 -1
- package/dist/worker.transport-B9mCQSM1.d.ts.map +0 -1
- package/dist/worker.transport-Bl8lFRck.d.mts.map +0 -1
- package/dist/worker.transport-CwNpH98o.js.map +0 -1
- package/dist/worker.transport-DgK_ZXlB.mjs.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
const require_secret_config = require("./secret-config
|
|
1
|
+
const require_secret_config = require("./secret-config--cVTOWwp.js");
|
|
2
2
|
const require_internal_log = require("./internal-log-DwqTjhpb.js");
|
|
3
|
+
const require_safe_stringify = require("./safe-stringify-J3sh-7YM.js");
|
|
3
4
|
const require_csv_utils = require("./csv.utils-CbVHY1pd.js");
|
|
4
|
-
const
|
|
5
|
-
const
|
|
5
|
+
const require_entry_fields = require("./entry-fields-BSLkzw18.js");
|
|
6
|
+
const require_batch_buffer = require("./batch-buffer-BLmVvJAZ.js");
|
|
6
7
|
let node_events = require("node:events");
|
|
7
8
|
let node_util = require("node:util");
|
|
8
9
|
let node_zlib = require("node:zlib");
|
|
@@ -250,6 +251,7 @@ function isDataError(type, error) {
|
|
|
250
251
|
return false;
|
|
251
252
|
}
|
|
252
253
|
/** A write that stored part of a batch: only `remaining` still needs to be written. */
|
|
254
|
+
var DatabaseUnavailableError = class extends Error {};
|
|
253
255
|
var PartialWriteError = class extends Error {
|
|
254
256
|
remaining;
|
|
255
257
|
constructor(message, remaining, cause) {
|
|
@@ -297,6 +299,8 @@ var DatabaseTransport = class {
|
|
|
297
299
|
connection;
|
|
298
300
|
isConnected = false;
|
|
299
301
|
connectionPromise;
|
|
302
|
+
connectFailures = 0;
|
|
303
|
+
nextConnectAt = 0;
|
|
300
304
|
cap;
|
|
301
305
|
constructor(config) {
|
|
302
306
|
this.config = config;
|
|
@@ -318,9 +322,12 @@ var DatabaseTransport = class {
|
|
|
318
322
|
];
|
|
319
323
|
}
|
|
320
324
|
async write(entry) {
|
|
321
|
-
if (!this.isConnected) await this.connect();
|
|
322
325
|
this.addToBatch(entry);
|
|
323
|
-
if (this.batch.length >= this.batchSize)
|
|
326
|
+
if (this.batch.length >= this.batchSize) try {
|
|
327
|
+
await this.flush();
|
|
328
|
+
} catch (error) {
|
|
329
|
+
if (!(error instanceof DatabaseUnavailableError)) throw error;
|
|
330
|
+
}
|
|
324
331
|
}
|
|
325
332
|
addToBatch(entry) {
|
|
326
333
|
this.batch.push(entry);
|
|
@@ -345,6 +352,7 @@ var DatabaseTransport = class {
|
|
|
345
352
|
*/
|
|
346
353
|
async drain() {
|
|
347
354
|
while (this.batch.length > 0) {
|
|
355
|
+
await this.ensureConnected();
|
|
348
356
|
const entries = this.batch.splice(0, this.batchSize);
|
|
349
357
|
try {
|
|
350
358
|
await this.writeEntries(entries);
|
|
@@ -442,6 +450,38 @@ var DatabaseTransport = class {
|
|
|
442
450
|
return false;
|
|
443
451
|
}
|
|
444
452
|
}
|
|
453
|
+
async ensureConnected() {
|
|
454
|
+
if (this.isConnected) return;
|
|
455
|
+
const wait = this.nextConnectAt - Date.now();
|
|
456
|
+
if (wait > 0) throw new DatabaseUnavailableError(`Database unavailable; next connect attempt in ${wait}ms`);
|
|
457
|
+
try {
|
|
458
|
+
await this.connect();
|
|
459
|
+
this.connectFailures = 0;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
this.connectFailures += 1;
|
|
462
|
+
this.nextConnectAt = Date.now() + Math.min(3e4, 1e3 * 2 ** (this.connectFailures - 1));
|
|
463
|
+
require_internal_log.internalError("Database connection error", error);
|
|
464
|
+
throw new DatabaseUnavailableError("Database unavailable", { cause: error });
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* The driver reported the connection gone (idle timeout, server restart,
|
|
469
|
+
* network drop). Forget it so the next flush reconnects; without an 'error'
|
|
470
|
+
* listener the driver's emitter would crash the process.
|
|
471
|
+
*/
|
|
472
|
+
onConnectionLost(connection, error) {
|
|
473
|
+
if (this.connection !== connection) return;
|
|
474
|
+
if (error) require_internal_log.internalError("Database connection lost", error);
|
|
475
|
+
this.isConnected = false;
|
|
476
|
+
this.connectionPromise = void 0;
|
|
477
|
+
this.connection = void 0;
|
|
478
|
+
}
|
|
479
|
+
watchConnection(connection) {
|
|
480
|
+
var _connection$on, _connection$on2;
|
|
481
|
+
const lost = (error) => this.onConnectionLost(connection, error);
|
|
482
|
+
(_connection$on = connection.on) === null || _connection$on === void 0 || _connection$on.call(connection, "error", lost);
|
|
483
|
+
(_connection$on2 = connection.on) === null || _connection$on2 === void 0 || _connection$on2.call(connection, "end", () => lost());
|
|
484
|
+
}
|
|
445
485
|
async connect() {
|
|
446
486
|
if (this.connectionPromise) return this.connectionPromise;
|
|
447
487
|
this.connectionPromise = this.establishConnection().catch((error) => {
|
|
@@ -478,6 +518,7 @@ var DatabaseTransport = class {
|
|
|
478
518
|
});
|
|
479
519
|
const connectionString = this.config.connectionString || `mongodb://${this.config.host}:${this.config.port}/${this.config.database}`;
|
|
480
520
|
this.connection = new MongoClient(connectionString);
|
|
521
|
+
this.watchConnection(this.connection);
|
|
481
522
|
await this.connection.connect();
|
|
482
523
|
await this.connection.db(this.config.database).admin().ping();
|
|
483
524
|
} catch (error) {
|
|
@@ -499,6 +540,7 @@ var DatabaseTransport = class {
|
|
|
499
540
|
if (this.config.password) config.password = this.config.password;
|
|
500
541
|
if (this.config.ssl) config.ssl = typeof this.config.ssl === "boolean" ? {} : this.config.ssl;
|
|
501
542
|
this.connection = new Client(config);
|
|
543
|
+
this.watchConnection(this.connection);
|
|
502
544
|
await this.connection.connect();
|
|
503
545
|
await this.createPostgreSQLTable();
|
|
504
546
|
} catch (error) {
|
|
@@ -519,6 +561,7 @@ var DatabaseTransport = class {
|
|
|
519
561
|
if (this.config.password) config.password = this.config.password;
|
|
520
562
|
if (this.config.ssl) config.ssl = typeof this.config.ssl === "boolean" ? {} : this.config.ssl;
|
|
521
563
|
this.connection = await mysql.createConnection(config);
|
|
564
|
+
this.watchConnection(this.connection);
|
|
522
565
|
await this.createMySQLTable();
|
|
523
566
|
} catch (error) {
|
|
524
567
|
throw new Error(`MySQL connection failed: ${error}`, { cause: error });
|
|
@@ -741,6 +784,7 @@ var DatabaseTransport = class {
|
|
|
741
784
|
this.flushTimer = void 0;
|
|
742
785
|
}
|
|
743
786
|
const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
|
|
787
|
+
this.nextConnectAt = 0;
|
|
744
788
|
if (this.flushPromise) await this.flushPromise.catch(() => {});
|
|
745
789
|
for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) try {
|
|
746
790
|
await this.flush();
|
|
@@ -749,17 +793,19 @@ var DatabaseTransport = class {
|
|
|
749
793
|
}
|
|
750
794
|
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`);
|
|
751
795
|
this.cap.report(0);
|
|
752
|
-
|
|
796
|
+
const connection = this.connection;
|
|
797
|
+
this.connection = void 0;
|
|
798
|
+
if (connection) switch (this.config.type) {
|
|
753
799
|
case "mongodb":
|
|
754
|
-
await
|
|
800
|
+
await connection.close();
|
|
755
801
|
break;
|
|
756
802
|
case "postgresql":
|
|
757
|
-
await
|
|
803
|
+
await connection.end();
|
|
758
804
|
break;
|
|
759
805
|
case "mysql":
|
|
760
|
-
await
|
|
806
|
+
await connection.end();
|
|
761
807
|
break;
|
|
762
|
-
case "sqlite": await
|
|
808
|
+
case "sqlite": await connection.close();
|
|
763
809
|
}
|
|
764
810
|
this.isConnected = false;
|
|
765
811
|
}
|
|
@@ -834,6 +880,9 @@ var AnalyticsTransport = class {
|
|
|
834
880
|
/** Set on the first write. Subclass fields don't exist yet while the base constructor runs. */
|
|
835
881
|
initPromise;
|
|
836
882
|
cap;
|
|
883
|
+
/** Consecutive failed drains; drives the backoff that stops a failing provider being re-sent every Nth log. */
|
|
884
|
+
failures = 0;
|
|
885
|
+
retryAt = 0;
|
|
837
886
|
constructor(name, config) {
|
|
838
887
|
this.name = name;
|
|
839
888
|
this.config = {
|
|
@@ -866,12 +915,13 @@ var AnalyticsTransport = class {
|
|
|
866
915
|
addToBatch(entry) {
|
|
867
916
|
this.batch.push(entry);
|
|
868
917
|
this.cap.enforce(this.batch);
|
|
869
|
-
|
|
870
|
-
|
|
918
|
+
const backoff = this.retryAt - Date.now();
|
|
919
|
+
if (this.batch.length >= (this.config.batchSize || 50) && backoff <= 0) this.flush().catch((err) => require_internal_log.internalError(`${this.name} batch flush failed`, err));
|
|
920
|
+
else if (!this.batchTimer && (this.config.flushInterval || backoff > 0)) {
|
|
871
921
|
var _this$batchTimer$unre, _this$batchTimer;
|
|
872
922
|
this.batchTimer = setTimeout(() => {
|
|
873
923
|
this.flush().catch((err) => require_internal_log.internalError(`${this.name} interval flush failed`, err));
|
|
874
|
-
}, this.config.flushInterval);
|
|
924
|
+
}, Math.max(this.config.flushInterval || 0, backoff));
|
|
875
925
|
(_this$batchTimer$unre = (_this$batchTimer = this.batchTimer).unref) === null || _this$batchTimer$unre === void 0 || _this$batchTimer$unre.call(_this$batchTimer);
|
|
876
926
|
}
|
|
877
927
|
}
|
|
@@ -898,7 +948,11 @@ var AnalyticsTransport = class {
|
|
|
898
948
|
this.batch = [];
|
|
899
949
|
try {
|
|
900
950
|
await this.sendBatch(entriesToSend);
|
|
951
|
+
this.failures = 0;
|
|
952
|
+
this.retryAt = 0;
|
|
901
953
|
} catch (error) {
|
|
954
|
+
this.failures += 1;
|
|
955
|
+
this.retryAt = Date.now() + Math.min(6e4, 1e3 * 2 ** (this.failures - 1));
|
|
902
956
|
require_secret_config.scrubError(error, this.secretValues());
|
|
903
957
|
require_internal_log.internalError(`Analytics transport ${this.name} flush failed`, error);
|
|
904
958
|
this.batch.unshift(...error instanceof PartialBatchError ? error.unsent : entriesToSend);
|
|
@@ -961,6 +1015,28 @@ var AnalyticsTransport = class {
|
|
|
961
1015
|
await this.ensureReady();
|
|
962
1016
|
}
|
|
963
1017
|
};
|
|
1018
|
+
// src/transports/fetch-timeout.ts
|
|
1019
|
+
/**
|
|
1020
|
+
* fetch() with a hard deadline, so an endpoint that accepts the connection and
|
|
1021
|
+
* never answers cannot hang a flush (and with it close()) forever. Uses an
|
|
1022
|
+
* AbortController rather than AbortSignal.timeout(), which needs Node 17.3+
|
|
1023
|
+
* while `engines` allows 16; the timer is unref'd so it never holds the process.
|
|
1024
|
+
*/
|
|
1025
|
+
async function fetchWithTimeout(url, init, timeoutMs = require_batch_buffer.DEFAULT_REQUEST_TIMEOUT_MS) {
|
|
1026
|
+
var _timer$unref;
|
|
1027
|
+
const controller = new AbortController();
|
|
1028
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1029
|
+
(_timer$unref = timer.unref) === null || _timer$unref === void 0 || _timer$unref.call(timer);
|
|
1030
|
+
try {
|
|
1031
|
+
return await fetch(url, {
|
|
1032
|
+
...init,
|
|
1033
|
+
signal: controller.signal
|
|
1034
|
+
});
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
if (controller.signal.aborted) throw new Error(`Request timed out after ${timeoutMs}ms`, { cause: error });
|
|
1037
|
+
throw error;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
964
1040
|
// src/transports/datadog.transport.ts
|
|
965
1041
|
const gzipAsync = (0, node_util.promisify)(node_zlib.gzip);
|
|
966
1042
|
const MAX_LOGS_PER_REQUEST = 1e3;
|
|
@@ -1200,7 +1276,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
1200
1276
|
const url = `${this.logsUrl}${endpoint}`;
|
|
1201
1277
|
try {
|
|
1202
1278
|
const compress = this.datadogConfig.compress === true;
|
|
1203
|
-
const response = await
|
|
1279
|
+
const response = await fetchWithTimeout(url, {
|
|
1204
1280
|
method: "POST",
|
|
1205
1281
|
headers: {
|
|
1206
1282
|
"Content-Type": "application/json",
|
|
@@ -1217,7 +1293,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
1217
1293
|
async makeMetricsRequest(endpoint, data) {
|
|
1218
1294
|
const url = `${this.metricsUrl}${endpoint}`;
|
|
1219
1295
|
try {
|
|
1220
|
-
const response = await
|
|
1296
|
+
const response = await fetchWithTimeout(url, {
|
|
1221
1297
|
method: "POST",
|
|
1222
1298
|
headers: {
|
|
1223
1299
|
"Content-Type": "application/json",
|
|
@@ -1262,7 +1338,7 @@ var DataDogTransport = class extends AnalyticsTransport {
|
|
|
1262
1338
|
};
|
|
1263
1339
|
const url = `${this.baseUrl}/api/v1/events`;
|
|
1264
1340
|
try {
|
|
1265
|
-
const response = await
|
|
1341
|
+
const response = await fetchWithTimeout(url, {
|
|
1266
1342
|
method: "POST",
|
|
1267
1343
|
headers: {
|
|
1268
1344
|
"Content-Type": "application/json",
|
|
@@ -1374,6 +1450,8 @@ var FileTransport = class {
|
|
|
1374
1450
|
lastDropWarning = 0;
|
|
1375
1451
|
/** Gzip and pruning of rotated files run off the write path, one at a time. */
|
|
1376
1452
|
housekeeping = Promise.resolve();
|
|
1453
|
+
exitListenerAttached = false;
|
|
1454
|
+
onExit = () => this.flushSyncOnExit();
|
|
1377
1455
|
constructor(config) {
|
|
1378
1456
|
this.config = {
|
|
1379
1457
|
format: "json",
|
|
@@ -1462,6 +1540,7 @@ var FileTransport = class {
|
|
|
1462
1540
|
await done;
|
|
1463
1541
|
}
|
|
1464
1542
|
enqueue(entry) {
|
|
1543
|
+
this.attachExitListener();
|
|
1465
1544
|
if (this.queueFull()) {
|
|
1466
1545
|
if (this.queuePolicy === "drop-oldest" && this.batch.length > 0) {
|
|
1467
1546
|
this.batch.shift();
|
|
@@ -1473,6 +1552,30 @@ var FileTransport = class {
|
|
|
1473
1552
|
this.batch.push(entry);
|
|
1474
1553
|
this.enqueued += 1;
|
|
1475
1554
|
}
|
|
1555
|
+
attachExitListener() {
|
|
1556
|
+
if (this.exitListenerAttached) return;
|
|
1557
|
+
this.exitListenerAttached = true;
|
|
1558
|
+
process.on("exit", this.onExit);
|
|
1559
|
+
}
|
|
1560
|
+
detachExitListener() {
|
|
1561
|
+
if (!this.exitListenerAttached) return;
|
|
1562
|
+
this.exitListenerAttached = false;
|
|
1563
|
+
process.removeListener("exit", this.onExit);
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Last chance on process exit: async writes cannot finish, so whatever is still
|
|
1567
|
+
* batched is appended synchronously to the current file.
|
|
1568
|
+
*/
|
|
1569
|
+
flushSyncOnExit() {
|
|
1570
|
+
if (this.batch.length === 0) return;
|
|
1571
|
+
const pending = this.batch;
|
|
1572
|
+
this.batch = [];
|
|
1573
|
+
this.enqueued -= pending.length;
|
|
1574
|
+
try {
|
|
1575
|
+
const content = pending.map((entry) => this.formatEntry(entry)).join("\n") + "\n";
|
|
1576
|
+
node_fs.appendFileSync(this.currentFilePath, content, { mode: this.fileMode });
|
|
1577
|
+
} catch {}
|
|
1578
|
+
}
|
|
1476
1579
|
queueFull() {
|
|
1477
1580
|
return this.batch.length + this.inFlight >= this.maxQueue;
|
|
1478
1581
|
}
|
|
@@ -1557,7 +1660,11 @@ var FileTransport = class {
|
|
|
1557
1660
|
case "json": return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
|
|
1558
1661
|
timestamp: entry.timestamp.toISOString(),
|
|
1559
1662
|
level: entry.level,
|
|
1560
|
-
message: entry.message
|
|
1663
|
+
message: entry.message,
|
|
1664
|
+
context: entry.context,
|
|
1665
|
+
traceId: entry.traceId,
|
|
1666
|
+
appName: entry.appName,
|
|
1667
|
+
environment: entry.environment
|
|
1561
1668
|
}, entry.data));
|
|
1562
1669
|
case "csv": return [
|
|
1563
1670
|
entry.timestamp.toISOString(),
|
|
@@ -1579,9 +1686,12 @@ var FileTransport = class {
|
|
|
1579
1686
|
this.batchTimer = void 0;
|
|
1580
1687
|
}
|
|
1581
1688
|
this.startDrain();
|
|
1582
|
-
} else if (!this.batchTimer && this.config.flushInterval)
|
|
1583
|
-
this.
|
|
1584
|
-
|
|
1689
|
+
} else if (!this.batchTimer && this.config.flushInterval) {
|
|
1690
|
+
this.batchTimer = setTimeout(() => {
|
|
1691
|
+
this.flush().catch((err) => require_internal_log.internalError("FileTransport interval flush failed", err));
|
|
1692
|
+
}, this.config.flushInterval);
|
|
1693
|
+
this.batchTimer.unref();
|
|
1694
|
+
}
|
|
1585
1695
|
}
|
|
1586
1696
|
/** Only ever called from drain(), so writes and rotations never overlap. */
|
|
1587
1697
|
async writeBatch(entries) {
|
|
@@ -1747,6 +1857,7 @@ var FileTransport = class {
|
|
|
1747
1857
|
this.batchTimer = void 0;
|
|
1748
1858
|
}
|
|
1749
1859
|
await this.flush();
|
|
1860
|
+
this.detachExitListener();
|
|
1750
1861
|
await this.housekeeping;
|
|
1751
1862
|
this.reportDropped(0);
|
|
1752
1863
|
}
|
|
@@ -1870,7 +1981,7 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
|
|
|
1870
1981
|
api_secret: this.gaConfig.apiSecret
|
|
1871
1982
|
});
|
|
1872
1983
|
try {
|
|
1873
|
-
const response = await
|
|
1984
|
+
const response = await fetchWithTimeout(`${url}?${params}`, {
|
|
1874
1985
|
method: "POST",
|
|
1875
1986
|
headers: { "Content-Type": "application/json" },
|
|
1876
1987
|
body: require_safe_stringify.stringifyForLog(payload)
|
|
@@ -2088,7 +2199,7 @@ var MixpanelTransport = class extends AnalyticsTransport {
|
|
|
2088
2199
|
async makeRequest(endpoint, data) {
|
|
2089
2200
|
const url = `${this.mixpanelConfig.endpoint || this.baseUrl}${endpoint}`;
|
|
2090
2201
|
try {
|
|
2091
|
-
const response = await
|
|
2202
|
+
const response = await fetchWithTimeout(url, {
|
|
2092
2203
|
method: "POST",
|
|
2093
2204
|
headers: {
|
|
2094
2205
|
"Content-Type": "application/json",
|
|
@@ -2257,7 +2368,7 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
2257
2368
|
const url = `${this.baseUrl}${endpoint}`;
|
|
2258
2369
|
const auth = Buffer.from(`${this.segmentConfig.writeKey}:`).toString("base64");
|
|
2259
2370
|
try {
|
|
2260
|
-
const response = await
|
|
2371
|
+
const response = await fetchWithTimeout(url, {
|
|
2261
2372
|
method: "POST",
|
|
2262
2373
|
headers: {
|
|
2263
2374
|
"Content-Type": "application/json",
|
|
@@ -2427,15 +2538,16 @@ var SegmentTransport = class extends AnalyticsTransport {
|
|
|
2427
2538
|
}
|
|
2428
2539
|
};
|
|
2429
2540
|
// src/transports/transport.manager.ts
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
}
|
|
2541
|
+
const DEFAULT_MAX_PENDING_RETRIES = 1e3;
|
|
2542
|
+
const RETRY_WARN_INTERVAL_MS = 5e3;
|
|
2433
2543
|
var TransportManager = class extends node_events.EventEmitter {
|
|
2434
2544
|
transports = /* @__PURE__ */ new Map();
|
|
2435
2545
|
metrics = /* @__PURE__ */ new Map();
|
|
2436
2546
|
isShuttingDown = false;
|
|
2437
2547
|
transportLevelPreferences = /* @__PURE__ */ new Map();
|
|
2438
2548
|
warnedPromptDeprecated = false;
|
|
2549
|
+
closePromise;
|
|
2550
|
+
retryStates = /* @__PURE__ */ new Map();
|
|
2439
2551
|
levelValues;
|
|
2440
2552
|
/**
|
|
2441
2553
|
* @param config Transport configuration.
|
|
@@ -2516,8 +2628,9 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2516
2628
|
if (!transport) return false;
|
|
2517
2629
|
this.transports.delete(id);
|
|
2518
2630
|
this.metrics.delete(id);
|
|
2631
|
+
this.drainRetries(id, transport);
|
|
2519
2632
|
if (transport.close) transport.close().catch((error) => {
|
|
2520
|
-
|
|
2633
|
+
require_internal_log.internalError(`Transport "${id}" failed to close`, error);
|
|
2521
2634
|
});
|
|
2522
2635
|
this.emit("transport:removed", id);
|
|
2523
2636
|
return true;
|
|
@@ -2533,7 +2646,10 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2533
2646
|
* sync path.
|
|
2534
2647
|
*/
|
|
2535
2648
|
write(entry) {
|
|
2536
|
-
if (this.isShuttingDown)
|
|
2649
|
+
if (this.isShuttingDown) {
|
|
2650
|
+
this.writeAfterClose(entry);
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2537
2653
|
const transportEntry = {
|
|
2538
2654
|
timestamp: typeof entry.timestamp === "string" ? new Date(entry.timestamp) : entry.timestamp,
|
|
2539
2655
|
level: entry.level,
|
|
@@ -2571,6 +2687,27 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2571
2687
|
}
|
|
2572
2688
|
});
|
|
2573
2689
|
}
|
|
2690
|
+
/**
|
|
2691
|
+
* Transports are gone once closed, but the app may still log (its own signal
|
|
2692
|
+
* handler, a late async callback). Emit such lines on stdout/stderr rather
|
|
2693
|
+
* than losing them silently.
|
|
2694
|
+
*/
|
|
2695
|
+
writeAfterClose(entry) {
|
|
2696
|
+
const line = `${require_safe_stringify.stringifyForLog({
|
|
2697
|
+
timestamp: entry.timestamp,
|
|
2698
|
+
level: entry.level,
|
|
2699
|
+
message: entry.message,
|
|
2700
|
+
appName: entry.appName,
|
|
2701
|
+
context: entry.context,
|
|
2702
|
+
traceId: entry.traceId,
|
|
2703
|
+
...entry.payload
|
|
2704
|
+
})}\n`;
|
|
2705
|
+
const level = String(entry.level).toLowerCase();
|
|
2706
|
+
const stream = level === "error" || level === "warn" ? "stderr" : "stdout";
|
|
2707
|
+
try {
|
|
2708
|
+
process[stream].write(line);
|
|
2709
|
+
} catch {}
|
|
2710
|
+
}
|
|
2574
2711
|
writeToTransport(id, transport, entry) {
|
|
2575
2712
|
const startTime = Date.now();
|
|
2576
2713
|
const metrics = this.metrics.get(id);
|
|
@@ -2597,43 +2734,86 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2597
2734
|
onSuccess();
|
|
2598
2735
|
return;
|
|
2599
2736
|
}
|
|
2600
|
-
return this._writeWithRetry(transport, entry).then(
|
|
2737
|
+
return this._writeWithRetry(id, transport, entry).then((written) => {
|
|
2738
|
+
if (written) onSuccess();
|
|
2739
|
+
}, onError);
|
|
2601
2740
|
}
|
|
2602
2741
|
/**
|
|
2603
2742
|
* Feature 9: Multi-transport retry + failover.
|
|
2604
2743
|
*
|
|
2605
|
-
*
|
|
2606
|
-
*
|
|
2607
|
-
*
|
|
2744
|
+
* The first attempt is awaited by the caller. If it fails, the entry moves to
|
|
2745
|
+
* a bounded per-transport retry queue and the caller's promise resolves, so a
|
|
2746
|
+
* down transport never holds a log call across backoff. The queue retries up
|
|
2747
|
+
* to `retry.maxRetries` more times with the configured backoff, then routes
|
|
2748
|
+
* the entry to the fallback transport (if any) and calls `onExhausted`.
|
|
2749
|
+
* Returns true when the first attempt succeeded.
|
|
2608
2750
|
*/
|
|
2609
|
-
async _writeWithRetry(transport, entry) {
|
|
2610
|
-
|
|
2611
|
-
if (!retryCfg || !retryCfg.maxRetries) {
|
|
2751
|
+
async _writeWithRetry(id, transport, entry) {
|
|
2752
|
+
try {
|
|
2612
2753
|
await transport.write(entry);
|
|
2613
|
-
return;
|
|
2754
|
+
return true;
|
|
2755
|
+
} catch (err) {
|
|
2756
|
+
this.enqueueRetry(id, transport, entry, err instanceof Error ? err : new Error(String(err)));
|
|
2757
|
+
return false;
|
|
2614
2758
|
}
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2759
|
+
}
|
|
2760
|
+
enqueueRetry(id, transport, entry, error) {
|
|
2761
|
+
let state = this.retryStates.get(id);
|
|
2762
|
+
if (!state) {
|
|
2763
|
+
state = {
|
|
2764
|
+
queue: [],
|
|
2765
|
+
timer: void 0,
|
|
2766
|
+
running: false,
|
|
2767
|
+
dropped: 0,
|
|
2768
|
+
lastWarn: 0
|
|
2769
|
+
};
|
|
2770
|
+
this.retryStates.set(id, state);
|
|
2771
|
+
}
|
|
2772
|
+
const maxPending = transport.retry.maxPending ?? DEFAULT_MAX_PENDING_RETRIES;
|
|
2773
|
+
while (state.queue.length >= maxPending) {
|
|
2774
|
+
state.queue.shift();
|
|
2775
|
+
state.dropped++;
|
|
2776
|
+
}
|
|
2777
|
+
this.warnDropped(id, state);
|
|
2778
|
+
this.scheduleRetry(id, transport, state, {
|
|
2779
|
+
entry,
|
|
2780
|
+
attempt: 0,
|
|
2781
|
+
due: 0
|
|
2782
|
+
}, error);
|
|
2783
|
+
this.pumpRetries(id, transport, state);
|
|
2784
|
+
}
|
|
2785
|
+
warnDropped(id, state) {
|
|
2786
|
+
const now = Date.now();
|
|
2787
|
+
if (state.dropped > 0 && now - state.lastWarn >= RETRY_WARN_INTERVAL_MS) {
|
|
2788
|
+
require_internal_log.internalWarn(`TransportManager: retry queue for "${id}" is full; dropped ${state.dropped} oldest log entr${state.dropped === 1 ? "y" : "ies"}`);
|
|
2789
|
+
state.dropped = 0;
|
|
2790
|
+
state.lastWarn = now;
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
/** Queues `item` for its next attempt, or finishes it when retries ran out. */
|
|
2794
|
+
scheduleRetry(id, transport, state, item, error) {
|
|
2795
|
+
const { maxRetries = 0, backoff = "exponential", delay = 500, maxDelay = 3e4 } = transport.retry;
|
|
2796
|
+
if (item.attempt >= maxRetries) {
|
|
2797
|
+
this.exhaust(id, transport, item.entry, error);
|
|
2619
2798
|
return;
|
|
2620
|
-
} catch (err) {
|
|
2621
|
-
lastError = err instanceof Error ? err : new Error(String(err));
|
|
2622
|
-
if (attempt < maxRetries) {
|
|
2623
|
-
let wait;
|
|
2624
|
-
switch (backoff) {
|
|
2625
|
-
case "fixed":
|
|
2626
|
-
wait = baseDelay;
|
|
2627
|
-
break;
|
|
2628
|
-
case "linear":
|
|
2629
|
-
wait = baseDelay * (attempt + 1);
|
|
2630
|
-
break;
|
|
2631
|
-
default: wait = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
2632
|
-
}
|
|
2633
|
-
this.emit("transport:retry", transport.name, attempt + 1, maxRetries, wait);
|
|
2634
|
-
await _sleep(wait);
|
|
2635
|
-
}
|
|
2636
2799
|
}
|
|
2800
|
+
let wait;
|
|
2801
|
+
switch (backoff) {
|
|
2802
|
+
case "fixed":
|
|
2803
|
+
wait = delay;
|
|
2804
|
+
break;
|
|
2805
|
+
case "linear":
|
|
2806
|
+
wait = delay * (item.attempt + 1);
|
|
2807
|
+
break;
|
|
2808
|
+
default: wait = Math.min(delay * Math.pow(2, item.attempt), maxDelay);
|
|
2809
|
+
}
|
|
2810
|
+
item.attempt++;
|
|
2811
|
+
item.due = Date.now() + wait;
|
|
2812
|
+
state.queue.push(item);
|
|
2813
|
+
this.emit("transport:retry", transport.name, item.attempt, maxRetries, wait);
|
|
2814
|
+
}
|
|
2815
|
+
async exhaust(id, transport, entry, error) {
|
|
2816
|
+
const { fallback, onExhausted } = transport.retry;
|
|
2637
2817
|
if (fallback) {
|
|
2638
2818
|
this.emit("transport:fallback", transport.name, fallback.name);
|
|
2639
2819
|
try {
|
|
@@ -2641,8 +2821,65 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2641
2821
|
return;
|
|
2642
2822
|
} catch {}
|
|
2643
2823
|
}
|
|
2644
|
-
|
|
2645
|
-
|
|
2824
|
+
const metrics = this.metrics.get(id);
|
|
2825
|
+
if (metrics) metrics.errors++;
|
|
2826
|
+
try {
|
|
2827
|
+
onExhausted === null || onExhausted === void 0 || onExhausted(error, entry);
|
|
2828
|
+
} catch (hookError) {
|
|
2829
|
+
require_internal_log.internalWarn(`TransportManager: onExhausted for "${id}" threw: ${String(hookError)}`);
|
|
2830
|
+
}
|
|
2831
|
+
if (this.listenerCount("error") > 0) this.emit("error", error, id);
|
|
2832
|
+
}
|
|
2833
|
+
/** One serial worker per transport: the earliest-due entry is retried first. */
|
|
2834
|
+
pumpRetries(id, transport, state) {
|
|
2835
|
+
var _state$timer$unref, _state$timer;
|
|
2836
|
+
if (state.running || state.timer || state.queue.length === 0) return;
|
|
2837
|
+
let next = 0;
|
|
2838
|
+
for (let i = 1; i < state.queue.length; i++) if (state.queue[i].due < state.queue[next].due) next = i;
|
|
2839
|
+
const wait = Math.max(0, state.queue[next].due - Date.now());
|
|
2840
|
+
state.timer = setTimeout(() => {
|
|
2841
|
+
state.timer = void 0;
|
|
2842
|
+
this.runRetry(id, transport, state);
|
|
2843
|
+
}, wait);
|
|
2844
|
+
(_state$timer$unref = (_state$timer = state.timer).unref) === null || _state$timer$unref === void 0 || _state$timer$unref.call(_state$timer);
|
|
2845
|
+
}
|
|
2846
|
+
async runRetry(id, transport, state) {
|
|
2847
|
+
if (state.queue.length === 0) return;
|
|
2848
|
+
let next = 0;
|
|
2849
|
+
for (let i = 1; i < state.queue.length; i++) if (state.queue[i].due < state.queue[next].due) next = i;
|
|
2850
|
+
const [item] = state.queue.splice(next, 1);
|
|
2851
|
+
if (!item) return;
|
|
2852
|
+
state.running = true;
|
|
2853
|
+
try {
|
|
2854
|
+
await transport.write(item.entry);
|
|
2855
|
+
const metrics = this.metrics.get(id);
|
|
2856
|
+
if (metrics) {
|
|
2857
|
+
metrics.logsWritten++;
|
|
2858
|
+
metrics.lastWrite = /* @__PURE__ */ new Date();
|
|
2859
|
+
}
|
|
2860
|
+
this.emit("log", item.entry);
|
|
2861
|
+
} catch (err) {
|
|
2862
|
+
this.scheduleRetry(id, transport, state, item, err instanceof Error ? err : new Error(String(err)));
|
|
2863
|
+
} finally {
|
|
2864
|
+
state.running = false;
|
|
2865
|
+
}
|
|
2866
|
+
if (!this.isShuttingDown) this.pumpRetries(id, transport, state);
|
|
2867
|
+
}
|
|
2868
|
+
/** Stops a transport's retry worker and hands what is still queued to its fallback. */
|
|
2869
|
+
async drainRetries(id, transport) {
|
|
2870
|
+
var _transport$retry;
|
|
2871
|
+
const state = this.retryStates.get(id);
|
|
2872
|
+
if (!state) return;
|
|
2873
|
+
this.retryStates.delete(id);
|
|
2874
|
+
if (state.timer) clearTimeout(state.timer);
|
|
2875
|
+
state.timer = void 0;
|
|
2876
|
+
const fallback = transport === null || transport === void 0 || (_transport$retry = transport.retry) === null || _transport$retry === void 0 ? void 0 : _transport$retry.fallback;
|
|
2877
|
+
if (state.queue.length === 0) return;
|
|
2878
|
+
if (!fallback) {
|
|
2879
|
+
require_internal_log.internalWarn(`TransportManager: "${id}" closed with ${state.queue.length} log entr${state.queue.length === 1 ? "y" : "ies"} still awaiting retry`);
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
await Promise.allSettled(state.queue.map((item) => fallback.write(item.entry)));
|
|
2646
2883
|
}
|
|
2647
2884
|
shouldTransportHandle(transport, level, transportId) {
|
|
2648
2885
|
if (transportId && this.transportLevelPreferences.has(transportId)) return this.transportLevelPreferences.get(transportId).includes(level.toLowerCase());
|
|
@@ -2661,19 +2898,35 @@ var TransportManager = class extends node_events.EventEmitter {
|
|
|
2661
2898
|
if (readyPromises.length > 0) await Promise.all(readyPromises);
|
|
2662
2899
|
}
|
|
2663
2900
|
async flush() {
|
|
2901
|
+
await this.flushTransports(false);
|
|
2902
|
+
}
|
|
2903
|
+
/**
|
|
2904
|
+
* @param skipClosable Leave out transports with a close(): close() flushes
|
|
2905
|
+
* them itself, and a second flush first would double the time a hung
|
|
2906
|
+
* endpoint can hold shutdown.
|
|
2907
|
+
*/
|
|
2908
|
+
async flushTransports(skipClosable) {
|
|
2664
2909
|
const flushPromises = [];
|
|
2665
|
-
for (const [id, transport] of this.transports)
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2910
|
+
for (const [id, transport] of this.transports) {
|
|
2911
|
+
if (skipClosable && transport.close) continue;
|
|
2912
|
+
if (this.isBatchTransport(transport)) {
|
|
2913
|
+
const flushPromise = transport.flush().catch((error) => {
|
|
2914
|
+
this.emit("error", error, id);
|
|
2915
|
+
});
|
|
2916
|
+
flushPromises.push(flushPromise);
|
|
2917
|
+
}
|
|
2670
2918
|
}
|
|
2671
2919
|
await Promise.allSettled(flushPromises);
|
|
2672
2920
|
this.emit("flush", "all", this.transports.size);
|
|
2673
2921
|
}
|
|
2674
|
-
|
|
2675
|
-
|
|
2922
|
+
close() {
|
|
2923
|
+
this.closePromise ??= this.closeOnce();
|
|
2924
|
+
return this.closePromise;
|
|
2925
|
+
}
|
|
2926
|
+
async closeOnce() {
|
|
2927
|
+
await this.flushTransports(true);
|
|
2676
2928
|
this.isShuttingDown = true;
|
|
2929
|
+
await Promise.allSettled([...this.retryStates.keys()].map((id) => this.drainRetries(id, this.transports.get(id))));
|
|
2677
2930
|
const closePromises = [];
|
|
2678
2931
|
for (const [id, transport] of this.transports) if (transport.close) {
|
|
2679
2932
|
const closePromise = transport.close().catch((error) => {
|
|
@@ -2997,4 +3250,4 @@ Object.defineProperty(exports, "stripControlChars", {
|
|
|
2997
3250
|
}
|
|
2998
3251
|
});
|
|
2999
3252
|
|
|
3000
|
-
//# sourceMappingURL=otel-
|
|
3253
|
+
//# sourceMappingURL=otel-8ypFGG19.js.map
|