@crimson-education/browser-logger 2.0.2-cognito.2 → 3.0.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 +289 -18
- package/lib/index.d.ts +10 -24
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +45 -116
- package/lib/index.js.map +1 -1
- package/lib/logger/consoleTransport.d.ts +37 -0
- package/lib/logger/consoleTransport.d.ts.map +1 -0
- package/lib/logger/consoleTransport.js +81 -0
- package/lib/logger/consoleTransport.js.map +1 -0
- package/lib/logger/datadogTransport.d.ts +8 -0
- package/lib/logger/datadogTransport.d.ts.map +1 -0
- package/lib/logger/datadogTransport.js +21 -0
- package/lib/logger/datadogTransport.js.map +1 -0
- package/lib/logger/index.d.ts +16 -0
- package/lib/logger/index.d.ts.map +1 -0
- package/lib/logger/index.js +148 -0
- package/lib/logger/index.js.map +1 -0
- package/lib/logger/index.test.d.ts +2 -0
- package/lib/logger/index.test.d.ts.map +1 -0
- package/lib/logger/index.test.js +60 -0
- package/lib/logger/index.test.js.map +1 -0
- package/lib/logger/utils.d.ts +15 -0
- package/lib/logger/utils.d.ts.map +1 -0
- package/lib/logger/utils.js +32 -0
- package/lib/logger/utils.js.map +1 -0
- package/lib/reporters/amplifyReporter.d.ts +40 -14
- package/lib/reporters/amplifyReporter.d.ts.map +1 -1
- package/lib/reporters/amplifyReporter.js +15 -23
- package/lib/reporters/amplifyReporter.js.map +1 -1
- package/lib/reporters/amplifyReporter.test.js +0 -11
- package/lib/reporters/amplifyReporter.test.js.map +1 -1
- package/lib/reporters/datadogReporter.d.ts +64 -14
- package/lib/reporters/datadogReporter.d.ts.map +1 -1
- package/lib/reporters/datadogReporter.js +46 -101
- package/lib/reporters/datadogReporter.js.map +1 -1
- package/lib/reporters/gtmReporter.d.ts +3 -2
- package/lib/reporters/gtmReporter.d.ts.map +1 -1
- package/lib/reporters/gtmReporter.js +20 -6
- package/lib/reporters/gtmReporter.js.map +1 -1
- package/lib/reporters/index.d.ts +66 -28
- package/lib/reporters/index.d.ts.map +1 -1
- package/lib/reporters/index.js +210 -0
- package/lib/reporters/index.js.map +1 -1
- package/lib/reporters/logReporter.d.ts +35 -0
- package/lib/reporters/logReporter.d.ts.map +1 -0
- package/lib/reporters/logReporter.js +62 -0
- package/lib/reporters/logReporter.js.map +1 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +19 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/logger.d.ts +78 -0
- package/lib/types/logger.d.ts.map +1 -0
- package/lib/{types.js → types/logger.js} +1 -1
- package/lib/types/logger.js.map +1 -0
- package/lib/types/reporter.d.ts +155 -0
- package/lib/types/reporter.d.ts.map +1 -0
- package/lib/types/reporter.js +3 -0
- package/lib/types/reporter.js.map +1 -0
- package/lib/utils.d.ts +9 -4
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +28 -43
- package/lib/utils.js.map +1 -1
- package/lib/utils.test.d.ts +2 -0
- package/lib/utils.test.d.ts.map +1 -0
- package/lib/utils.test.js +32 -0
- package/lib/utils.test.js.map +1 -0
- package/package.json +5 -4
- package/src/index.ts +41 -120
- package/src/logger/consoleTransport.ts +101 -0
- package/src/logger/datadogTransport.ts +20 -0
- package/src/logger/index.test.ts +68 -0
- package/src/logger/index.ts +139 -0
- package/src/logger/utils.ts +28 -0
- package/src/reporters/amplifyReporter.test.ts +1 -14
- package/src/reporters/amplifyReporter.ts +65 -36
- package/src/reporters/datadogReporter.ts +123 -115
- package/src/reporters/gtmReporter.ts +35 -8
- package/src/reporters/index.ts +208 -24
- package/src/reporters/logReporter.ts +86 -0
- package/src/types/index.ts +2 -0
- package/src/types/logger.ts +85 -0
- package/src/types/reporter.ts +167 -0
- package/src/utils.test.ts +32 -0
- package/src/utils.ts +39 -49
- package/lib/types.d.ts +0 -48
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js.map +0 -1
- package/src/types.ts +0 -50
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
IReporter,
|
|
3
|
+
ReporterBreadcrumb,
|
|
4
|
+
ReporterEvent,
|
|
5
|
+
Metadata,
|
|
6
|
+
ReportUser,
|
|
7
|
+
ServiceInfo,
|
|
8
|
+
ReporterConfigBase,
|
|
9
|
+
} from '../types';
|
|
10
|
+
|
|
11
|
+
export type GTMReporterConfig = ReporterConfigBase;
|
|
4
12
|
|
|
5
13
|
declare global {
|
|
6
14
|
interface Window {
|
|
@@ -8,10 +16,27 @@ declare global {
|
|
|
8
16
|
}
|
|
9
17
|
}
|
|
10
18
|
|
|
11
|
-
export function gtmReporter(): IReporter {
|
|
19
|
+
export function gtmReporter(info: ServiceInfo, config: GTMReporterConfig): IReporter {
|
|
20
|
+
let loadedDataLayer = !!window.dataLayer;
|
|
21
|
+
const baseMetadata = {
|
|
22
|
+
service: info.service,
|
|
23
|
+
domain: window.location.host,
|
|
24
|
+
environment: info.environment,
|
|
25
|
+
version: info.version,
|
|
26
|
+
};
|
|
27
|
+
|
|
12
28
|
const reporter: IReporter = {
|
|
29
|
+
...config,
|
|
13
30
|
addMetadata: function (metadata: Metadata): void {
|
|
14
|
-
window.dataLayer
|
|
31
|
+
if (window.dataLayer) {
|
|
32
|
+
// Lazy load base metadata, e.g. if GTM isn't ready yet.
|
|
33
|
+
if (!loadedDataLayer) {
|
|
34
|
+
window.dataLayer.push(baseMetadata);
|
|
35
|
+
loadedDataLayer = true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
window.dataLayer.push(metadata);
|
|
39
|
+
}
|
|
15
40
|
},
|
|
16
41
|
trackEvent: function (event: ReporterEvent): void {
|
|
17
42
|
reporter.addMetadata({
|
|
@@ -39,9 +64,11 @@ export function gtmReporter(): IReporter {
|
|
|
39
64
|
setPageName: function (pageName: string): void {
|
|
40
65
|
reporter.addMetadata({ pageName });
|
|
41
66
|
},
|
|
42
|
-
reportError: function (): void {},
|
|
43
|
-
recordSession: function (): void {},
|
|
44
|
-
recordSessionStop: function (): void {},
|
|
45
67
|
};
|
|
68
|
+
|
|
69
|
+
if (loadedDataLayer) {
|
|
70
|
+
reporter.addMetadata(baseMetadata);
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
return reporter;
|
|
47
74
|
}
|
package/src/reporters/index.ts
CHANGED
|
@@ -1,32 +1,216 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isAboveLevel } from '../logger/utils';
|
|
2
|
+
import {
|
|
3
|
+
IReporter,
|
|
4
|
+
LogLevel,
|
|
5
|
+
Metadata,
|
|
6
|
+
ReporterBreadcrumb,
|
|
7
|
+
ReporterEvent,
|
|
8
|
+
ReporterFilters,
|
|
9
|
+
ReportError,
|
|
10
|
+
ReporterType,
|
|
11
|
+
ReportUser,
|
|
12
|
+
TrackedReporterEvent,
|
|
13
|
+
} from '../types';
|
|
14
|
+
import { filterReporterMetadata } from '../utils';
|
|
3
15
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
export const reporters: Partial<Record<ReporterType, IReporter>> = {};
|
|
17
|
+
|
|
18
|
+
export let globalEventLevel: LogLevel | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Sets the global event level.
|
|
21
|
+
*/
|
|
22
|
+
export function setEventLevel(level: LogLevel | null): void {
|
|
23
|
+
globalEventLevel = level ?? undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Gets reporters, optionally with filters.
|
|
28
|
+
* @param filters Filters to remove or specify specific reporters.
|
|
29
|
+
* @returns Selected reporters, or all registered reporters.
|
|
30
|
+
*/
|
|
31
|
+
function getReporters(filters?: ReporterFilters) {
|
|
32
|
+
let result = Object.entries(reporters);
|
|
33
|
+
if (filters?.excludeReporters) {
|
|
34
|
+
result = result.filter(([key]) => !filters?.excludeReporters?.includes(key as ReporterType));
|
|
35
|
+
}
|
|
36
|
+
if (filters?.toReporters) {
|
|
37
|
+
result = result.filter(([key]) => filters?.toReporters?.includes(key as ReporterType));
|
|
38
|
+
}
|
|
39
|
+
return result.map(([, reporter]) => reporter);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Tracks an Analytics event.
|
|
44
|
+
*/
|
|
45
|
+
export function trackEvent(event: ReporterEvent): void {
|
|
46
|
+
if (globalEventLevel && event.level && !isAboveLevel(event.level, globalEventLevel)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const reporter of getReporters(event)) {
|
|
51
|
+
if (reporter.endpoints?.trackEvent === false) {
|
|
52
|
+
continue;
|
|
53
|
+
} else if (reporter.eventLevel && event.level && !isAboveLevel(event.level, reporter.eventLevel)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const reporterEvent = { ...event };
|
|
58
|
+
reporterEvent.metadata = filterReporterMetadata(event.metadata, reporter);
|
|
59
|
+
reporterEvent.metrics = filterReporterMetadata(event.metrics, reporter);
|
|
60
|
+
reporterEvent.tags = filterReporterMetadata(event.tags, reporter);
|
|
61
|
+
reporter.trackEvent(reporterEvent);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Tracks an Analytics event, recording the time since the last event, if available.
|
|
67
|
+
*/
|
|
68
|
+
export function trackEventSinceLastAction(event: ReporterEvent): void {
|
|
69
|
+
if (globalEventLevel && event.level && !isAboveLevel(event.level, globalEventLevel)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const lastEvent = getLastTrackedEvent();
|
|
74
|
+
if (lastEvent) {
|
|
75
|
+
const duration = new Date().getTime() - lastEvent.occurred.getTime();
|
|
76
|
+
trackEvent({
|
|
77
|
+
...event,
|
|
78
|
+
metadata: {
|
|
79
|
+
...event.metadata,
|
|
80
|
+
lastEventName: lastEvent.message,
|
|
81
|
+
timeSinceLastEvent: duration,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
trackEvent(event);
|
|
86
|
+
}
|
|
87
|
+
sessionStorage.setItem('loggerLastEvent', JSON.stringify({ ...event, occurred: new Date() }));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gets the last tracked event, if available.
|
|
92
|
+
*/
|
|
93
|
+
export function getLastTrackedEvent(): TrackedReporterEvent | null {
|
|
94
|
+
const eventStr = sessionStorage.getItem('loggerLastEvent');
|
|
95
|
+
if (!eventStr) return null;
|
|
96
|
+
|
|
97
|
+
const event: TrackedReporterEvent = JSON.parse(eventStr);
|
|
98
|
+
event.occurred = new Date(event.occurred);
|
|
99
|
+
return event;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Breadcrumbs to create a trail of events that happened prior to an issue.
|
|
104
|
+
* These events are very similar to traditional logs, but can record more rich structured data.
|
|
105
|
+
*/
|
|
106
|
+
export function addBreadcrumb(breadcrumb: ReporterBreadcrumb): void {
|
|
107
|
+
for (const reporter of getReporters(breadcrumb)) {
|
|
108
|
+
if (reporter.endpoints?.addBreadcrumb === false) {
|
|
109
|
+
continue;
|
|
110
|
+
} else if (breadcrumb.category && reporter.ignoreBreadcrumbCategories?.includes(breadcrumb.category)) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const reporterBreadcrumb = { ...breadcrumb };
|
|
115
|
+
reporterBreadcrumb.metadata = filterReporterMetadata(breadcrumb.metadata, reporter);
|
|
116
|
+
reporter.addBreadcrumb(reporterBreadcrumb);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Adds global metadata to all events and logs.
|
|
122
|
+
* @param metadata Metadata to add.
|
|
123
|
+
* @param filters Optional filters to specify which reporters to add metadata to.
|
|
124
|
+
*/
|
|
125
|
+
export function addMetadata(metadata: Metadata, filters?: ReporterFilters): void {
|
|
126
|
+
for (const reporter of getReporters(filters)) {
|
|
127
|
+
if (reporter.endpoints?.addMetadata === false) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
reporter.addMetadata(filterReporterMetadata(metadata, reporter));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Sets the user information in Analytics.
|
|
136
|
+
* @param user User information, or null to clear.
|
|
137
|
+
* @param filters Optional filters to specify which reporters to set the user for.
|
|
138
|
+
*/
|
|
139
|
+
export function setUser(user: ReportUser | null, filters?: ReporterFilters): void {
|
|
140
|
+
for (const reporter of getReporters(filters)) {
|
|
141
|
+
if (reporter.endpoints?.setUser === false) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
reporter.setUser(user);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Sets the route name in Analytics.
|
|
150
|
+
* Some Analytics services use this differentiate SPA Route vs Page changes.
|
|
151
|
+
* @param routeName Name of the Route.
|
|
152
|
+
* @param filters Optional filters to specify which reporters to set the route name for.
|
|
153
|
+
*/
|
|
154
|
+
export function setRouteName(routeName: string, filters?: ReporterFilters): void {
|
|
155
|
+
for (const reporter of getReporters(filters)) {
|
|
156
|
+
if (reporter.endpoints?.setRouteName === false) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
reporter.setRouteName(routeName);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Sets the page name in Analytics.
|
|
165
|
+
* @param pageName Name of the Page.
|
|
166
|
+
* @param filters Optional filters to specify which reporters to set the page name for.
|
|
167
|
+
*/
|
|
168
|
+
export function setPageName(pageName: string, filters?: ReporterFilters): void {
|
|
169
|
+
for (const reporter of getReporters(filters)) {
|
|
170
|
+
if (reporter.endpoints?.setPageName === false) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
reporter.setPageName(pageName);
|
|
174
|
+
}
|
|
10
175
|
}
|
|
11
176
|
|
|
12
|
-
|
|
13
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Reports an Error in Reporters that support error tracking.
|
|
179
|
+
* @param error Error data.
|
|
180
|
+
* @param metadata Metadata to add to the error.
|
|
181
|
+
* @param filters Optional filters to specify which reporters to report the error to.
|
|
182
|
+
*/
|
|
183
|
+
export function reportError(error: ReportError, metadata?: Metadata, filters?: ReporterFilters): void {
|
|
184
|
+
for (const reporter of getReporters(filters)) {
|
|
185
|
+
if (reporter.endpoints?.reportError === false) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
reporter.reportError?.(error, filterReporterMetadata(metadata, reporter));
|
|
189
|
+
}
|
|
14
190
|
}
|
|
15
191
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Starts a session recording in Analytics, e.g. RUM Session Replay
|
|
194
|
+
* @param filters Optional filters to specify which reporters to start a session recording for.
|
|
195
|
+
*/
|
|
196
|
+
export function recordSession(filters?: ReporterFilters): void {
|
|
197
|
+
for (const reporter of getReporters(filters)) {
|
|
198
|
+
if (reporter.endpoints?.recordSession === false) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
reporter.recordSession?.();
|
|
202
|
+
}
|
|
20
203
|
}
|
|
21
204
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Stops a session recording in Analytics, e.g. RUM Session Replay
|
|
207
|
+
* @param filters Optional filters to specify which reporters to stop a session recording for.
|
|
208
|
+
*/
|
|
209
|
+
export function recordSessionStop(filters?: ReporterFilters): void {
|
|
210
|
+
for (const reporter of getReporters(filters)) {
|
|
211
|
+
if (reporter.endpoints?.recordSessionStop === false) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
reporter.recordSessionStop?.();
|
|
215
|
+
}
|
|
32
216
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { logger, globalMetadata as globalLogMetadata } from '../logger';
|
|
2
|
+
import { IReporter, LogLevel, ReporterConfigBase, ServiceInfo } from '../types';
|
|
3
|
+
|
|
4
|
+
export interface LogReporterConfig extends ReporterConfigBase {
|
|
5
|
+
/**
|
|
6
|
+
* The fallback log level to apply to all trackEvent calls (if the event's level is not set).
|
|
7
|
+
* Defaults to info.
|
|
8
|
+
*/
|
|
9
|
+
trackEventDefaultLevel?: LogLevel;
|
|
10
|
+
/**
|
|
11
|
+
* The log level to apply to all addBreadcrumb calls.
|
|
12
|
+
* Defaults to info.
|
|
13
|
+
*/
|
|
14
|
+
addBreadcrumbLevel?: LogLevel;
|
|
15
|
+
/**
|
|
16
|
+
* The log level to apply to all setRouteName calls.
|
|
17
|
+
* Defaults to debug.
|
|
18
|
+
*/
|
|
19
|
+
setRouteNameLevel?: LogLevel;
|
|
20
|
+
/**
|
|
21
|
+
* The log level to apply to all setPageName calls.
|
|
22
|
+
* Defaults to debug.
|
|
23
|
+
*/
|
|
24
|
+
setPageNameLevel?: LogLevel;
|
|
25
|
+
/**
|
|
26
|
+
* The log level to apply to all recordSession calls.
|
|
27
|
+
* Defaults to debug.
|
|
28
|
+
*/
|
|
29
|
+
recordSessionLevel?: LogLevel;
|
|
30
|
+
/**
|
|
31
|
+
* The log level to apply to all recordSessionStop calls.
|
|
32
|
+
* Defaults to debug.
|
|
33
|
+
*/
|
|
34
|
+
recordSessionStopLevel?: LogLevel;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function logReporter(info: ServiceInfo, config: LogReporterConfig) {
|
|
38
|
+
const reporter: IReporter = {
|
|
39
|
+
...config,
|
|
40
|
+
trackEvent(event) {
|
|
41
|
+
// config.trackEventLevel and config.level overrides event.level here, as it is an override, while config.trackEventDefaultLevel is a fallback.
|
|
42
|
+
const level = event.level ?? config.trackEventDefaultLevel ?? LogLevel.Info;
|
|
43
|
+
logger.log(level, event.message, {
|
|
44
|
+
...(event.metadata ?? {}),
|
|
45
|
+
...(event.metrics ?? {}),
|
|
46
|
+
...(event.tags ?? {}),
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
addBreadcrumb(breadcrumb) {
|
|
50
|
+
const level = config.addBreadcrumbLevel ?? LogLevel.Info;
|
|
51
|
+
logger.log(level, breadcrumb.message, {
|
|
52
|
+
...(breadcrumb.metadata ?? {}),
|
|
53
|
+
category: breadcrumb.category,
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
addMetadata(metadata) {
|
|
57
|
+
Object.assign(globalLogMetadata, metadata);
|
|
58
|
+
},
|
|
59
|
+
setUser(user) {
|
|
60
|
+
Object.assign(globalLogMetadata, { user });
|
|
61
|
+
},
|
|
62
|
+
setRouteName(routeName) {
|
|
63
|
+
Object.assign(globalLogMetadata, { routeName });
|
|
64
|
+
const level = config.setRouteNameLevel ?? LogLevel.Debug;
|
|
65
|
+
logger.log(level, `Route changed to ${routeName}`);
|
|
66
|
+
},
|
|
67
|
+
setPageName(pageName) {
|
|
68
|
+
Object.assign(globalLogMetadata, { pageName });
|
|
69
|
+
const level = config.setPageNameLevel ?? LogLevel.Debug;
|
|
70
|
+
logger.log(level, `Page changed to ${pageName}`);
|
|
71
|
+
},
|
|
72
|
+
reportError(error, metadata) {
|
|
73
|
+
logger.error(typeof error === 'string' ? error : error.message, { ...metadata, error });
|
|
74
|
+
},
|
|
75
|
+
recordSession() {
|
|
76
|
+
const level = config.recordSessionLevel ?? LogLevel.Debug;
|
|
77
|
+
logger.log(level, 'Recording Session');
|
|
78
|
+
},
|
|
79
|
+
recordSessionStop() {
|
|
80
|
+
const level = config.recordSessionStopLevel ?? LogLevel.Debug;
|
|
81
|
+
logger.log(level, 'Recording Session Stopping');
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return reporter;
|
|
86
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type Metadata = Record<string, any>;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options to Customize the Logger
|
|
5
|
+
*/
|
|
6
|
+
export type LoggerOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* The min log level for events to be sent to the logger.
|
|
9
|
+
*/
|
|
10
|
+
logLevel?: LogLevel;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Metadata to add to all logs.
|
|
14
|
+
*/
|
|
15
|
+
metadata?: Metadata;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export enum LogLevel {
|
|
19
|
+
Debug = 'debug',
|
|
20
|
+
Info = 'info',
|
|
21
|
+
Warn = 'warn',
|
|
22
|
+
Error = 'error',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface LogLevelMethod {
|
|
26
|
+
(message: string, metadata?: Metadata): ILogger;
|
|
27
|
+
(message: string, ...meta: any[]): ILogger;
|
|
28
|
+
(message: any): ILogger;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface LogMethod {
|
|
32
|
+
(level: LogLevel, message: string, metadata?: Metadata): ILogger;
|
|
33
|
+
(level: LogLevel, message: string, ...meta: any[]): ILogger;
|
|
34
|
+
(level: LogLevel, message: any): ILogger;
|
|
35
|
+
(message: Record<string, any>): ILogger;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Profiler {
|
|
39
|
+
logger: ILogger;
|
|
40
|
+
done(info?: { message?: string; level?: LogLevel; metadata?: Metadata }): boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type StructuredLog = {
|
|
44
|
+
level: LogLevel;
|
|
45
|
+
message: any;
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export interface LogTransportConfigBase {
|
|
50
|
+
/**
|
|
51
|
+
* The min log level for logs to be sent.
|
|
52
|
+
*/
|
|
53
|
+
logLevel?: LogLevel;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Ignore specific metadata keys from being sent.
|
|
57
|
+
* This can be a regular expression, or a string to exact match.
|
|
58
|
+
* This is useful to prevent data of no use for the logger, or if the data keys are too long.
|
|
59
|
+
*/
|
|
60
|
+
ignoreMetadataPatterns?: (string | RegExp)[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A logger interface that is used to transport logs to a destination
|
|
65
|
+
*/
|
|
66
|
+
export interface ILogTransport extends LogTransportConfigBase {
|
|
67
|
+
/**
|
|
68
|
+
* Inbound log event to transport.
|
|
69
|
+
*/
|
|
70
|
+
log: (logInfo: StructuredLog) => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A Logger is a service that can receive log messages.
|
|
75
|
+
*/
|
|
76
|
+
export interface ILogger {
|
|
77
|
+
startTimer(): Profiler;
|
|
78
|
+
child(metadata?: Metadata, name?: string): ILogger;
|
|
79
|
+
|
|
80
|
+
log: LogMethod;
|
|
81
|
+
debug: LogLevelMethod;
|
|
82
|
+
info: LogLevelMethod;
|
|
83
|
+
warn: LogLevelMethod;
|
|
84
|
+
error: LogLevelMethod;
|
|
85
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { AmplifyReporterConfig } from '../reporters/amplifyReporter';
|
|
2
|
+
import { DatadogReporterConfig } from '../reporters/datadogReporter';
|
|
3
|
+
import { GTMReporterConfig } from '../reporters/gtmReporter';
|
|
4
|
+
import { LogReporterConfig } from '../reporters/logReporter';
|
|
5
|
+
import { LogLevel, Metadata } from './logger';
|
|
6
|
+
|
|
7
|
+
export type ReporterConfigurations = {
|
|
8
|
+
/**
|
|
9
|
+
* Log reporter configuration.
|
|
10
|
+
* If not set, it will default to everything enabled.
|
|
11
|
+
*/
|
|
12
|
+
log?: boolean | LogReporterConfig;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Datadog reporter configuration.
|
|
16
|
+
* If not set, the datadog reporter will not be used.
|
|
17
|
+
*/
|
|
18
|
+
datadog?: DatadogReporterConfig;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Amplify/Pinpoint reporter configuration.
|
|
22
|
+
* If not set, the amplify reporter will not be used.
|
|
23
|
+
*/
|
|
24
|
+
amplify?: AmplifyReporterConfig;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Google Tag Manager reporter configuration.
|
|
28
|
+
* If not set, the gtm reporter will not be used.
|
|
29
|
+
*/
|
|
30
|
+
gtm?: true | GTMReporterConfig;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ReporterType = keyof ReporterConfigurations;
|
|
34
|
+
|
|
35
|
+
export type Metrics = Record<string, number>;
|
|
36
|
+
|
|
37
|
+
export type ServiceInfo = {
|
|
38
|
+
/** The Application's name. */
|
|
39
|
+
service: string;
|
|
40
|
+
/** The Application's Environment */
|
|
41
|
+
environment: string;
|
|
42
|
+
/** The Application's Version. */
|
|
43
|
+
version: string;
|
|
44
|
+
/**
|
|
45
|
+
* Default metadata to add to Reporter events.
|
|
46
|
+
*/
|
|
47
|
+
defaultMetadata?: Metadata;
|
|
48
|
+
/**
|
|
49
|
+
* The min log level for logs to be sent to the logger.
|
|
50
|
+
*/
|
|
51
|
+
logLevel?: LogLevel;
|
|
52
|
+
/**
|
|
53
|
+
* The min event level for events to be sent to reporters.
|
|
54
|
+
*/
|
|
55
|
+
eventLevel?: LogLevel;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type ReportUser = { id: string; email?: string; username?: string; name?: string };
|
|
59
|
+
|
|
60
|
+
export type ReportError = Error | string;
|
|
61
|
+
|
|
62
|
+
export interface ReporterFilters {
|
|
63
|
+
/**
|
|
64
|
+
* Send only to these Reporters.
|
|
65
|
+
*/
|
|
66
|
+
toReporters?: ReporterType[];
|
|
67
|
+
/**
|
|
68
|
+
* Don't send to these Reporters.
|
|
69
|
+
*/
|
|
70
|
+
excludeReporters?: ReporterType[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ReporterEvent extends ReporterFilters {
|
|
74
|
+
/**
|
|
75
|
+
* The Severity of this event.
|
|
76
|
+
*/
|
|
77
|
+
level?: LogLevel;
|
|
78
|
+
/**
|
|
79
|
+
* The event message/name.
|
|
80
|
+
*/
|
|
81
|
+
message: string;
|
|
82
|
+
/**
|
|
83
|
+
* Event metadata.
|
|
84
|
+
*/
|
|
85
|
+
metadata?: Metadata | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Event tags, if supported by the Reporter. (Otherwise, they will be added to metadata)
|
|
88
|
+
*/
|
|
89
|
+
tags?: Metadata | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Event metrics, if supported by the Reporter. (Otherwise, they will be added to metadata)
|
|
92
|
+
* Metrics are numbers, and are used for aggregations.
|
|
93
|
+
*/
|
|
94
|
+
metrics?: Metrics | undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface TrackedReporterEvent extends ReporterEvent {
|
|
98
|
+
/**
|
|
99
|
+
* The time this event was created.
|
|
100
|
+
*/
|
|
101
|
+
occurred: Date;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface ReporterBreadcrumb extends ReporterFilters {
|
|
105
|
+
/**
|
|
106
|
+
* The breadcrumb event message/name.
|
|
107
|
+
*/
|
|
108
|
+
message: string;
|
|
109
|
+
/**
|
|
110
|
+
* The category of this breadcrumb (Useful for filtering out in specific reporters).
|
|
111
|
+
*/
|
|
112
|
+
category?: string | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Breadcrumb metadata.
|
|
115
|
+
*/
|
|
116
|
+
metadata?: Metadata | undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface ReporterConfigBase {
|
|
120
|
+
/**
|
|
121
|
+
* Enable/Disable reporter endpoints from being called.
|
|
122
|
+
*/
|
|
123
|
+
endpoints?: {
|
|
124
|
+
trackEvent?: boolean;
|
|
125
|
+
addMetadata?: boolean;
|
|
126
|
+
addBreadcrumb?: boolean;
|
|
127
|
+
setUser?: boolean;
|
|
128
|
+
setRouteName?: boolean;
|
|
129
|
+
setPageName?: boolean;
|
|
130
|
+
reportError?: boolean;
|
|
131
|
+
recordSession?: boolean;
|
|
132
|
+
recordSessionStop?: boolean;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The min event level for events to be sent to the reporter.
|
|
137
|
+
*/
|
|
138
|
+
eventLevel?: LogLevel;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Categories of breadcrumbs to ignore sending to the reporter.
|
|
142
|
+
* This is useful to prevent data of no use for that reporter.
|
|
143
|
+
*/
|
|
144
|
+
ignoreBreadcrumbCategories?: string[];
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Ignore specific metadata keys from being sent to the reporter.
|
|
148
|
+
* This can be a regular expression, or a string to exact match.
|
|
149
|
+
* This is useful to prevent data of no use for the reporter, or if the data keys are too long.
|
|
150
|
+
*/
|
|
151
|
+
ignoreMetadataPatterns?: (string | RegExp)[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A Reporter is a service that can receive Analytics data.
|
|
156
|
+
*/
|
|
157
|
+
export interface IReporter extends ReporterConfigBase {
|
|
158
|
+
trackEvent(event: ReporterEvent): void;
|
|
159
|
+
addBreadcrumb(breadcrumb: ReporterBreadcrumb): void;
|
|
160
|
+
addMetadata(metadata: Metadata): void;
|
|
161
|
+
setUser(user: ReportUser | null): void;
|
|
162
|
+
setRouteName(routeName: string): void;
|
|
163
|
+
setPageName(pageName: string): void;
|
|
164
|
+
reportError?(error: ReportError, metadata?: Metadata): void;
|
|
165
|
+
recordSession?(): void;
|
|
166
|
+
recordSessionStop?(): void;
|
|
167
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { filterReporterMetadata } from './utils';
|
|
2
|
+
|
|
3
|
+
describe('utils', () => {
|
|
4
|
+
describe('filterReporterMetadata', () => {
|
|
5
|
+
it('should remove attributes which match the ignore patterns', () => {
|
|
6
|
+
const inputAttributeMap = {
|
|
7
|
+
includeme: '5',
|
|
8
|
+
excludeme: 'false',
|
|
9
|
+
differentProp: 'boo',
|
|
10
|
+
deep: {
|
|
11
|
+
includeme: '5',
|
|
12
|
+
excludeme: 'false',
|
|
13
|
+
deepExcludeStr: 'boo',
|
|
14
|
+
deepExcludeRegex: 'boo',
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const filtered = filterReporterMetadata(inputAttributeMap, {
|
|
19
|
+
ignoreMetadataPatterns: [/excludeme/g, /Prop/g, 'deep.deepExcludeStr', /deep\.deepExcludeRegex/g],
|
|
20
|
+
});
|
|
21
|
+
expect(filtered.includeme).toBeTruthy();
|
|
22
|
+
expect(filtered.excludeme).toBeFalsy();
|
|
23
|
+
expect(filtered.differentProp).toBeFalsy();
|
|
24
|
+
|
|
25
|
+
// deep
|
|
26
|
+
expect(filtered.deep.includeme).toBeTruthy();
|
|
27
|
+
expect(filtered.deep.excludeme).toBeFalsy();
|
|
28
|
+
expect(filtered.deep.deepExcludeStr).toBeFalsy();
|
|
29
|
+
expect(filtered.deep.deepExcludeRegex).toBeFalsy();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|