@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.
Files changed (89) hide show
  1. package/README.md +289 -18
  2. package/lib/index.d.ts +10 -24
  3. package/lib/index.d.ts.map +1 -1
  4. package/lib/index.js +45 -116
  5. package/lib/index.js.map +1 -1
  6. package/lib/logger/consoleTransport.d.ts +37 -0
  7. package/lib/logger/consoleTransport.d.ts.map +1 -0
  8. package/lib/logger/consoleTransport.js +81 -0
  9. package/lib/logger/consoleTransport.js.map +1 -0
  10. package/lib/logger/datadogTransport.d.ts +8 -0
  11. package/lib/logger/datadogTransport.d.ts.map +1 -0
  12. package/lib/logger/datadogTransport.js +21 -0
  13. package/lib/logger/datadogTransport.js.map +1 -0
  14. package/lib/logger/index.d.ts +16 -0
  15. package/lib/logger/index.d.ts.map +1 -0
  16. package/lib/logger/index.js +148 -0
  17. package/lib/logger/index.js.map +1 -0
  18. package/lib/logger/index.test.d.ts +2 -0
  19. package/lib/logger/index.test.d.ts.map +1 -0
  20. package/lib/logger/index.test.js +60 -0
  21. package/lib/logger/index.test.js.map +1 -0
  22. package/lib/logger/utils.d.ts +15 -0
  23. package/lib/logger/utils.d.ts.map +1 -0
  24. package/lib/logger/utils.js +32 -0
  25. package/lib/logger/utils.js.map +1 -0
  26. package/lib/reporters/amplifyReporter.d.ts +40 -14
  27. package/lib/reporters/amplifyReporter.d.ts.map +1 -1
  28. package/lib/reporters/amplifyReporter.js +15 -23
  29. package/lib/reporters/amplifyReporter.js.map +1 -1
  30. package/lib/reporters/amplifyReporter.test.js +0 -11
  31. package/lib/reporters/amplifyReporter.test.js.map +1 -1
  32. package/lib/reporters/datadogReporter.d.ts +64 -14
  33. package/lib/reporters/datadogReporter.d.ts.map +1 -1
  34. package/lib/reporters/datadogReporter.js +46 -101
  35. package/lib/reporters/datadogReporter.js.map +1 -1
  36. package/lib/reporters/gtmReporter.d.ts +3 -2
  37. package/lib/reporters/gtmReporter.d.ts.map +1 -1
  38. package/lib/reporters/gtmReporter.js +20 -6
  39. package/lib/reporters/gtmReporter.js.map +1 -1
  40. package/lib/reporters/index.d.ts +66 -28
  41. package/lib/reporters/index.d.ts.map +1 -1
  42. package/lib/reporters/index.js +210 -0
  43. package/lib/reporters/index.js.map +1 -1
  44. package/lib/reporters/logReporter.d.ts +35 -0
  45. package/lib/reporters/logReporter.d.ts.map +1 -0
  46. package/lib/reporters/logReporter.js +62 -0
  47. package/lib/reporters/logReporter.js.map +1 -0
  48. package/lib/types/index.d.ts +3 -0
  49. package/lib/types/index.d.ts.map +1 -0
  50. package/lib/types/index.js +19 -0
  51. package/lib/types/index.js.map +1 -0
  52. package/lib/types/logger.d.ts +78 -0
  53. package/lib/types/logger.d.ts.map +1 -0
  54. package/lib/{types.js → types/logger.js} +1 -1
  55. package/lib/types/logger.js.map +1 -0
  56. package/lib/types/reporter.d.ts +155 -0
  57. package/lib/types/reporter.d.ts.map +1 -0
  58. package/lib/types/reporter.js +3 -0
  59. package/lib/types/reporter.js.map +1 -0
  60. package/lib/utils.d.ts +9 -4
  61. package/lib/utils.d.ts.map +1 -1
  62. package/lib/utils.js +28 -43
  63. package/lib/utils.js.map +1 -1
  64. package/lib/utils.test.d.ts +2 -0
  65. package/lib/utils.test.d.ts.map +1 -0
  66. package/lib/utils.test.js +32 -0
  67. package/lib/utils.test.js.map +1 -0
  68. package/package.json +5 -4
  69. package/src/index.ts +41 -120
  70. package/src/logger/consoleTransport.ts +101 -0
  71. package/src/logger/datadogTransport.ts +20 -0
  72. package/src/logger/index.test.ts +68 -0
  73. package/src/logger/index.ts +139 -0
  74. package/src/logger/utils.ts +28 -0
  75. package/src/reporters/amplifyReporter.test.ts +1 -14
  76. package/src/reporters/amplifyReporter.ts +65 -36
  77. package/src/reporters/datadogReporter.ts +123 -115
  78. package/src/reporters/gtmReporter.ts +35 -8
  79. package/src/reporters/index.ts +208 -24
  80. package/src/reporters/logReporter.ts +86 -0
  81. package/src/types/index.ts +2 -0
  82. package/src/types/logger.ts +85 -0
  83. package/src/types/reporter.ts +167 -0
  84. package/src/utils.test.ts +32 -0
  85. package/src/utils.ts +39 -49
  86. package/lib/types.d.ts +0 -48
  87. package/lib/types.d.ts.map +0 -1
  88. package/lib/types.js.map +0 -1
  89. package/src/types.ts +0 -50
package/lib/utils.js CHANGED
@@ -1,47 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.consoleLogger = void 0;
4
- /* eslint-disable @typescript-eslint/no-unused-vars */
5
- /* eslint-disable @typescript-eslint/no-explicit-any */
6
- const _1 = require(".");
7
- function consoleLogger(name, options) {
8
- const logger = {
9
- startTimer() {
10
- const start = new Date();
11
- return {
12
- logger: this,
13
- done: (args) => {
14
- var _a, _b;
15
- const duration = new Date().getTime() - start.getTime();
16
- logger[(_a = args === null || args === void 0 ? void 0 : args.level) !== null && _a !== void 0 ? _a : _1.LogLevel.Info](`${(_b = args === null || args === void 0 ? void 0 : args.message) !== null && _b !== void 0 ? _b : 'Timer'} completed in: ${duration}`);
17
- return true;
18
- },
19
- };
20
- },
21
- child(metadata, name) {
22
- return consoleLogger(name, { metadata });
23
- },
24
- log: (level, message, metadata) => {
25
- return logger[level](message, message);
26
- },
27
- debug: (...args) => {
28
- console.debug(...args);
29
- return logger;
30
- },
31
- info: (...args) => {
32
- console.log(...args);
33
- return logger;
34
- },
35
- warn: (...args) => {
36
- console.warn(...args);
37
- return logger;
38
- },
39
- error: (...args) => {
40
- console.error(...args);
41
- return logger;
42
- },
43
- };
44
- return logger;
3
+ exports.filterReporterMetadata = void 0;
4
+ /**
5
+ * Recursively filter reporter metadata.
6
+ * @param metadata Deep Metadata to filter.
7
+ * @param reporter Reporter with filter config.
8
+ * @param prefix Prefix for recusring nested metadata.
9
+ * @returns Filtered metadata.
10
+ */
11
+ function filterReporterMetadata(metadata, reporter, prefix) {
12
+ const ignorePatterns = reporter.ignoreMetadataPatterns;
13
+ // No metadata, or no patterns.
14
+ if (metadata === undefined || !ignorePatterns) {
15
+ return metadata;
16
+ }
17
+ const entries = Object.entries(metadata);
18
+ return Object.fromEntries(entries
19
+ .filter(([key]) => {
20
+ const fullKey = prefix ? prefix + key : key;
21
+ return !ignorePatterns.some((pattern) => typeof pattern === 'string' ? pattern === fullKey : pattern.test(fullKey));
22
+ })
23
+ .map(([key, value]) => {
24
+ if (typeof value === 'object' && value !== null) {
25
+ const fullKey = prefix ? prefix + key : key;
26
+ return [key, filterReporterMetadata(value, reporter, `${fullKey}.`)];
27
+ }
28
+ return [key, value];
29
+ }));
45
30
  }
46
- exports.consoleLogger = consoleLogger;
31
+ exports.filterReporterMetadata = filterReporterMetadata;
47
32
  //# sourceMappingURL=utils.js.map
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,sDAAsD;AACtD,uDAAuD;AACvD,wBAAqF;AAErF,SAAgB,aAAa,CAAC,IAAa,EAAE,OAAiC;IAC5E,MAAM,MAAM,GAAY;QACtB,UAAU;YACR,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;YAEzB,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;;oBACb,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;oBACxD,MAAM,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,mCAAI,WAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,mCAAI,OAAO,kBAAkB,QAAQ,EAAE,CAAC,CAAC;oBAC9F,OAAO,IAAI,CAAC;gBACd,CAAC;aACF,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,QAA8B,EAAE,IAAa;YACjD,OAAO,aAAa,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,GAAG,EAAE,CAAC,KAAe,EAAE,OAAe,EAAE,QAAc,EAAE,EAAE;YACxD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QAED,KAAK,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACrB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACvB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACtB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,KAAK,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AA7CD,sCA6CC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAEA;;;;;;GAMG;AACH,SAAgB,sBAAsB,CACpC,QAAmB,EACnB,QAAmD,EACnD,MAAe;IAEf,MAAM,cAAc,GAAG,QAAQ,CAAC,sBAAsB,CAAC;IAEvD,+BAA+B;IAC/B,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE;QAC7C,OAAO,QAAQ,CAAC;KACjB;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC,WAAW,CACvB,OAAO;SACJ,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC5C,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACtC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAC1E,CAAC;IACJ,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;YAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC5C,OAAO,CAAC,GAAG,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;SACtE;QACD,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC,CACQ,CAAC;AACjB,CAAC;AA9BD,wDA8BC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("./utils");
4
+ describe('utils', () => {
5
+ describe('filterReporterMetadata', () => {
6
+ it('should remove attributes which match the ignore patterns', () => {
7
+ const inputAttributeMap = {
8
+ includeme: '5',
9
+ excludeme: 'false',
10
+ differentProp: 'boo',
11
+ deep: {
12
+ includeme: '5',
13
+ excludeme: 'false',
14
+ deepExcludeStr: 'boo',
15
+ deepExcludeRegex: 'boo',
16
+ },
17
+ };
18
+ const filtered = (0, utils_1.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
+ // deep
25
+ expect(filtered.deep.includeme).toBeTruthy();
26
+ expect(filtered.deep.excludeme).toBeFalsy();
27
+ expect(filtered.deep.deepExcludeStr).toBeFalsy();
28
+ expect(filtered.deep.deepExcludeRegex).toBeFalsy();
29
+ });
30
+ });
31
+ });
32
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":";;AAAA,mCAAiD;AAEjD,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,iBAAiB,GAAG;gBACxB,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,OAAO;gBAClB,aAAa,EAAE,KAAK;gBACpB,IAAI,EAAE;oBACJ,SAAS,EAAE,GAAG;oBACd,SAAS,EAAE,OAAO;oBAClB,cAAc,EAAE,KAAK;oBACrB,gBAAgB,EAAE,KAAK;iBACxB;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAA,8BAAsB,EAAC,iBAAiB,EAAE;gBACzD,sBAAsB,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,CAAC;aAClG,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;YAE3C,OAAO;YACP,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,CAAC;YACjD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@crimson-education/browser-logger",
3
- "version": "2.0.2-cognito.2",
3
+ "version": "3.0.0",
4
4
  "description": "An abstract logger and reporting utility for browser environments",
5
5
  "scripts": {
6
6
  "prepack": "npm run build",
7
7
  "clean": "rimraf lib",
8
8
  "prebuild": "npm run clean",
9
9
  "build": "tsc",
10
+ "ts-check": "tsc --noEmit",
10
11
  "lint": "eslint src",
11
12
  "fixlint": "npm run lint -- --fix",
12
- "test": "jest --config jest.config.js --passWithNoTests"
13
+ "test": "jest --config jest.config.js"
13
14
  },
14
15
  "repository": {
15
16
  "type": "git",
@@ -28,8 +29,8 @@
28
29
  "homepage": "https://github.com/crimson-education/browser-logger#readme",
29
30
  "dependencies": {
30
31
  "@aws-amplify/analytics": "^5.2.22",
31
- "@datadog/browser-logs": "^4.4.0",
32
- "@datadog/browser-rum": "^4.4.0"
32
+ "@datadog/browser-logs": "^4.21.0",
33
+ "@datadog/browser-rum": "^4.21.0"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@crimson-education/eslint-config": "^2.1.0",
package/src/index.ts CHANGED
@@ -1,143 +1,64 @@
1
- import { ILogger, Metadata, ReportError, ReportUser, ServiceInfo } from './types';
2
- import { IReporter, ReporterBreadcrumb, ReporterEvent, TrackedReporterEvent } from './reporters';
3
- import { consoleLogger } from './utils';
4
- import { datadogLogger, datadogReporter, DatadogReporterConfig } from './reporters/datadogReporter';
1
+ import { ReporterConfigurations, ServiceInfo } from './types';
2
+ import { setLogLevel } from './logger';
3
+ import { addMetadata, reporters, setEventLevel } from './reporters';
5
4
  import { gtmReporter } from './reporters/gtmReporter';
6
- import { amplifyReporter, AmplifyReporterConfig } from './reporters/amplifyReporter';
5
+ import { amplifyReporter } from './reporters/amplifyReporter';
6
+ import { datadogReporter } from './reporters/datadogReporter';
7
+ import { logReporter } from './reporters/logReporter';
7
8
 
8
9
  export * from './types';
10
+ export * from './reporters';
11
+ export * from './logger';
9
12
 
10
- export let logger: ILogger | null = null;
13
+ export type LoggerConfig = ServiceInfo & { reporters?: ReporterConfigurations };
11
14
 
12
- export type ReporterConfig = ServiceInfo & {
13
- // Datadog
14
- datadog?: DatadogReporterConfig;
15
-
16
- // Amplify/Pinpoint
17
- amplify?: AmplifyReporterConfig;
18
-
19
- // Google Tag Manager
20
- gtm?: boolean;
21
- };
22
-
23
- const reporters: IReporter[] = [];
24
15
  let initialized = false;
25
- let ddInitialized = false;
26
-
27
- export function init(config: ReporterConfig) {
28
- initialized = true;
29
16
 
30
- if (config.datadog) {
31
- reporters.push(datadogReporter(config, config.datadog));
32
- ddInitialized = true;
17
+ /**
18
+ * Initializes the logger and reporters.
19
+ * @param config Reporter config options.
20
+ */
21
+ export function init(config: LoggerConfig) {
22
+ // Some reporters don't like being initialized multiple times.
23
+ if (initialized) {
24
+ return;
33
25
  }
26
+ initialized = true;
34
27
 
35
- if (config.amplify) {
36
- reporters.push(amplifyReporter(config, config.amplify));
37
- }
38
-
39
- if (config.gtm) {
40
- reporters.push(gtmReporter());
41
- }
42
-
43
- if (config.defaultMetadata) {
44
- for (const reporter of reporters) {
45
- reporter.addMetadata(config.defaultMetadata);
46
- }
47
- }
48
-
49
- logger = createLogger('Reporter');
50
- }
51
-
52
- export function trackEvent(event: ReporterEvent): void {
53
- for (const reporter of reporters) {
54
- reporter.trackEvent(event);
55
- }
56
- }
57
-
58
- export function addBreadcrumb(breadcrumb: ReporterBreadcrumb): void {
59
- for (const reporter of reporters) {
60
- reporter.addBreadcrumb(breadcrumb);
61
- }
62
- }
63
-
64
- export function addMetadata(metadata: Metadata): void {
65
- for (const reporter of reporters) {
66
- reporter.addMetadata(metadata);
67
- }
68
- }
69
-
70
- export function setUser(user: ReportUser | null): void {
71
- for (const reporter of reporters) {
72
- reporter.setUser(user);
73
- }
74
- }
75
-
76
- export function setRouteName(routeName: string): void {
77
- for (const reporter of reporters) {
78
- reporter.setRouteName(routeName);
28
+ // Log Reporter enabled by default.
29
+ const logReporterConfig = config.reporters?.log ?? true;
30
+ if (logReporterConfig !== false) {
31
+ reporters['log'] = logReporter(config, typeof logReporterConfig === 'boolean' ? {} : logReporterConfig);
79
32
  }
80
- }
81
33
 
82
- export function setPageName(pageName: string): void {
83
- for (const reporter of reporters) {
84
- reporter.setPageName(pageName);
34
+ if (config.reporters?.datadog) {
35
+ reporters['datadog'] = datadogReporter(config, config.reporters.datadog);
85
36
  }
86
- }
87
37
 
88
- export function reportError(error: ReportError, metadata?: Metadata): void {
89
- for (const reporter of reporters) {
90
- reporter.reportError(error, metadata);
38
+ if (config.reporters?.amplify) {
39
+ reporters['amplify'] = amplifyReporter(config, config.reporters.amplify);
91
40
  }
92
- }
93
41
 
94
- export function recordSession(): void {
95
- for (const reporter of reporters) {
96
- reporter.recordSession();
42
+ if (config.reporters?.gtm) {
43
+ reporters['gtm'] = gtmReporter(config, typeof config.reporters.gtm === 'boolean' ? {} : config.reporters.gtm);
97
44
  }
98
- }
99
45
 
100
- export function recordSessionStop(): void {
101
- for (const reporter of reporters) {
102
- reporter.recordSessionStop();
103
- }
104
- }
46
+ const defaultMetadata = {
47
+ ...(config.defaultMetadata ?? {}),
48
+ service: config.service,
49
+ environment: config.environment,
50
+ version: config.version,
51
+ };
105
52
 
106
- export function trackEventSinceLastAction(event: ReporterEvent): void {
107
- const lastEvent = getLastTrackedEvent();
108
- if (lastEvent) {
109
- const duration = new Date().getTime() - lastEvent.occurred.getTime();
110
- trackEvent({
111
- ...event,
112
- metadata: {
113
- ...event.metadata,
114
- lastEventName: lastEvent.message,
115
- timeSinceLastEvent: duration,
116
- },
117
- });
118
- } else {
119
- trackEvent(event);
53
+ // Sets the global log level, if specified.
54
+ if (config.logLevel) {
55
+ setLogLevel(config.logLevel);
120
56
  }
121
- sessionStorage.setItem('loggerLastEvent', JSON.stringify({ ...event, occurred: new Date() }));
122
- }
123
57
 
124
- export function getLastTrackedEvent(): TrackedReporterEvent | null {
125
- const eventStr = sessionStorage.getItem('loggerLastEvent');
126
- if (!eventStr) return null;
127
-
128
- const event: TrackedReporterEvent = JSON.parse(eventStr);
129
- event.occurred = new Date(event.occurred);
130
- return event;
131
- }
132
-
133
- export function createLogger(name?: string, options?: { metadata?: Metadata }): ILogger {
134
- if (!initialized) {
135
- throw new Error('You must call init on BrowserLogger before creating a logger');
58
+ // Sets the global event level, if specified.
59
+ if (config.eventLevel) {
60
+ setEventLevel(config.eventLevel);
136
61
  }
137
62
 
138
- if (ddInitialized) {
139
- return datadogLogger(name, options);
140
- } else {
141
- return consoleLogger(name, options);
142
- }
63
+ addMetadata(defaultMetadata);
143
64
  }
@@ -0,0 +1,101 @@
1
+ import { ILogTransport, LogLevel, LogTransportConfigBase } from '../types';
2
+
3
+ // from browser-util-inspect
4
+ const colors = {
5
+ bold: [1, 22],
6
+ italic: [3, 23],
7
+ underline: [4, 24],
8
+ inverse: [7, 27],
9
+ white: [37, 39],
10
+ grey: [90, 39],
11
+ black: [30, 39],
12
+ blue: [34, 39],
13
+ cyan: [36, 39],
14
+ green: [32, 39],
15
+ magenta: [35, 39],
16
+ red: [31, 39],
17
+ yellow: [33, 39],
18
+ };
19
+ export type ColorizeColor = keyof typeof colors;
20
+
21
+ /**
22
+ * Colorize a string with a specified color.
23
+ * @param str String to colorize
24
+ * @param color Color to colorize the string with
25
+ * @returns Colorized string
26
+ */
27
+ export function colorize(str: string, color: ColorizeColor) {
28
+ const colorData = colors[color];
29
+ return '\u001b[' + colorData[0] + 'm' + str + '\u001b[' + colorData[1] + 'm';
30
+ }
31
+
32
+ /**
33
+ * Gets a stack trace from metadata or accompanying error.
34
+ */
35
+ function getStackTrace(data: any) {
36
+ const stack = data?.err?.stack || data.stack || data['error.stack'];
37
+ delete data.stack;
38
+ return stack ?? '';
39
+ }
40
+
41
+ export interface ConsoleLogTransportConfig extends LogTransportConfigBase {
42
+ /**
43
+ * Add colors to log messages.
44
+ */
45
+ colorize?: false | typeof colorize;
46
+
47
+ /**
48
+ * Gets the color for the log level.
49
+ */
50
+ getLogLevelColor?: (level: LogLevel) => ColorizeColor;
51
+ }
52
+
53
+ export function consoleTransport(config: ConsoleLogTransportConfig = {}) {
54
+ // Default ignore patterns
55
+ config.ignoreMetadataPatterns ??= ['application', 'service', 'environment', 'version'];
56
+
57
+ // Get the colorizer function, or a no-op if not enabled.
58
+ const colorizer = config.colorize !== false ? config.colorize ?? colorize : (str: string) => str;
59
+
60
+ // Get the log level color function, or use the default colors.
61
+ const getLogLevelColor =
62
+ config.getLogLevelColor ??
63
+ ((level) => {
64
+ return {
65
+ error: 'red',
66
+ warn: 'yellow',
67
+ info: 'cyan',
68
+ debug: 'green',
69
+ }[level] as ColorizeColor;
70
+ });
71
+
72
+ const transport: ILogTransport & ConsoleLogTransportConfig = {
73
+ ...config,
74
+ log: ({ level, message, timestamp, splat, ...metadata }) => {
75
+ let splatData = splat ?? [];
76
+ const stackTrace = getStackTrace(metadata);
77
+
78
+ const strippedInfo: any = { ...metadata };
79
+ delete strippedInfo['level'];
80
+ delete strippedInfo['message'];
81
+ delete strippedInfo['splat'];
82
+ delete strippedInfo['timestamp'];
83
+ delete strippedInfo['stack'];
84
+
85
+ if (Object.keys(strippedInfo).length > 0) {
86
+ splatData = [strippedInfo, ...splatData];
87
+ }
88
+
89
+ if (message) {
90
+ splatData = [message, ...splatData];
91
+ }
92
+
93
+ if (stackTrace) {
94
+ splatData = [...splatData, stackTrace];
95
+ }
96
+
97
+ console.log(`${colorizer(timestamp, 'magenta')} ${colorizer(level, getLogLevelColor(level))}: `, ...splatData);
98
+ },
99
+ };
100
+ return transport;
101
+ }
@@ -0,0 +1,20 @@
1
+ import { ILogTransport, LogTransportConfigBase } from '../types';
2
+ import { getLogMessage } from './utils';
3
+ import { datadogLogs } from '@datadog/browser-logs';
4
+
5
+ export type DatadogLogTransportConfig = LogTransportConfigBase;
6
+
7
+ /**
8
+ * A transport that sends logs to Datadog.
9
+ * Note: This requires the datadog reporter to be initialized for it to work.
10
+ */
11
+ export function datadogTransport(config: DatadogLogTransportConfig = {}) {
12
+ const transport: ILogTransport = {
13
+ ...config,
14
+ log: ({ level, message, ...metadata }) => {
15
+ // Datadog expects a string message.
16
+ datadogLogs.logger[level](getLogMessage(message), metadata);
17
+ },
18
+ };
19
+ return transport;
20
+ }
@@ -0,0 +1,68 @@
1
+ import { createLogger, setLogLevel as setGlobalLogLevel, logTransports, consoleTransport } from '.';
2
+ import { init } from '..';
3
+ import { addMetadata, setUser } from '../reporters';
4
+ import { LogLevel } from '../types';
5
+
6
+ // This isn't actually asserting anything.
7
+ // But it ensures that the logs look correct, and no errors get thrown.
8
+ describe('logger', () => {
9
+ const logger = createLogger({
10
+ metadata: {
11
+ service: 'test',
12
+ },
13
+ });
14
+
15
+ // Manually set the log transports.
16
+ logTransports.length = 0;
17
+ const transport = consoleTransport({
18
+ // So we can see everything.
19
+ ignoreMetadataPatterns: [],
20
+ });
21
+ logTransports.push(transport);
22
+
23
+ it('should log', async () => {
24
+ logger.log({
25
+ level: 'info',
26
+ message: 'data',
27
+ });
28
+ logger.log({ data: 'obj' });
29
+ logger.log(LogLevel.Debug, 'level, message', { data: 'obj' });
30
+ logger.log(LogLevel.Debug, 'level, message, metadata', { data: 'obj' });
31
+
32
+ init({
33
+ service: 'test-service',
34
+ environment: 'test',
35
+ version: 'no-version',
36
+ defaultMetadata: {
37
+ application: 'test',
38
+ },
39
+ });
40
+
41
+ const infoLogger = logger.child({ isLevel: 'info' });
42
+ infoLogger.info('info call, message');
43
+ infoLogger.info('info call, message, metadata', { data: 'metadataobj' });
44
+
45
+ const timer = logger.startTimer();
46
+ await new Promise((resolve) => setTimeout(resolve, 1000));
47
+ timer.done({ message: 'timer done', metadata: { id: 1 } });
48
+
49
+ setGlobalLogLevel(LogLevel.Info);
50
+ addMetadata({ global: 'metadata' });
51
+
52
+ logger.debug('You should not see this');
53
+ logger.info('You should see this with { global: "metadata" }');
54
+
55
+ setGlobalLogLevel(null);
56
+ setUser({
57
+ id: '123',
58
+ email: 'test@example.com',
59
+ });
60
+
61
+ logger.debug('debug call, user metadata');
62
+
63
+ transport.logLevel = LogLevel.Info;
64
+ logger.debug('You should not see this');
65
+ logger.info('You should see this');
66
+ transport.logLevel = undefined;
67
+ });
68
+ });