@rawnodes/logger 2.10.0 → 2.12.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/dist/index.d.mts +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +67 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -218,20 +218,24 @@ declare class TelegramTransport extends BaseHttpTransport {
|
|
|
218
218
|
declare class CloudWatchTransport extends BaseHttpTransport {
|
|
219
219
|
private config;
|
|
220
220
|
private client;
|
|
221
|
-
private sequenceToken;
|
|
222
221
|
private initialized;
|
|
223
222
|
private initPromise;
|
|
223
|
+
private initFailures;
|
|
224
|
+
private nextInitAttempt;
|
|
224
225
|
private resolvedLogStreamName;
|
|
225
226
|
private maskReplacer;
|
|
227
|
+
private static readonly INIT_BACKOFF_BASE_MS;
|
|
228
|
+
private static readonly INIT_BACKOFF_MAX_MS;
|
|
226
229
|
constructor(config: CloudWatchConfig, configHostname?: string, maskReplacerFn?: MaskReplacer);
|
|
227
230
|
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
231
|
+
private putLogEvents;
|
|
228
232
|
private ensureInitialized;
|
|
229
233
|
private initialize;
|
|
230
234
|
private createLogGroupIfNotExists;
|
|
231
235
|
private createLogStreamIfNotExists;
|
|
232
|
-
private fetchSequenceToken;
|
|
233
236
|
private isResourceAlreadyExistsError;
|
|
234
|
-
private
|
|
237
|
+
private isResourceNotFoundError;
|
|
238
|
+
private isAwsErrorNamed;
|
|
235
239
|
}
|
|
236
240
|
|
|
237
241
|
declare class ZohoCliqTransport extends BaseHttpTransport {
|
|
@@ -313,6 +317,12 @@ interface HttpErrorData {
|
|
|
313
317
|
url?: string;
|
|
314
318
|
/** HTTP method (GET, POST, etc.) */
|
|
315
319
|
method?: string;
|
|
320
|
+
/** Request query params */
|
|
321
|
+
params?: unknown;
|
|
322
|
+
/** Request body */
|
|
323
|
+
requestData?: unknown;
|
|
324
|
+
/** Request headers */
|
|
325
|
+
requestHeaders?: unknown;
|
|
316
326
|
/** Error code (e.g., ECONNREFUSED, ETIMEDOUT) */
|
|
317
327
|
code?: string;
|
|
318
328
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -218,20 +218,24 @@ declare class TelegramTransport extends BaseHttpTransport {
|
|
|
218
218
|
declare class CloudWatchTransport extends BaseHttpTransport {
|
|
219
219
|
private config;
|
|
220
220
|
private client;
|
|
221
|
-
private sequenceToken;
|
|
222
221
|
private initialized;
|
|
223
222
|
private initPromise;
|
|
223
|
+
private initFailures;
|
|
224
|
+
private nextInitAttempt;
|
|
224
225
|
private resolvedLogStreamName;
|
|
225
226
|
private maskReplacer;
|
|
227
|
+
private static readonly INIT_BACKOFF_BASE_MS;
|
|
228
|
+
private static readonly INIT_BACKOFF_MAX_MS;
|
|
226
229
|
constructor(config: CloudWatchConfig, configHostname?: string, maskReplacerFn?: MaskReplacer);
|
|
227
230
|
protected sendBatch(messages: BufferedMessage[]): Promise<void>;
|
|
231
|
+
private putLogEvents;
|
|
228
232
|
private ensureInitialized;
|
|
229
233
|
private initialize;
|
|
230
234
|
private createLogGroupIfNotExists;
|
|
231
235
|
private createLogStreamIfNotExists;
|
|
232
|
-
private fetchSequenceToken;
|
|
233
236
|
private isResourceAlreadyExistsError;
|
|
234
|
-
private
|
|
237
|
+
private isResourceNotFoundError;
|
|
238
|
+
private isAwsErrorNamed;
|
|
235
239
|
}
|
|
236
240
|
|
|
237
241
|
declare class ZohoCliqTransport extends BaseHttpTransport {
|
|
@@ -313,6 +317,12 @@ interface HttpErrorData {
|
|
|
313
317
|
url?: string;
|
|
314
318
|
/** HTTP method (GET, POST, etc.) */
|
|
315
319
|
method?: string;
|
|
320
|
+
/** Request query params */
|
|
321
|
+
params?: unknown;
|
|
322
|
+
/** Request body */
|
|
323
|
+
requestData?: unknown;
|
|
324
|
+
/** Request headers */
|
|
325
|
+
requestHeaders?: unknown;
|
|
316
326
|
/** Error code (e.g., ECONNREFUSED, ETIMEDOUT) */
|
|
317
327
|
code?: string;
|
|
318
328
|
}
|
package/dist/index.js
CHANGED
|
@@ -651,14 +651,21 @@ function resolveLogStreamName(config, configHostname) {
|
|
|
651
651
|
}
|
|
652
652
|
return hostname;
|
|
653
653
|
}
|
|
654
|
-
var CloudWatchTransport = class extends BaseHttpTransport {
|
|
654
|
+
var CloudWatchTransport = class _CloudWatchTransport extends BaseHttpTransport {
|
|
655
655
|
config;
|
|
656
656
|
client;
|
|
657
|
-
sequenceToken;
|
|
658
657
|
initialized = false;
|
|
659
658
|
initPromise = null;
|
|
659
|
+
initFailures = 0;
|
|
660
|
+
nextInitAttempt = 0;
|
|
660
661
|
resolvedLogStreamName;
|
|
661
662
|
maskReplacer;
|
|
663
|
+
// Backoff bounds for repeated init failures (e.g. IAM not yet propagated,
|
|
664
|
+
// throttling). Without this, a sustained outage makes every flush re-run
|
|
665
|
+
// initialize() back-to-back and hammer the CloudWatch control-plane APIs,
|
|
666
|
+
// which only deepens the throttling.
|
|
667
|
+
static INIT_BACKOFF_BASE_MS = 1e3;
|
|
668
|
+
static INIT_BACKOFF_MAX_MS = 3e4;
|
|
662
669
|
constructor(config, configHostname, maskReplacerFn) {
|
|
663
670
|
super({
|
|
664
671
|
batchSize: config.batchSize ?? 100,
|
|
@@ -694,36 +701,46 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
694
701
|
}, replacer)
|
|
695
702
|
}));
|
|
696
703
|
logEvents.sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0));
|
|
697
|
-
const command = new clientCloudwatchLogs.PutLogEventsCommand({
|
|
698
|
-
logGroupName: this.config.logGroupName,
|
|
699
|
-
logStreamName: this.resolvedLogStreamName,
|
|
700
|
-
logEvents,
|
|
701
|
-
sequenceToken: this.sequenceToken
|
|
702
|
-
});
|
|
703
704
|
try {
|
|
704
|
-
|
|
705
|
-
this.sequenceToken = response.nextSequenceToken;
|
|
705
|
+
await this.putLogEvents(logEvents);
|
|
706
706
|
} catch (error) {
|
|
707
|
-
if (this.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
logEvents,
|
|
713
|
-
sequenceToken: this.sequenceToken
|
|
714
|
-
});
|
|
715
|
-
const response = await this.client.send(retryCommand);
|
|
716
|
-
this.sequenceToken = response.nextSequenceToken;
|
|
707
|
+
if (this.isResourceNotFoundError(error)) {
|
|
708
|
+
this.initialized = false;
|
|
709
|
+
this.initPromise = null;
|
|
710
|
+
await this.ensureInitialized();
|
|
711
|
+
await this.putLogEvents(logEvents);
|
|
717
712
|
} else {
|
|
718
713
|
throw error;
|
|
719
714
|
}
|
|
720
715
|
}
|
|
721
716
|
}
|
|
717
|
+
// PutLogEvents no longer requires a sequence token: since 2023 CloudWatch
|
|
718
|
+
// Logs ignores the `sequenceToken` field for sequential writes, so we omit it
|
|
719
|
+
// entirely. This also removes the need for DescribeLogStreams (and the
|
|
720
|
+
// logs:DescribeLogStreams IAM permission) on the hot path.
|
|
721
|
+
async putLogEvents(logEvents) {
|
|
722
|
+
await this.client.send(
|
|
723
|
+
new clientCloudwatchLogs.PutLogEventsCommand({
|
|
724
|
+
logGroupName: this.config.logGroupName,
|
|
725
|
+
logStreamName: this.resolvedLogStreamName,
|
|
726
|
+
logEvents
|
|
727
|
+
})
|
|
728
|
+
);
|
|
729
|
+
}
|
|
722
730
|
async ensureInitialized() {
|
|
723
731
|
if (this.initialized) return;
|
|
732
|
+
if (!this.initPromise && Date.now() < this.nextInitAttempt) {
|
|
733
|
+
throw new Error("CloudWatch transport initialization is backing off");
|
|
734
|
+
}
|
|
724
735
|
if (!this.initPromise) {
|
|
725
736
|
this.initPromise = this.initialize().catch((err) => {
|
|
726
737
|
this.initPromise = null;
|
|
738
|
+
this.initFailures += 1;
|
|
739
|
+
const delay = Math.min(
|
|
740
|
+
_CloudWatchTransport.INIT_BACKOFF_MAX_MS,
|
|
741
|
+
_CloudWatchTransport.INIT_BACKOFF_BASE_MS * 2 ** (this.initFailures - 1)
|
|
742
|
+
);
|
|
743
|
+
this.nextInitAttempt = Date.now() + delay;
|
|
727
744
|
throw err;
|
|
728
745
|
});
|
|
729
746
|
}
|
|
@@ -736,8 +753,9 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
736
753
|
if (this.config.createLogStream !== false) {
|
|
737
754
|
await this.createLogStreamIfNotExists();
|
|
738
755
|
}
|
|
739
|
-
await this.fetchSequenceToken();
|
|
740
756
|
this.initialized = true;
|
|
757
|
+
this.initFailures = 0;
|
|
758
|
+
this.nextInitAttempt = 0;
|
|
741
759
|
}
|
|
742
760
|
async createLogGroupIfNotExists() {
|
|
743
761
|
try {
|
|
@@ -766,22 +784,14 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
766
784
|
}
|
|
767
785
|
}
|
|
768
786
|
}
|
|
769
|
-
async fetchSequenceToken() {
|
|
770
|
-
const response = await this.client.send(
|
|
771
|
-
new clientCloudwatchLogs.DescribeLogStreamsCommand({
|
|
772
|
-
logGroupName: this.config.logGroupName,
|
|
773
|
-
logStreamNamePrefix: this.resolvedLogStreamName,
|
|
774
|
-
limit: 1
|
|
775
|
-
})
|
|
776
|
-
);
|
|
777
|
-
const stream = response.logStreams?.find((s) => s.logStreamName === this.resolvedLogStreamName);
|
|
778
|
-
this.sequenceToken = stream?.uploadSequenceToken;
|
|
779
|
-
}
|
|
780
787
|
isResourceAlreadyExistsError(error) {
|
|
781
|
-
return
|
|
788
|
+
return this.isAwsErrorNamed(error, "ResourceAlreadyExistsException");
|
|
789
|
+
}
|
|
790
|
+
isResourceNotFoundError(error) {
|
|
791
|
+
return this.isAwsErrorNamed(error, "ResourceNotFoundException");
|
|
782
792
|
}
|
|
783
|
-
|
|
784
|
-
return typeof error === "object" && error !== null && "name" in error && error.name ===
|
|
793
|
+
isAwsErrorNamed(error, name) {
|
|
794
|
+
return typeof error === "object" && error !== null && "name" in error && error.name === name;
|
|
785
795
|
}
|
|
786
796
|
};
|
|
787
797
|
|
|
@@ -1688,13 +1698,22 @@ function extractAxiosHttpData(error) {
|
|
|
1688
1698
|
}
|
|
1689
1699
|
}
|
|
1690
1700
|
if (error.config) {
|
|
1691
|
-
const { url, baseURL, method } = error.config;
|
|
1701
|
+
const { url, baseURL, method, params, data, headers } = error.config;
|
|
1692
1702
|
if (url) {
|
|
1693
1703
|
httpData.url = baseURL && !url.startsWith("http") ? `${baseURL}${url}` : url;
|
|
1694
1704
|
}
|
|
1695
1705
|
if (method) {
|
|
1696
1706
|
httpData.method = method.toUpperCase();
|
|
1697
1707
|
}
|
|
1708
|
+
if (params !== void 0) {
|
|
1709
|
+
httpData.params = sanitizeResponseData(params);
|
|
1710
|
+
}
|
|
1711
|
+
if (data !== void 0) {
|
|
1712
|
+
httpData.requestData = sanitizeResponseData(data);
|
|
1713
|
+
}
|
|
1714
|
+
if (headers !== void 0) {
|
|
1715
|
+
httpData.requestHeaders = sanitizeResponseData(headers);
|
|
1716
|
+
}
|
|
1698
1717
|
}
|
|
1699
1718
|
return httpData;
|
|
1700
1719
|
}
|
|
@@ -1732,6 +1751,18 @@ function extractGenericHttpData(error) {
|
|
|
1732
1751
|
httpData.method = config.method.toUpperCase();
|
|
1733
1752
|
hasData = true;
|
|
1734
1753
|
}
|
|
1754
|
+
if (config.params !== void 0) {
|
|
1755
|
+
httpData.params = sanitizeResponseData(config.params);
|
|
1756
|
+
hasData = true;
|
|
1757
|
+
}
|
|
1758
|
+
if (config.data !== void 0) {
|
|
1759
|
+
httpData.requestData = sanitizeResponseData(config.data);
|
|
1760
|
+
hasData = true;
|
|
1761
|
+
}
|
|
1762
|
+
if (config.headers !== void 0) {
|
|
1763
|
+
httpData.requestHeaders = sanitizeResponseData(config.headers);
|
|
1764
|
+
hasData = true;
|
|
1765
|
+
}
|
|
1735
1766
|
}
|
|
1736
1767
|
return hasData ? httpData : void 0;
|
|
1737
1768
|
}
|