@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.
Files changed (46) hide show
  1. package/dist/aws-amplify-core.js +571 -391
  2. package/dist/aws-amplify-core.js.map +1 -1
  3. package/dist/aws-amplify-core.min.js +6 -6
  4. package/dist/aws-amplify-core.min.js.map +1 -1
  5. package/lib/Hub.js +1 -0
  6. package/lib/Hub.js.map +1 -1
  7. package/lib/Logger/ConsoleLogger.d.ts +6 -0
  8. package/lib/Logger/ConsoleLogger.js +118 -43
  9. package/lib/Logger/ConsoleLogger.js.map +1 -1
  10. package/lib/Platform/version.d.ts +1 -1
  11. package/lib/Platform/version.js +1 -1
  12. package/lib/Providers/AWSCloudWatchProvider.d.ts +11 -3
  13. package/lib/Providers/AWSCloudWatchProvider.js +97 -37
  14. package/lib/Providers/AWSCloudWatchProvider.js.map +1 -1
  15. package/lib/Providers/AmazonKinesisLoggingProvider.d.ts +13 -0
  16. package/lib/Providers/AmazonKinesisLoggingProvider.js +30 -0
  17. package/lib/Providers/AmazonKinesisLoggingProvider.js.map +1 -0
  18. package/lib/Util/Constants.d.ts +3 -1
  19. package/lib/Util/Constants.js +5 -0
  20. package/lib/Util/Constants.js.map +1 -1
  21. package/lib/types/types.d.ts +13 -0
  22. package/lib-esm/Hub.js +1 -0
  23. package/lib-esm/Hub.js.map +1 -1
  24. package/lib-esm/Logger/ConsoleLogger.d.ts +6 -0
  25. package/lib-esm/Logger/ConsoleLogger.js +118 -43
  26. package/lib-esm/Logger/ConsoleLogger.js.map +1 -1
  27. package/lib-esm/Platform/version.d.ts +1 -1
  28. package/lib-esm/Platform/version.js +1 -1
  29. package/lib-esm/Providers/AWSCloudWatchProvider.d.ts +11 -3
  30. package/lib-esm/Providers/AWSCloudWatchProvider.js +97 -37
  31. package/lib-esm/Providers/AWSCloudWatchProvider.js.map +1 -1
  32. package/lib-esm/Providers/AmazonKinesisLoggingProvider.d.ts +13 -0
  33. package/lib-esm/Providers/AmazonKinesisLoggingProvider.js +28 -0
  34. package/lib-esm/Providers/AmazonKinesisLoggingProvider.js.map +1 -0
  35. package/lib-esm/Util/Constants.d.ts +3 -1
  36. package/lib-esm/Util/Constants.js +4 -1
  37. package/lib-esm/Util/Constants.js.map +1 -1
  38. package/lib-esm/types/types.d.ts +13 -0
  39. package/package.json +4 -3
  40. package/src/Hub.ts +1 -0
  41. package/src/Logger/ConsoleLogger.ts +119 -34
  42. package/src/Platform/version.ts +1 -1
  43. package/src/Providers/AWSCloudWatchProvider.ts +112 -18
  44. package/src/Providers/AmazonKinesisLoggingProvider.ts +43 -0
  45. package/src/Util/Constants.ts +7 -0
  46. 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
- const logger = new Logger('AWSCloudWatch');
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
- constructor(config?: AWSCloudWatchProviderOptions) {
70
- this.configure(config);
71
- this._dataTracker = {
72
- eventUploadInProgress: false,
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 configure(
92
- config?: AWSCloudWatchProviderOptions
93
- ): AWSCloudWatchProviderOptions {
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 Cloudwatch...');
221
- this._dataTracker.logEvents = [...this._dataTracker.logEvents, ...logs];
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
- const currentEvent = this._dataTracker.logEvents[currentEventIdx];
448
- const eventSize = currentEvent
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.message = currentEvent.message.substring(0, eventSize);
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
- }, 2000);
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
+ }
@@ -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
  };
@@ -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
- export interface AWSCloudWatchProviderOptions {
51
- logGroupName?: string;
52
- logStreamName?: string;
53
- region?: string;
54
- credentials?: Credentials;
55
- endpoint?: string;
56
- }
57
-
58
- export interface CloudWatchDataTracker {
59
- eventUploadInProgress: boolean;
60
- logEvents: InputLogEvent[];
61
- verifiedLogGroup?: LogGroup;
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
+ }