@aws-amplify/core 4.3.14 → 4.3.15-cloud-logging.10
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/aws-amplify-core.js +571 -391
- package/dist/aws-amplify-core.js.map +1 -1
- package/dist/aws-amplify-core.min.js +6 -6
- package/dist/aws-amplify-core.min.js.map +1 -1
- package/lib/Hub.js +1 -0
- package/lib/Hub.js.map +1 -1
- package/lib/Logger/ConsoleLogger.d.ts +6 -0
- package/lib/Logger/ConsoleLogger.js +118 -43
- package/lib/Logger/ConsoleLogger.js.map +1 -1
- package/lib/Platform/version.d.ts +1 -1
- package/lib/Platform/version.js +1 -1
- package/lib/Providers/AWSCloudWatchProvider.d.ts +11 -3
- package/lib/Providers/AWSCloudWatchProvider.js +97 -37
- package/lib/Providers/AWSCloudWatchProvider.js.map +1 -1
- package/lib/Providers/AmazonKinesisLoggingProvider.d.ts +13 -0
- package/lib/Providers/AmazonKinesisLoggingProvider.js +30 -0
- package/lib/Providers/AmazonKinesisLoggingProvider.js.map +1 -0
- package/lib/Util/Constants.d.ts +3 -1
- package/lib/Util/Constants.js +5 -0
- package/lib/Util/Constants.js.map +1 -1
- package/lib/types/types.d.ts +13 -0
- package/lib-esm/Hub.js +1 -0
- package/lib-esm/Hub.js.map +1 -1
- package/lib-esm/Logger/ConsoleLogger.d.ts +6 -0
- package/lib-esm/Logger/ConsoleLogger.js +118 -43
- package/lib-esm/Logger/ConsoleLogger.js.map +1 -1
- package/lib-esm/Platform/version.d.ts +1 -1
- package/lib-esm/Platform/version.js +1 -1
- package/lib-esm/Providers/AWSCloudWatchProvider.d.ts +11 -3
- package/lib-esm/Providers/AWSCloudWatchProvider.js +97 -37
- package/lib-esm/Providers/AWSCloudWatchProvider.js.map +1 -1
- package/lib-esm/Providers/AmazonKinesisLoggingProvider.d.ts +13 -0
- package/lib-esm/Providers/AmazonKinesisLoggingProvider.js +28 -0
- package/lib-esm/Providers/AmazonKinesisLoggingProvider.js.map +1 -0
- package/lib-esm/Util/Constants.d.ts +3 -1
- package/lib-esm/Util/Constants.js +4 -1
- package/lib-esm/Util/Constants.js.map +1 -1
- package/lib-esm/types/types.d.ts +13 -0
- package/package.json +4 -3
- package/src/Hub.ts +1 -0
- package/src/Logger/ConsoleLogger.ts +119 -34
- package/src/Platform/version.ts +1 -1
- package/src/Providers/AWSCloudWatchProvider.ts +112 -18
- package/src/Providers/AmazonKinesisLoggingProvider.ts +43 -0
- package/src/Util/Constants.ts +7 -0
- package/src/types/types.ts +79 -62
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
AWSCloudWatchProviderOptions,
|
|
40
40
|
CloudWatchDataTracker,
|
|
41
41
|
LoggingProvider,
|
|
42
|
+
AmplifyConfigure,
|
|
42
43
|
} from '../types/types';
|
|
43
44
|
import { Credentials } from '../..';
|
|
44
45
|
import { ConsoleLogger as Logger } from '../Logger';
|
|
@@ -54,8 +55,15 @@ import {
|
|
|
54
55
|
RETRY_ERROR_CODES,
|
|
55
56
|
} from '../Util/Constants';
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
if (
|
|
59
|
+
typeof window === 'undefined' ||
|
|
60
|
+
(typeof window === 'object' && !window.TextEncoder)
|
|
61
|
+
) {
|
|
62
|
+
require('fast-text-encoding');
|
|
63
|
+
}
|
|
58
64
|
|
|
65
|
+
const logger = new Logger('AWSCloudWatch');
|
|
66
|
+
const INTERVAL = 10000;
|
|
59
67
|
class AWSCloudWatchProvider implements LoggingProvider {
|
|
60
68
|
static readonly PROVIDER_NAME = AWS_CLOUDWATCH_PROVIDER_NAME;
|
|
61
69
|
static readonly CATEGORY = AWS_CLOUDWATCH_CATEGORY;
|
|
@@ -65,15 +73,25 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
65
73
|
private _currentLogBatch: InputLogEvent[];
|
|
66
74
|
private _timer;
|
|
67
75
|
private _nextSequenceToken: string | undefined;
|
|
76
|
+
private _processing: boolean;
|
|
77
|
+
private _initialized = false;
|
|
78
|
+
private _preFlightCheck: () => Promise<boolean>;
|
|
79
|
+
|
|
80
|
+
constructor(config?: AmplifyConfigure) {
|
|
81
|
+
console.log('cstr', config);
|
|
82
|
+
if (!this._initialized) {
|
|
83
|
+
this.configure(config);
|
|
84
|
+
|
|
85
|
+
this._dataTracker = {
|
|
86
|
+
eventUploadInProgress: false,
|
|
87
|
+
logEvents: [],
|
|
88
|
+
verifiedLogGroup: { logGroupName: this._config.logGroupName },
|
|
89
|
+
};
|
|
68
90
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
logEvents: [],
|
|
74
|
-
};
|
|
75
|
-
this._currentLogBatch = [];
|
|
76
|
-
this._initiateLogPushInterval();
|
|
91
|
+
this._currentLogBatch = [];
|
|
92
|
+
this._initiateLogPushInterval();
|
|
93
|
+
this._initialized = true;
|
|
94
|
+
}
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
public getProviderName(): string {
|
|
@@ -88,9 +106,13 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
88
106
|
return this._dataTracker.logEvents;
|
|
89
107
|
}
|
|
90
108
|
|
|
91
|
-
public
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
public setPreFlightCheck(cb): void {
|
|
110
|
+
if (typeof cb === 'function') {
|
|
111
|
+
this._preFlightCheck = cb;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public configure(config?: AmplifyConfigure): AWSCloudWatchProviderOptions {
|
|
94
116
|
if (!config) return this._config || {};
|
|
95
117
|
|
|
96
118
|
const conf = Object.assign(
|
|
@@ -217,8 +239,25 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
217
239
|
}
|
|
218
240
|
|
|
219
241
|
public pushLogs(logs: InputLogEvent[]): void {
|
|
220
|
-
logger.debug('pushing log events to
|
|
221
|
-
this._dataTracker.logEvents =
|
|
242
|
+
logger.debug('pushing log events to buffer');
|
|
243
|
+
this._dataTracker.logEvents = this._dataTracker.logEvents.concat(logs);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public pause() {
|
|
247
|
+
this._processing = false;
|
|
248
|
+
if (this._timer) {
|
|
249
|
+
clearInterval(this._timer);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
public resume() {
|
|
254
|
+
this._processing = true;
|
|
255
|
+
this._initiateLogPushInterval();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public clear() {
|
|
259
|
+
this._dataTracker.logEvents = [];
|
|
260
|
+
this._currentLogBatch = [];
|
|
222
261
|
}
|
|
223
262
|
|
|
224
263
|
private async _validateLogGroupExistsAndCreate(
|
|
@@ -394,6 +433,11 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
394
433
|
* We also need to ensure that the logs in the batch are sorted in chronological order.
|
|
395
434
|
* https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
|
|
396
435
|
*/
|
|
436
|
+
if (!(await this._preFlightCheck())) {
|
|
437
|
+
this.clear();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
|
|
397
441
|
const seqToken = await this._getNextSequenceToken();
|
|
398
442
|
const logBatch =
|
|
399
443
|
this._currentLogBatch.length === 0
|
|
@@ -431,6 +475,47 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
431
475
|
}
|
|
432
476
|
}
|
|
433
477
|
|
|
478
|
+
private truncateOversizedEvent(event) {
|
|
479
|
+
const { timestamp, message } = event;
|
|
480
|
+
let messageJson;
|
|
481
|
+
try {
|
|
482
|
+
messageJson = JSON.parse(message);
|
|
483
|
+
|
|
484
|
+
const truncated = JSON.stringify({
|
|
485
|
+
level: messageJson.level,
|
|
486
|
+
class: messageJson.class,
|
|
487
|
+
message: messageJson.message.substring(0, 500),
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
if (messageJson.data != null) {
|
|
491
|
+
truncated[
|
|
492
|
+
'data'
|
|
493
|
+
] = `OBJECT SIZE EXCEEDS CLOUDWATCH EVENT LIMIT. Truncated: ${JSON.stringify(
|
|
494
|
+
messageJson.data
|
|
495
|
+
).substring(0, 500)}`;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return {
|
|
499
|
+
timestamp,
|
|
500
|
+
message: truncated,
|
|
501
|
+
};
|
|
502
|
+
} catch (error) {
|
|
503
|
+
logger.warn('Could not minify oversized event', error);
|
|
504
|
+
|
|
505
|
+
const truncated = JSON.stringify({
|
|
506
|
+
level: 'UNKNOWN',
|
|
507
|
+
class: 'Unknown',
|
|
508
|
+
message:
|
|
509
|
+
'OBJECT SIZE EXCEEDS CLOUDWATCH EVENT LIMIT. Could not parse event to truncate',
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
return {
|
|
513
|
+
timestamp,
|
|
514
|
+
message: truncated,
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
434
519
|
private _getBufferedBatchOfLogs(): InputLogEvent[] {
|
|
435
520
|
/**
|
|
436
521
|
* CloudWatch has restrictions on the size of the log events that get sent up.
|
|
@@ -444,20 +529,28 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
444
529
|
let totalByteSize = 0;
|
|
445
530
|
|
|
446
531
|
while (currentEventIdx < this._dataTracker.logEvents.length) {
|
|
447
|
-
|
|
448
|
-
|
|
532
|
+
let currentEvent = this._dataTracker.logEvents[currentEventIdx];
|
|
533
|
+
|
|
534
|
+
let eventSize = currentEvent
|
|
449
535
|
? new TextEncoder().encode(currentEvent.message).length +
|
|
450
536
|
AWS_CLOUDWATCH_BASE_BUFFER_SIZE
|
|
451
537
|
: 0;
|
|
538
|
+
|
|
452
539
|
if (eventSize > AWS_CLOUDWATCH_MAX_EVENT_SIZE) {
|
|
453
540
|
const errString = `Log entry exceeds maximum size for CloudWatch logs. Log size: ${eventSize}. Truncating log message.`;
|
|
454
541
|
logger.warn(errString);
|
|
455
542
|
|
|
456
|
-
currentEvent
|
|
543
|
+
currentEvent = this.truncateOversizedEvent(currentEvent);
|
|
544
|
+
this._dataTracker.logEvents[currentEventIdx] = currentEvent;
|
|
545
|
+
|
|
546
|
+
eventSize =
|
|
547
|
+
new TextEncoder().encode(currentEvent.message).length +
|
|
548
|
+
AWS_CLOUDWATCH_BASE_BUFFER_SIZE;
|
|
457
549
|
}
|
|
458
550
|
|
|
459
551
|
if (totalByteSize + eventSize > AWS_CLOUDWATCH_MAX_BATCH_EVENT_SIZE)
|
|
460
552
|
break;
|
|
553
|
+
|
|
461
554
|
totalByteSize += eventSize;
|
|
462
555
|
currentEventIdx++;
|
|
463
556
|
}
|
|
@@ -509,8 +602,9 @@ class AWSCloudWatchProvider implements LoggingProvider {
|
|
|
509
602
|
logger.error(
|
|
510
603
|
`error when calling _safeUploadLogEvents in the timer interval - ${err}`
|
|
511
604
|
);
|
|
605
|
+
this.pause();
|
|
512
606
|
}
|
|
513
|
-
},
|
|
607
|
+
}, INTERVAL);
|
|
514
608
|
}
|
|
515
609
|
|
|
516
610
|
private _getDocUploadPermissibility(): boolean {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AmazonKinesisLoggerOptions, LoggingProvider } from '../types/types';
|
|
2
|
+
import { ConsoleLogger as Logger } from '../Logger';
|
|
3
|
+
import {
|
|
4
|
+
AMAZON_KINESIS_LOGGING_PROVIDER_NAME,
|
|
5
|
+
AMAZON_KINESIS_LOGGING_CATEGORY,
|
|
6
|
+
NO_CREDS_ERROR_STRING,
|
|
7
|
+
RETRY_ERROR_CODES,
|
|
8
|
+
} from '../Util/Constants';
|
|
9
|
+
|
|
10
|
+
const logger = new Logger('AmazonKinesisLoggingProvider');
|
|
11
|
+
|
|
12
|
+
export class AmazonKinesisLoggingProvider implements LoggingProvider {
|
|
13
|
+
static readonly PROVIDER_NAME = AMAZON_KINESIS_LOGGING_PROVIDER_NAME;
|
|
14
|
+
static readonly CATEGORY = AMAZON_KINESIS_LOGGING_CATEGORY;
|
|
15
|
+
|
|
16
|
+
private _config: AmazonKinesisLoggerOptions;
|
|
17
|
+
|
|
18
|
+
constructor(config?: AmazonKinesisLoggerOptions) {}
|
|
19
|
+
|
|
20
|
+
public getProviderName(): string {
|
|
21
|
+
return AmazonKinesisLoggingProvider.PROVIDER_NAME;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public getCategoryName(): string {
|
|
25
|
+
return AmazonKinesisLoggingProvider.CATEGORY;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public configure(
|
|
29
|
+
config?: AmazonKinesisLoggerOptions
|
|
30
|
+
): AmazonKinesisLoggerOptions {
|
|
31
|
+
if (!config) return this._config || {};
|
|
32
|
+
|
|
33
|
+
return this._config;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public pushLogs(logs: any[]): void {
|
|
37
|
+
logger.debug('pushing log events to Kinesis...');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public pause() {}
|
|
41
|
+
|
|
42
|
+
public resume() {}
|
|
43
|
+
}
|
package/src/Util/Constants.ts
CHANGED
|
@@ -12,11 +12,16 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
// Logging constants
|
|
15
|
+
// Cloudwatch
|
|
15
16
|
const AWS_CLOUDWATCH_BASE_BUFFER_SIZE = 26;
|
|
16
17
|
const AWS_CLOUDWATCH_MAX_BATCH_EVENT_SIZE = 1048576;
|
|
17
18
|
const AWS_CLOUDWATCH_MAX_EVENT_SIZE = 256000;
|
|
18
19
|
const AWS_CLOUDWATCH_CATEGORY = 'Logging';
|
|
19
20
|
const AWS_CLOUDWATCH_PROVIDER_NAME = 'AWSCloudWatch';
|
|
21
|
+
|
|
22
|
+
const AMAZON_KINESIS_LOGGING_CATEGORY = 'KinesisLogging';
|
|
23
|
+
const AMAZON_KINESIS_LOGGING_PROVIDER_NAME = 'AmazonKinesisLogging';
|
|
24
|
+
|
|
20
25
|
const NO_CREDS_ERROR_STRING = 'No credentials';
|
|
21
26
|
const RETRY_ERROR_CODES = [
|
|
22
27
|
'ResourceNotFoundException',
|
|
@@ -31,4 +36,6 @@ export {
|
|
|
31
36
|
AWS_CLOUDWATCH_PROVIDER_NAME,
|
|
32
37
|
NO_CREDS_ERROR_STRING,
|
|
33
38
|
RETRY_ERROR_CODES,
|
|
39
|
+
AMAZON_KINESIS_LOGGING_PROVIDER_NAME,
|
|
40
|
+
AMAZON_KINESIS_LOGGING_CATEGORY,
|
|
34
41
|
};
|
package/src/types/types.ts
CHANGED
|
@@ -1,62 +1,79 @@
|
|
|
1
|
-
import { InputLogEvent, LogGroup } from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
-
import { Credentials } from '@aws-sdk/types';
|
|
3
|
-
|
|
4
|
-
export interface AmplifyConfig {
|
|
5
|
-
Analytics?: object;
|
|
6
|
-
Auth?: object;
|
|
7
|
-
API?: object;
|
|
8
|
-
Logging?: object;
|
|
9
|
-
Storage?: object;
|
|
10
|
-
Cache?: object;
|
|
11
|
-
Geo?: object;
|
|
12
|
-
ssr?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ICredentials {
|
|
16
|
-
accessKeyId: string;
|
|
17
|
-
sessionToken: string;
|
|
18
|
-
secretAccessKey: string;
|
|
19
|
-
identityId: string;
|
|
20
|
-
authenticated: boolean;
|
|
21
|
-
// Long term creds do not provide an expiration date
|
|
22
|
-
expiration?: Date;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @private
|
|
27
|
-
* Internal use of Amplify only
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
export type DelayFunction = (
|
|
31
|
-
attempt: number,
|
|
32
|
-
args?: any[],
|
|
33
|
-
error?: Error
|
|
34
|
-
) => number | false;
|
|
35
|
-
|
|
36
|
-
export interface LoggingProvider {
|
|
37
|
-
// return the name of you provider
|
|
38
|
-
getProviderName(): string;
|
|
39
|
-
|
|
40
|
-
// return the name of you category
|
|
41
|
-
getCategoryName(): string;
|
|
42
|
-
|
|
43
|
-
// configure the plugin
|
|
44
|
-
configure(config?: object): object;
|
|
45
|
-
|
|
46
|
-
// take logs and push to provider
|
|
47
|
-
pushLogs(logs: InputLogEvent[]): void;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
import { InputLogEvent, LogGroup } from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
+
import { Credentials } from '@aws-sdk/types';
|
|
3
|
+
|
|
4
|
+
export interface AmplifyConfig {
|
|
5
|
+
Analytics?: object;
|
|
6
|
+
Auth?: object;
|
|
7
|
+
API?: object;
|
|
8
|
+
Logging?: object;
|
|
9
|
+
Storage?: object;
|
|
10
|
+
Cache?: object;
|
|
11
|
+
Geo?: object;
|
|
12
|
+
ssr?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ICredentials {
|
|
16
|
+
accessKeyId: string;
|
|
17
|
+
sessionToken: string;
|
|
18
|
+
secretAccessKey: string;
|
|
19
|
+
identityId: string;
|
|
20
|
+
authenticated: boolean;
|
|
21
|
+
// Long term creds do not provide an expiration date
|
|
22
|
+
expiration?: Date;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
* Internal use of Amplify only
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export type DelayFunction = (
|
|
31
|
+
attempt: number,
|
|
32
|
+
args?: any[],
|
|
33
|
+
error?: Error
|
|
34
|
+
) => number | false;
|
|
35
|
+
|
|
36
|
+
export interface LoggingProvider {
|
|
37
|
+
// return the name of you provider
|
|
38
|
+
getProviderName(): string;
|
|
39
|
+
|
|
40
|
+
// return the name of you category
|
|
41
|
+
getCategoryName(): string;
|
|
42
|
+
|
|
43
|
+
// configure the plugin
|
|
44
|
+
configure(config?: object): object;
|
|
45
|
+
|
|
46
|
+
// take logs and push to provider
|
|
47
|
+
pushLogs(logs: InputLogEvent[]): void;
|
|
48
|
+
|
|
49
|
+
// pause sending logs
|
|
50
|
+
pause(): void;
|
|
51
|
+
resume(): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface AWSCloudWatchProviderOptions {
|
|
55
|
+
logGroupName?: string;
|
|
56
|
+
logStreamName?: string;
|
|
57
|
+
region?: string;
|
|
58
|
+
credentials?: Credentials;
|
|
59
|
+
endpoint?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface AmplifyConfigure {
|
|
63
|
+
Logging: {
|
|
64
|
+
logGroupName: string;
|
|
65
|
+
logStreamName: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface CloudWatchDataTracker {
|
|
70
|
+
eventUploadInProgress: boolean;
|
|
71
|
+
logEvents: InputLogEvent[];
|
|
72
|
+
verifiedLogGroup?: LogGroup;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface AmazonKinesisLoggerOptions {
|
|
76
|
+
region?: string;
|
|
77
|
+
credentials?: Credentials;
|
|
78
|
+
endpoint?: string;
|
|
79
|
+
}
|