@aws-amplify/core 4.4.1 → 4.4.2-api-logging.2
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 +1104 -202
- package/dist/aws-amplify-core.js.map +1 -1
- package/dist/aws-amplify-core.min.js +7 -7
- package/dist/aws-amplify-core.min.js.map +1 -1
- package/lib/Logger/ConsoleLogger.d.ts +12 -1
- package/lib/Logger/ConsoleLogger.js +61 -6
- 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/APIProvider/APILoggingProvider.d.ts +28 -0
- package/lib/Providers/APIProvider/APILoggingProvider.js +311 -0
- package/lib/Providers/APIProvider/APILoggingProvider.js.map +1 -0
- package/lib/Providers/APIProvider/CloudWatchEventFormatter.d.ts +5 -0
- package/lib/Providers/APIProvider/CloudWatchEventFormatter.js +78 -0
- package/lib/Providers/APIProvider/CloudWatchEventFormatter.js.map +1 -0
- package/lib/Providers/APIProvider/Fetch.d.ts +10 -0
- package/lib/Providers/APIProvider/Fetch.js +13 -0
- package/lib/Providers/APIProvider/Fetch.js.map +1 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.d.ts +3 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.js +5 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.js.map +1 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.native.d.ts +3 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.native.js +9 -0
- package/lib/Providers/APIProvider/LoggerReachability/index.native.js.map +1 -0
- package/lib/Providers/APIProvider/index.d.ts +1 -0
- package/lib/Providers/APIProvider/index.js +5 -0
- package/lib/Providers/APIProvider/index.js.map +1 -0
- package/lib/Providers/APIProvider/loggerConnectivity.d.ts +14 -0
- package/lib/Providers/APIProvider/loggerConnectivity.js +55 -0
- package/lib/Providers/APIProvider/loggerConnectivity.js.map +1 -0
- package/lib/Providers/index.d.ts +1 -0
- package/lib/Providers/index.js +2 -0
- package/lib/Providers/index.js.map +1 -1
- package/lib/Util/Constants.d.ts +3 -1
- package/lib/Util/Constants.js +4 -0
- package/lib/Util/Constants.js.map +1 -1
- package/lib/Util/Reachability.js +7 -5
- package/lib/Util/Reachability.js.map +1 -1
- package/lib/Util/Retry.js +2 -2
- package/lib/Util/Retry.js.map +1 -1
- package/lib/Util/StringUtils.d.ts +1 -0
- package/lib/Util/StringUtils.js +11 -6
- package/lib/Util/StringUtils.js.map +1 -1
- package/lib/types/index.js +4 -0
- package/lib/types/index.js.map +1 -1
- package/lib/types/types.d.ts +26 -1
- package/lib/types/types.js +5 -0
- package/lib/types/types.js.map +1 -1
- package/lib-esm/Logger/ConsoleLogger.d.ts +12 -1
- package/lib-esm/Logger/ConsoleLogger.js +59 -4
- 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/APIProvider/APILoggingProvider.d.ts +28 -0
- package/lib-esm/Providers/APIProvider/APILoggingProvider.js +306 -0
- package/lib-esm/Providers/APIProvider/APILoggingProvider.js.map +1 -0
- package/lib-esm/Providers/APIProvider/CloudWatchEventFormatter.d.ts +5 -0
- package/lib-esm/Providers/APIProvider/CloudWatchEventFormatter.js +76 -0
- package/lib-esm/Providers/APIProvider/CloudWatchEventFormatter.js.map +1 -0
- package/lib-esm/Providers/APIProvider/Fetch.d.ts +10 -0
- package/lib-esm/Providers/APIProvider/Fetch.js +11 -0
- package/lib-esm/Providers/APIProvider/Fetch.js.map +1 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.d.ts +3 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.js +3 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.js.map +1 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.native.d.ts +3 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.native.js +4 -0
- package/lib-esm/Providers/APIProvider/LoggerReachability/index.native.js.map +1 -0
- package/lib-esm/Providers/APIProvider/index.d.ts +1 -0
- package/lib-esm/Providers/APIProvider/index.js +2 -0
- package/lib-esm/Providers/APIProvider/index.js.map +1 -0
- package/lib-esm/Providers/APIProvider/loggerConnectivity.d.ts +14 -0
- package/lib-esm/Providers/APIProvider/loggerConnectivity.js +50 -0
- package/lib-esm/Providers/APIProvider/loggerConnectivity.js.map +1 -0
- package/lib-esm/Providers/index.d.ts +1 -0
- package/lib-esm/Providers/index.js +1 -0
- package/lib-esm/Providers/index.js.map +1 -1
- package/lib-esm/Util/Constants.d.ts +3 -1
- package/lib-esm/Util/Constants.js +3 -1
- package/lib-esm/Util/Constants.js.map +1 -1
- package/lib-esm/Util/Reachability.js +5 -3
- package/lib-esm/Util/Reachability.js.map +1 -1
- package/lib-esm/Util/Retry.js +2 -2
- package/lib-esm/Util/Retry.js.map +1 -1
- package/lib-esm/Util/StringUtils.d.ts +1 -0
- package/lib-esm/Util/StringUtils.js +11 -6
- package/lib-esm/Util/StringUtils.js.map +1 -1
- package/lib-esm/types/index.js +1 -0
- package/lib-esm/types/index.js.map +1 -1
- package/lib-esm/types/types.d.ts +26 -1
- package/lib-esm/types/types.js +5 -0
- package/lib-esm/types/types.js.map +1 -1
- package/package.json +2 -2
- package/src/Logger/ConsoleLogger.ts +45 -2
- package/src/Platform/version.ts +1 -1
- package/src/Providers/APIProvider/APILoggingProvider.ts +286 -0
- package/src/Providers/APIProvider/CloudWatchEventFormatter.ts +97 -0
- package/src/Providers/APIProvider/Fetch.ts +10 -0
- package/src/Providers/APIProvider/LoggerReachability/index.native.ts +4 -0
- package/src/Providers/APIProvider/LoggerReachability/index.ts +2 -0
- package/src/Providers/APIProvider/index.ts +1 -0
- package/src/Providers/APIProvider/loggerConnectivity.ts +49 -0
- package/src/Providers/index.ts +1 -0
- package/src/Util/Constants.ts +4 -0
- package/src/Util/Reachability.ts +9 -7
- package/src/Util/Retry.ts +2 -2
- package/src/Util/StringUtils.ts +15 -6
- package/src/types/types.ts +88 -62
package/lib-esm/Util/Retry.js
CHANGED
|
@@ -68,7 +68,7 @@ var __spread = (this && this.__spread) || function () {
|
|
|
68
68
|
return ar;
|
|
69
69
|
};
|
|
70
70
|
import { ConsoleLogger as Logger } from '../Logger/ConsoleLogger';
|
|
71
|
-
var logger = new Logger('
|
|
71
|
+
var logger = new Logger('Retry');
|
|
72
72
|
var NonRetryableError = /** @class */ (function (_super) {
|
|
73
73
|
__extends(NonRetryableError, _super);
|
|
74
74
|
function NonRetryableError(message) {
|
|
@@ -97,7 +97,7 @@ export function retry(functionToRetry, args, delayFn, attempt) {
|
|
|
97
97
|
if (typeof functionToRetry !== 'function') {
|
|
98
98
|
throw Error('functionToRetry must be a function');
|
|
99
99
|
}
|
|
100
|
-
logger.debug(functionToRetry.name + " attempt #" + attempt + " with
|
|
100
|
+
logger.debug(functionToRetry.name + " attempt #" + attempt + " with these vars: " + JSON.stringify(args));
|
|
101
101
|
_a.label = 1;
|
|
102
102
|
case 1:
|
|
103
103
|
_a.trys.push([1, 3, , 8]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Retry.js","sourceRoot":"","sources":["../../src/Util/Retry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,OAAO,EAAE,aAAa,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAClE,IAAM,MAAM,GAAG,IAAI,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"Retry.js","sourceRoot":"","sources":["../../src/Util/Retry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,OAAO,EAAE,aAAa,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAClE,IAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AAEnC;IAAuC,qCAAK;IAE3C,2BAAY,OAAe;QAA3B,YACC,kBAAM,OAAO,CAAC,SACd;QAHe,kBAAY,GAAG,IAAI,CAAC;;IAGpC,CAAC;IACF,wBAAC;AAAD,CAAC,AALD,CAAuC,KAAK,GAK3C;;AAED,IAAM,mBAAmB,GAAG,UAAC,GAAQ;IACpC,IAAM,GAAG,GAA4B,cAAc,CAAC;IACpD,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAgB,KAAK,CAC1B,eAAyB,EACzB,IAAW,EACX,OAAsB,EACtB,OAAmB;IAAnB,wBAAA,EAAA,WAAmB;;;;;;oBAEnB,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE;wBAC1C,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;qBAClD;oBACD,MAAM,CAAC,KAAK,CAEV,eAAe,CAAC,IAAI,kBACR,OAAO,0BAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAG,CAC/D,CAAC;;;;oBAGM,qBAAM,eAAe,wBAAI,IAAI,IAAC;wBAArC,sBAAO,SAA8B,EAAC;;;oBAEtC,MAAM,CAAC,KAAK,CAAC,cAAY,eAAe,CAAC,IAAM,EAAE,KAAG,CAAC,CAAC;oBAEtD,IAAI,mBAAmB,CAAC,KAAG,CAAC,EAAE;wBAC7B,MAAM,CAAC,KAAK,CAAI,eAAe,CAAC,IAAI,yBAAsB,EAAE,KAAG,CAAC,CAAC;wBACjE,MAAM,KAAG,CAAC;qBACV;oBAEK,YAAU,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAG,CAAC,CAAC;oBAC5C,MAAM,CAAC,KAAK,CAAI,eAAe,CAAC,IAAI,qBAAgB,SAAO,QAAK,CAAC,CAAC;yBAE9D,CAAA,SAAO,KAAK,KAAK,CAAA,EAAjB,wBAAiB;oBACpB,qBAAM,IAAI,OAAO,CAAC,UAAA,GAAG,IAAI,OAAA,UAAU,CAAC,GAAG,EAAE,SAAO,CAAC,EAAxB,CAAwB,CAAC,EAAA;;oBAAlD,SAAkD,CAAC;oBAC5C,qBAAM,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC,EAAA;wBAA/D,sBAAO,SAAwD,EAAC;wBAEhE,MAAM,KAAG,CAAC;;;;;;CAGZ;AAED,IAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,SAAS,eAAe,CAAC,UAAkB;IAC1C,IAAM,YAAY,GAAG,GAAG,CAAC;IACzB,IAAM,aAAa,GAAG,GAAG,CAAC;IAE1B,OAAO,UAAA,OAAO;QACb,IAAM,KAAK,GAAG,SAAA,CAAC,EAAI,OAAO,CAAA,GAAG,YAAY,GAAG,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1E,OAAO,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3C,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACvC,eAAyB,EACzB,IAAW,EACX,UAAiC;IAAjC,2BAAA,EAAA,yBAAiC;IAC7B,OAAA,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;AAAzD,CAAyD,CAAC"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
+
import { browserOrNode } from '../../';
|
|
1
2
|
export function urlSafeEncode(str) {
|
|
2
3
|
return str
|
|
3
4
|
.split('')
|
|
4
|
-
.map(function (char) {
|
|
5
|
-
return char
|
|
6
|
-
.charCodeAt(0)
|
|
7
|
-
.toString(16)
|
|
8
|
-
.padStart(2, '0');
|
|
9
|
-
})
|
|
5
|
+
.map(function (char) { return char.charCodeAt(0).toString(16).padStart(2, '0'); })
|
|
10
6
|
.join('');
|
|
11
7
|
}
|
|
12
8
|
export function urlSafeDecode(hex) {
|
|
@@ -15,4 +11,13 @@ export function urlSafeDecode(hex) {
|
|
|
15
11
|
.map(function (char) { return String.fromCharCode(parseInt(char, 16)); })
|
|
16
12
|
.join('');
|
|
17
13
|
}
|
|
14
|
+
export var getStringByteSize = function (str) {
|
|
15
|
+
if (browserOrNode().isBrowser || Blob !== undefined) {
|
|
16
|
+
return new Blob([str]).size;
|
|
17
|
+
}
|
|
18
|
+
if (Buffer !== undefined) {
|
|
19
|
+
return Buffer.byteLength(str, 'utf8');
|
|
20
|
+
}
|
|
21
|
+
throw new Error('Cannot compute string length. Blob and Buffer are undefined');
|
|
22
|
+
};
|
|
18
23
|
//# sourceMappingURL=StringUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StringUtils.js","sourceRoot":"","sources":["../../src/Util/StringUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,OAAO,GAAG;SACR,KAAK,CAAC,EAAE,CAAC;SACT,GAAG,CAAC,UAAA,IAAI
|
|
1
|
+
{"version":3,"file":"StringUtils.js","sourceRoot":"","sources":["../../src/Util/StringUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,OAAO,GAAG;SACR,KAAK,CAAC,EAAE,CAAC;SACT,GAAG,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAhD,CAAgD,CAAC;SAC7D,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,OAAO,GAAG;SACR,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,UAAA,IAAI,IAAI,OAAA,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAvC,CAAuC,CAAC;SACpD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AACD,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,GAAW;IAC5C,IAAI,aAAa,EAAE,CAAC,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE;QACpD,OAAO,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;KAC5B;IAED,IAAI,MAAM,KAAK,SAAS,EAAE;QACzB,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;KACtC;IAED,MAAM,IAAI,KAAK,CACd,6DAA6D,CAC7D,CAAC;AACH,CAAC,CAAC"}
|
package/lib-esm/types/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
|
package/lib-esm/types/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { InputLogEvent, LogGroup } from '@aws-sdk/client-cloudwatch-logs';
|
|
2
2
|
import { Credentials } from '@aws-sdk/types';
|
|
3
|
+
import { LOG_TYPE } from '../Logger/ConsoleLogger';
|
|
3
4
|
export interface AmplifyConfig {
|
|
4
5
|
Analytics?: object;
|
|
5
6
|
Auth?: object;
|
|
@@ -27,7 +28,8 @@ export interface LoggingProvider {
|
|
|
27
28
|
getProviderName(): string;
|
|
28
29
|
getCategoryName(): string;
|
|
29
30
|
configure(config?: object): object;
|
|
30
|
-
pushLogs(logs: InputLogEvent[]): void;
|
|
31
|
+
pushLogs?(logs: InputLogEvent[]): void;
|
|
32
|
+
pushLog?(log: GenericLogEvent): void;
|
|
31
33
|
}
|
|
32
34
|
export interface AWSCloudWatchProviderOptions {
|
|
33
35
|
logGroupName?: string;
|
|
@@ -41,3 +43,26 @@ export interface CloudWatchDataTracker {
|
|
|
41
43
|
logEvents: InputLogEvent[];
|
|
42
44
|
verifiedLogGroup?: LogGroup;
|
|
43
45
|
}
|
|
46
|
+
export interface APILoggingProviderOptions {
|
|
47
|
+
endpoint: string;
|
|
48
|
+
apiKey?: string;
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
level?: LOG_TYPE;
|
|
51
|
+
excludeClassList?: string[];
|
|
52
|
+
metadata?: {
|
|
53
|
+
[key: string]: any;
|
|
54
|
+
};
|
|
55
|
+
eventFormat?: EVENT_FORMAT;
|
|
56
|
+
bufferInterval?: number;
|
|
57
|
+
}
|
|
58
|
+
export declare enum EVENT_FORMAT {
|
|
59
|
+
GENERIC = "GENERIC",
|
|
60
|
+
CLOUDWATCH = "CLOUDWATCH"
|
|
61
|
+
}
|
|
62
|
+
export interface GenericLogEvent {
|
|
63
|
+
level: string;
|
|
64
|
+
source: string;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
message?: string;
|
|
67
|
+
data?: object;
|
|
68
|
+
}
|
package/lib-esm/types/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AA6EA,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACvB,mCAAmB,CAAA;IACnB,yCAAyB,CAAA;AAC1B,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-amplify/core",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.2-api-logging.2+ad8e979fc",
|
|
4
4
|
"description": "Core category of aws-amplify",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib-esm/index.js",
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"lib-esm"
|
|
109
109
|
]
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "ad8e979fc00dfdab256c46f97d9973e8facbcfaa"
|
|
112
112
|
}
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { InputLogEvent } from '@aws-sdk/client-cloudwatch-logs';
|
|
15
|
-
import { LoggingProvider } from '../types';
|
|
15
|
+
import { GenericLogEvent, LoggingProvider } from '../types';
|
|
16
16
|
import { AWS_CLOUDWATCH_CATEGORY } from '../Util/Constants';
|
|
17
17
|
import { Logger } from './logger-interface';
|
|
18
18
|
|
|
19
|
-
const LOG_LEVELS = {
|
|
19
|
+
export const LOG_LEVELS = {
|
|
20
20
|
VERBOSE: 1,
|
|
21
21
|
DEBUG: 2,
|
|
22
22
|
INFO: 3,
|
|
@@ -42,6 +42,11 @@ export class ConsoleLogger implements Logger {
|
|
|
42
42
|
private _pluggables: LoggingProvider[];
|
|
43
43
|
private _config: object;
|
|
44
44
|
|
|
45
|
+
private static pluggables: LoggingProvider[] = [];
|
|
46
|
+
public static addPluggable(pluggable: LoggingProvider) {
|
|
47
|
+
ConsoleLogger.pluggables.push(pluggable);
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
/**
|
|
46
51
|
* @constructor
|
|
47
52
|
* @param {string} name - Name of the logger
|
|
@@ -77,6 +82,42 @@ export class ConsoleLogger implements Logger {
|
|
|
77
82
|
return this._config;
|
|
78
83
|
}
|
|
79
84
|
|
|
85
|
+
_logGlobal(type: LOG_TYPE | string, ...msg) {
|
|
86
|
+
for (const pluggable of ConsoleLogger.pluggables) {
|
|
87
|
+
const event = this._generateGenericEvent(type, msg);
|
|
88
|
+
pluggable.pushLog(event);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_generateGenericEvent(type: LOG_TYPE | string, msg: any[]): GenericLogEvent {
|
|
93
|
+
let strMessage = '';
|
|
94
|
+
let data;
|
|
95
|
+
|
|
96
|
+
if (msg.length === 1 && typeof msg[0] === 'string') {
|
|
97
|
+
strMessage = msg[0];
|
|
98
|
+
} else if (msg.length === 1) {
|
|
99
|
+
data = msg[0];
|
|
100
|
+
} else if (typeof msg[0] === 'string') {
|
|
101
|
+
let obj = msg.slice(1);
|
|
102
|
+
if (obj.length === 1) {
|
|
103
|
+
obj = obj[0];
|
|
104
|
+
}
|
|
105
|
+
strMessage = msg[0];
|
|
106
|
+
data = obj;
|
|
107
|
+
} else {
|
|
108
|
+
data = msg;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const event = {
|
|
112
|
+
data,
|
|
113
|
+
level: type,
|
|
114
|
+
message: strMessage,
|
|
115
|
+
source: this.name,
|
|
116
|
+
timestamp: Date.now(),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return event;
|
|
120
|
+
}
|
|
80
121
|
/**
|
|
81
122
|
* Write log
|
|
82
123
|
* @method
|
|
@@ -85,6 +126,8 @@ export class ConsoleLogger implements Logger {
|
|
|
85
126
|
* @param {string|object} msg - Logging message or object
|
|
86
127
|
*/
|
|
87
128
|
_log(type: LOG_TYPE | string, ...msg) {
|
|
129
|
+
this._logGlobal(type, ...msg);
|
|
130
|
+
|
|
88
131
|
let logger_level_name = this.level;
|
|
89
132
|
if (ConsoleLogger.LOG_LEVEL) {
|
|
90
133
|
logger_level_name = ConsoleLogger.LOG_LEVEL;
|
package/src/Platform/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// generated by genversion
|
|
2
|
-
export const version = '4.4.
|
|
2
|
+
export const version = '4.4.1';
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { InputLogEvent } from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
+
import { ConsoleLogger as Logger, LOG_LEVELS, LOG_TYPE } from '../../Logger';
|
|
3
|
+
import LoggerConnectivity from './loggerConnectivity';
|
|
4
|
+
import {
|
|
5
|
+
EVENT_FORMAT,
|
|
6
|
+
LoggingProvider,
|
|
7
|
+
GenericLogEvent,
|
|
8
|
+
APILoggingProviderOptions,
|
|
9
|
+
} from '../../types/types';
|
|
10
|
+
import { jitteredExponentialRetry, NonRetryableError } from '../../../';
|
|
11
|
+
import {
|
|
12
|
+
cloudWatchEventFromGeneric,
|
|
13
|
+
cloudWatchLogEventBatch,
|
|
14
|
+
} from './CloudWatchEventFormatter';
|
|
15
|
+
import { postOptions } from './Fetch';
|
|
16
|
+
import {
|
|
17
|
+
API_LOGGING_PROVIDER_NAME,
|
|
18
|
+
API_LOGGING_PROVIDER_CATEGORY,
|
|
19
|
+
} from '../../Util/Constants';
|
|
20
|
+
import { getStringByteSize } from '../../Util/StringUtils';
|
|
21
|
+
|
|
22
|
+
const logger = new Logger('APILoggingProvider');
|
|
23
|
+
const HTTPS = 'https';
|
|
24
|
+
const LOCALHOST = 'http://localhost';
|
|
25
|
+
const DEFAULT_INTERVAL = 3000;
|
|
26
|
+
|
|
27
|
+
// Exclude these to avoid infinite loop
|
|
28
|
+
const DEFAULT_CLASS_EXCLUDE_LIST = [
|
|
29
|
+
'APILoggingProvider',
|
|
30
|
+
'AWSCloudWatch',
|
|
31
|
+
'Retry', // causes a loop because we're using jitteredExponentialRetry below
|
|
32
|
+
];
|
|
33
|
+
const LAMBDA_PAYLOAD_LIMIT = 6 * 1024 * 1024; // 6MB
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
Todo:
|
|
37
|
+
* Refactor this into a FSM - managing state will become complex when remote config functionality gets added in P1
|
|
38
|
+
*/
|
|
39
|
+
class APILoggingProvider implements LoggingProvider {
|
|
40
|
+
static readonly PROVIDER_NAME = API_LOGGING_PROVIDER_NAME;
|
|
41
|
+
static readonly CATEGORY = API_LOGGING_PROVIDER_CATEGORY;
|
|
42
|
+
|
|
43
|
+
private config: APILoggingProviderOptions;
|
|
44
|
+
private connectivity: LoggerConnectivity;
|
|
45
|
+
private online: boolean = false;
|
|
46
|
+
private bufferInterval: ReturnType<typeof setInterval>;
|
|
47
|
+
private eventBuffer: GenericLogEvent[] | InputLogEvent[] = [];
|
|
48
|
+
|
|
49
|
+
constructor(config?: APILoggingProviderOptions) {
|
|
50
|
+
this.configure(config);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public getProviderName(): string {
|
|
54
|
+
return APILoggingProvider.PROVIDER_NAME;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public getCategoryName(): string {
|
|
58
|
+
return APILoggingProvider.CATEGORY;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public configure(
|
|
62
|
+
config: APILoggingProviderOptions
|
|
63
|
+
): object | APILoggingProviderOptions {
|
|
64
|
+
try {
|
|
65
|
+
this.validateConfig(config);
|
|
66
|
+
this.config = this.normalizeConfig(config);
|
|
67
|
+
|
|
68
|
+
if (this.config.enabled === true) {
|
|
69
|
+
this.initialize();
|
|
70
|
+
} else {
|
|
71
|
+
this.disable();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return this.config;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
logger.error('Unable to start: ', error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public pushLog(event: GenericLogEvent): void {
|
|
81
|
+
if (this.config?.enabled === false) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!this.verifyEvent(event)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
switch (this.config.eventFormat) {
|
|
90
|
+
case EVENT_FORMAT.CLOUDWATCH:
|
|
91
|
+
const cloudWatchEvent = cloudWatchEventFromGeneric(event);
|
|
92
|
+
(this.eventBuffer as InputLogEvent[]).push(cloudWatchEvent);
|
|
93
|
+
break;
|
|
94
|
+
case EVENT_FORMAT.GENERIC:
|
|
95
|
+
default:
|
|
96
|
+
(this.eventBuffer as GenericLogEvent[]).push(event);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private validateConfig(config: APILoggingProviderOptions): void {
|
|
102
|
+
if (typeof config?.endpoint !== 'string') {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Invalid configuration. \`config.endpoint\` must be a string. Received: ${typeof config?.endpoint}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const protocolStr = config.endpoint.substring(0, 5).toLowerCase();
|
|
109
|
+
const isUsingLocalhost =
|
|
110
|
+
config.endpoint.substring(0, LOCALHOST.length).toLowerCase() ===
|
|
111
|
+
LOCALHOST;
|
|
112
|
+
|
|
113
|
+
if (protocolStr !== HTTPS && !isUsingLocalhost) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Invalid configuration. Only HTTPS endpoints are supported. Received: ${protocolStr}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private normalizeConfig(
|
|
121
|
+
config: APILoggingProviderOptions
|
|
122
|
+
): APILoggingProviderOptions {
|
|
123
|
+
const normalizedConfig = {
|
|
124
|
+
endpoint: config.endpoint,
|
|
125
|
+
apiKey: config.apiKey,
|
|
126
|
+
metadata: config.metadata,
|
|
127
|
+
enabled: config.enabled ?? true,
|
|
128
|
+
level: config.level ?? LOG_TYPE.WARN,
|
|
129
|
+
eventFormat: config.eventFormat ?? EVENT_FORMAT.CLOUDWATCH,
|
|
130
|
+
bufferInterval: config.bufferInterval ?? DEFAULT_INTERVAL,
|
|
131
|
+
excludeClassList:
|
|
132
|
+
config.excludeClassList instanceof Array
|
|
133
|
+
? [...DEFAULT_CLASS_EXCLUDE_LIST, ...config.excludeClassList]
|
|
134
|
+
: DEFAULT_CLASS_EXCLUDE_LIST,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
return normalizedConfig;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private initialize() {
|
|
141
|
+
this.subscribeConnectivity();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private disable() {
|
|
145
|
+
this.clearInterval();
|
|
146
|
+
this.unsubscribeConnectivity();
|
|
147
|
+
this.eventBuffer = [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private subscribeConnectivity() {
|
|
151
|
+
if (this.connectivity) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.connectivity = new LoggerConnectivity();
|
|
156
|
+
this.connectivity.status().subscribe(({ online }) => {
|
|
157
|
+
if (online && !this.online) {
|
|
158
|
+
this.startInterval();
|
|
159
|
+
} else {
|
|
160
|
+
this.clearInterval();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.online = online;
|
|
164
|
+
logger.debug('Connectivity status: ', online);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private unsubscribeConnectivity() {
|
|
169
|
+
if (this.connectivity) {
|
|
170
|
+
this.connectivity.unsubscribe();
|
|
171
|
+
this.connectivity = undefined;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private startInterval() {
|
|
176
|
+
if (this.bufferInterval) {
|
|
177
|
+
this.clearInterval();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.bufferInterval = setInterval(async () => {
|
|
181
|
+
try {
|
|
182
|
+
await this.uploadEvents();
|
|
183
|
+
} catch (error) {
|
|
184
|
+
logger.error(`Could not upload log events`, error);
|
|
185
|
+
}
|
|
186
|
+
}, this.config.bufferInterval);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private clearInterval() {
|
|
190
|
+
clearInterval(this.bufferInterval);
|
|
191
|
+
this.bufferInterval = undefined;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
Filter out events that don't adhere to config settings
|
|
196
|
+
*/
|
|
197
|
+
private verifyEvent(event: GenericLogEvent): boolean {
|
|
198
|
+
const { level, source } = event;
|
|
199
|
+
|
|
200
|
+
const configLevelValue = LOG_LEVELS[this.config.level];
|
|
201
|
+
const eventLevelValue = LOG_LEVELS[level];
|
|
202
|
+
|
|
203
|
+
if (eventLevelValue < configLevelValue) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (this.config.excludeClassList.includes(source)) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private async uploadEvents(): Promise<void> {
|
|
215
|
+
const eventBatch = this.generateEventBatch(this.eventBuffer);
|
|
216
|
+
|
|
217
|
+
if (eventBatch.length < 1) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const body = {
|
|
222
|
+
logEvents: eventBatch,
|
|
223
|
+
metadata: this.config.metadata,
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const options = postOptions(body);
|
|
227
|
+
|
|
228
|
+
await jitteredExponentialRetry(
|
|
229
|
+
async (endpoint, options) => {
|
|
230
|
+
try {
|
|
231
|
+
const res = await fetch(endpoint, options);
|
|
232
|
+
if (!res.ok)
|
|
233
|
+
throw new Error(
|
|
234
|
+
`Request Failed. Status: ${res.status} - ${res.statusText}`
|
|
235
|
+
);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// fetch will only fail in the event of a network error. Don't retry
|
|
238
|
+
if (error.message === 'Failed to fetch') {
|
|
239
|
+
throw new NonRetryableError(error.message);
|
|
240
|
+
}
|
|
241
|
+
// all other errors are logged and retried
|
|
242
|
+
logger.warn(error);
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
[this.config.endpoint, options]
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// remove events from buffer after the request succeeds
|
|
250
|
+
this.eventBuffer.splice(0, eventBatch.length);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private generateEventBatch(
|
|
254
|
+
buffer: GenericLogEvent[] | InputLogEvent[]
|
|
255
|
+
): GenericLogEvent[] | InputLogEvent[] {
|
|
256
|
+
switch (this.config.eventFormat) {
|
|
257
|
+
case EVENT_FORMAT.CLOUDWATCH:
|
|
258
|
+
return cloudWatchLogEventBatch(buffer as InputLogEvent[]);
|
|
259
|
+
|
|
260
|
+
case EVENT_FORMAT.GENERIC:
|
|
261
|
+
default:
|
|
262
|
+
return this.genericLogEventBatch(buffer as GenericLogEvent[]);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private genericLogEventBatch(buffer: GenericLogEvent[]): GenericLogEvent[] {
|
|
267
|
+
let totalByteSize = 0;
|
|
268
|
+
let currentEventIdx = 0;
|
|
269
|
+
|
|
270
|
+
while (currentEventIdx < buffer.length) {
|
|
271
|
+
const currentEvent = buffer[currentEventIdx];
|
|
272
|
+
const eventSize = getStringByteSize(JSON.stringify(currentEvent));
|
|
273
|
+
|
|
274
|
+
if (totalByteSize + eventSize > LAMBDA_PAYLOAD_LIMIT) {
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
totalByteSize += eventSize;
|
|
279
|
+
currentEventIdx += 1;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return buffer.slice(0, currentEventIdx);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export { APILoggingProvider };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { InputLogEvent } from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
+
import {
|
|
3
|
+
AWS_CLOUDWATCH_BASE_BUFFER_SIZE,
|
|
4
|
+
AWS_CLOUDWATCH_MAX_BATCH_EVENT_SIZE,
|
|
5
|
+
AWS_CLOUDWATCH_MAX_EVENT_SIZE,
|
|
6
|
+
} from '../../Util/Constants';
|
|
7
|
+
import { GenericLogEvent } from '../../types/types';
|
|
8
|
+
import { ConsoleLogger as Logger, getStringByteSize } from '../../';
|
|
9
|
+
|
|
10
|
+
const logger = new Logger('APILoggingProvider');
|
|
11
|
+
const TRUNCATE_MAX_LENGTH = 5000;
|
|
12
|
+
|
|
13
|
+
export const cloudWatchEventFromGeneric = (
|
|
14
|
+
event: GenericLogEvent
|
|
15
|
+
): InputLogEvent => {
|
|
16
|
+
const { timestamp, ...message } = event;
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
timestamp,
|
|
20
|
+
message: JSON.stringify(message),
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const truncateOversizedEvent = (event: InputLogEvent): InputLogEvent => {
|
|
25
|
+
const { timestamp, message } = event;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const messageJson = JSON.parse(message);
|
|
29
|
+
|
|
30
|
+
const truncatedObj = {
|
|
31
|
+
level: messageJson.level,
|
|
32
|
+
class: messageJson.class,
|
|
33
|
+
message: messageJson.message.substring(0, TRUNCATE_MAX_LENGTH),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (messageJson.data != null) {
|
|
37
|
+
truncatedObj[
|
|
38
|
+
'data'
|
|
39
|
+
] = `OBJECT SIZE EXCEEDS CLOUDWATCH EVENT LIMIT. Truncated: ${JSON.stringify(
|
|
40
|
+
messageJson.data
|
|
41
|
+
).substring(0, TRUNCATE_MAX_LENGTH)}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
timestamp,
|
|
46
|
+
message: JSON.stringify(truncatedObj),
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
logger.warn('Could not truncate oversized event', error);
|
|
50
|
+
|
|
51
|
+
const truncated = JSON.stringify({
|
|
52
|
+
level: 'UNKNOWN',
|
|
53
|
+
class: 'Unknown',
|
|
54
|
+
message:
|
|
55
|
+
'OBJECT SIZE EXCEEDS CLOUDWATCH EVENT LIMIT. Could not parse event to truncate',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
timestamp,
|
|
60
|
+
message: truncated,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const cloudWatchLogEventBatch = (
|
|
66
|
+
buffer: InputLogEvent[]
|
|
67
|
+
): InputLogEvent[] => {
|
|
68
|
+
let totalByteSize = 0;
|
|
69
|
+
let currentEventIdx = 0;
|
|
70
|
+
|
|
71
|
+
while (currentEventIdx < buffer.length) {
|
|
72
|
+
let currentEvent = buffer[currentEventIdx];
|
|
73
|
+
let eventSize =
|
|
74
|
+
getStringByteSize(currentEvent.message) + AWS_CLOUDWATCH_BASE_BUFFER_SIZE;
|
|
75
|
+
|
|
76
|
+
if (eventSize > AWS_CLOUDWATCH_MAX_EVENT_SIZE) {
|
|
77
|
+
const errString = `Log event exceeds maximum size for CloudWatch logs. Log size: ${eventSize}. Truncating log message.`;
|
|
78
|
+
logger.debug(errString);
|
|
79
|
+
|
|
80
|
+
currentEvent = truncateOversizedEvent(currentEvent);
|
|
81
|
+
buffer[currentEventIdx] = currentEvent;
|
|
82
|
+
|
|
83
|
+
eventSize =
|
|
84
|
+
new TextEncoder().encode(currentEvent.message).length +
|
|
85
|
+
AWS_CLOUDWATCH_BASE_BUFFER_SIZE;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (totalByteSize + eventSize > AWS_CLOUDWATCH_MAX_BATCH_EVENT_SIZE) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
totalByteSize += eventSize;
|
|
93
|
+
currentEventIdx += 1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return buffer.slice(0, currentEventIdx);
|
|
97
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { APILoggingProvider } from './APILoggingProvider';
|