@volontariapp/logger 0.2.6 → 0.3.0-snap-271697b

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 (35) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +23 -23
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/logger.d.ts +3 -0
  8. package/dist/logger.d.ts.map +1 -1
  9. package/dist/logger.js +9 -2
  10. package/dist/logger.js.map +1 -1
  11. package/dist/masking.d.ts +21 -0
  12. package/dist/masking.d.ts.map +1 -0
  13. package/dist/masking.js +86 -0
  14. package/dist/masking.js.map +1 -0
  15. package/dist/test/core/logger-masking.unit.spec.d.ts +2 -0
  16. package/dist/test/core/logger-masking.unit.spec.d.ts.map +1 -0
  17. package/dist/test/core/logger-masking.unit.spec.js +62 -0
  18. package/dist/test/core/logger-masking.unit.spec.js.map +1 -0
  19. package/dist/test/core/masking.unit.spec.d.ts +2 -0
  20. package/dist/test/core/masking.unit.spec.d.ts.map +1 -0
  21. package/dist/test/core/masking.unit.spec.js +117 -0
  22. package/dist/test/core/masking.unit.spec.js.map +1 -0
  23. package/dist/test/core/trace-context.unit.spec.d.ts +2 -0
  24. package/dist/test/core/trace-context.unit.spec.d.ts.map +1 -0
  25. package/dist/test/core/trace-context.unit.spec.js +69 -0
  26. package/dist/test/core/trace-context.unit.spec.js.map +1 -0
  27. package/dist/test/factories/span-context.factory.d.ts +5 -0
  28. package/dist/test/factories/span-context.factory.d.ts.map +1 -0
  29. package/dist/test/factories/span-context.factory.js +10 -0
  30. package/dist/test/factories/span-context.factory.js.map +1 -0
  31. package/dist/trace-context.d.ts +7 -0
  32. package/dist/trace-context.d.ts.map +1 -0
  33. package/dist/trace-context.js +15 -0
  34. package/dist/trace-context.js.map +1 -0
  35. package/package.json +5 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Mask personal data and add trace correlation (tickets 3.0 and 3.1).
8
+
9
+ - Masking (3.0): metadata, positional params, error details and the message are masked before serialization, in JSON and text. Keys are matched by fragment, case-insensitively and ignoring `-` and `_` (`password`, `token`, `authorization`, `cookie`, `apikey`, `email`, `phone`, `iban`... so `x-internal-token` and `refresh_token` are covered), and strings are scanned for emails, JWTs and `Bearer` credentials. The walk is recursive, handles arrays, class instances, errors and circular references (`[Circular]`), and never mutates the object passed by the caller.
10
+ - Configurable: `new Logger({ masking: { keys, patterns, replacement } })` extends the defaults, `masking: false` disables it. New exports: `Masker`, `MaskingConfig`, `DEFAULT_SENSITIVE_KEYS`, `DEFAULT_SENSITIVE_PATTERNS`, `DEFAULT_REDACTION`, `CIRCULAR_REFERENCE`.
11
+ - Trace correlation (3.1): inside an active OpenTelemetry span, the JSON payload carries `trace_id` (hex), `dd.trace_id` (lower 64 bits, decimal) and `dd.span_id` (decimal). They are written after the caller metadata, which cannot override them. The text format is unchanged. New exports: `getTraceFields`, `TraceFields`. New dependency: `@opentelemetry/api` (`^1.9.0`, no SDK).
12
+
13
+ Behavior change: masking is on by default, so a consumer that logged an `email`, `phone` or `token` field will now see `[REDACTED]` once it bumps.
14
+
15
+ ## 0.2.7
16
+
17
+ ### Patch Changes
18
+
19
+ - README bump
20
+
3
21
  ## 0.2.6
4
22
 
5
23
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @volontariapp/logger
2
2
 
3
- A cross-platform logging utility that works seamlessly in NodeJS, NestJS, and React Native. It outputs beautifully structured JSON logs or colored plain text logs based on the execution environment.
3
+ Un utilitaire de log cross-platform qui fonctionne parfaitement sur NodeJS, NestJS et React Native. Il génère des logs JSON structurés ou des logs texte colorés selon l'environnement d'exécution.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,13 +8,13 @@ A cross-platform logging utility that works seamlessly in NodeJS, NestJS, and Re
8
8
  npm install @volontariapp/logger
9
9
  ```
10
10
 
11
- ## Setup & Configuration
11
+ ## Configuration & Mise en place
12
12
 
13
- This logger is highly versatile and supports different instantiation strategies depending on the platform you're targeting.
13
+ Ce logger est très polyvalent et supporte différentes stratégies d'instanciation en fonction de la plateforme ciblée.
14
14
 
15
- ### 1. NodeJS Project
15
+ ### 1. Projet NodeJS
16
16
 
17
- For a typical NodeJS application or script, you can instantiate the logger directly. We recommend using `text` format for local development and `json` format in production.
17
+ Pour une application ou un script NodeJS classique, vous pouvez instancier le logger directement. Nous recommandons d'utiliser le format `text` pour le développement local et `json` en production.
18
18
 
19
19
  ```typescript
20
20
  import { Logger } from '@volontariapp/logger';
@@ -25,22 +25,22 @@ const logger = new Logger({
25
25
  minLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
26
26
  });
27
27
 
28
- logger.info('Worker initialized successfully.');
29
- logger.error('Failed to sync data.', new Error('Connection timeout'));
28
+ logger.info('Worker initialisé avec succès.');
29
+ logger.error('Échec de synchronisation des données.', new Error('Connection timeout'));
30
30
  ```
31
31
 
32
- ### 2. NestJS Project
32
+ ### 2. Projet NestJS
33
33
 
34
- The logger adheres to NestJS's `LoggerService` interface out of the box (`log`, `error`, `warn`, `debug`, `verbose`). You can use it as a custom application-wide logger as well as via dependency injection.
34
+ Le logger respecte l'interface `LoggerService` de NestJS de manière native (`log`, `error`, `warn`, `debug`, `verbose`). Vous pouvez l'utiliser comme logger global de l'application ou via l'injection de dépendances.
35
35
 
36
- **Application Bootstrap** (`main.ts`):
36
+ **Initialisation de l'Application** (`main.ts`) :
37
37
  ```typescript
38
38
  import { NestFactory } from '@nestjs/core';
39
39
  import { AppModule } from './app.module';
40
40
  import { Logger } from '@volontariapp/logger';
41
41
 
42
42
  async function bootstrap() {
43
- // Use JSON formatting for structured logging in NestJS apps
43
+ // Utilise le format JSON pour des logs structurés dans les applications NestJS
44
44
  const appLogger = new Logger({ format: 'json', context: 'NestApplication' });
45
45
 
46
46
  const app = await NestFactory.create(AppModule, {
@@ -52,7 +52,7 @@ async function bootstrap() {
52
52
  bootstrap();
53
53
  ```
54
54
 
55
- **Dependency Injection Module** (`logger.module.ts`):
55
+ **Module d'Injection de Dépendances** (`logger.module.ts`) :
56
56
  ```typescript
57
57
  import { Module, Global } from '@nestjs/common';
58
58
  import { Logger } from '@volontariapp/logger';
@@ -72,34 +72,34 @@ const customLogger = new Logger({ format: 'json', context: 'RequestScope' });
72
72
  export class LoggerModule {}
73
73
  ```
74
74
 
75
- ### 3. React Native Project
75
+ ### 3. Projet React Native
76
76
 
77
- In React Native, it is often easier to read text logs in Metro Bundler, rather than a full JSON object. You can instantiate it locally to your specific component or as a Singleton for the entire app.
77
+ Sur React Native, il est souvent plus simple de lire des logs texte dans la console Metro Bundler plutôt qu'un objet JSON complet. Vous pouvez l'instancier localement pour un composant spécifique ou en Singleton pour toute l'application.
78
78
 
79
79
  ```typescript
80
80
  import { Logger } from '@volontariapp/logger';
81
81
 
82
82
  export const logger = new Logger({
83
83
  context: 'MobileApp',
84
- format: 'text', // Recommended for reacting native metro bundler console
84
+ format: 'text', // Recommandé pour la console metro bundler de react native
85
85
  minLevel: 'debug',
86
86
  });
87
87
 
88
- // Inside a React Component
88
+ // À l'intérieur d'un composant React
89
89
  export const HomeScreen = () => {
90
- logger.debug('HomeScreen mounted', { timestamp: Date.now() });
90
+ logger.debug('HomeScreen monté', { timestamp: Date.now() });
91
91
 
92
92
  const handlePress = () => {
93
- logger.info('Button pressed');
93
+ logger.info('Bouton cliqué');
94
94
  };
95
95
 
96
96
  return <Action handlePress={handlePress} />;
97
97
  };
98
98
  ```
99
99
 
100
- ## Features
100
+ ## Fonctionnalités
101
101
 
102
- - **JSON & Text Output**: Switch formats based on the environment (`json` for Grafana/ELK, `text` for local development).
103
- - **Log Levels**: Standard levels (`debug`, `info`, `warn`, `error`, `fatal`).
104
- - **NestJS Compatible**: `log` and `verbose` wrappers ensure NestJS interface compatibility.
105
- - **Micro-metadata**: Pass specific metadata objects simply. `logger.info('User Login', { userId: 1 })`.
102
+ - **Sortie JSON & Texte** : Changez de format selon l'environnement (`json` pour Grafana/ELK, `text` pour le dev local).
103
+ - **Niveaux de Log** : Niveaux standards (`debug`, `info`, `warn`, `error`, `fatal`).
104
+ - **Compatible NestJS** : Les méthodes `log` et `verbose` garantissent la compatibilité avec l'interface NestJS.
105
+ - **Micro-metadata** : Passez facilement des objets de métadonnées. `logger.info('User Login', { userId: 1 })`.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './colors.js';
2
2
  export * from './logger.js';
3
+ export * from './masking.js';
4
+ export * from './trace-context.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './colors.js';
2
2
  export * from './logger.js';
3
+ export * from './masking.js';
4
+ export * from './trace-context.js';
3
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
package/dist/logger.d.ts CHANGED
@@ -1,13 +1,16 @@
1
1
  import type { LogLevel } from './colors.js';
2
+ import type { MaskingConfig } from './masking.js';
2
3
  export interface LoggerConfig {
3
4
  context?: string;
4
5
  format?: 'json' | 'text';
5
6
  minLevel?: LogLevel;
7
+ masking?: MaskingConfig | false;
6
8
  }
7
9
  export declare class Logger {
8
10
  private readonly context;
9
11
  private readonly format;
10
12
  private readonly minLevel;
13
+ private readonly masker;
11
14
  private readonly levels;
12
15
  constructor(config?: LoggerConfig);
13
16
  log(message: unknown, ...optionalParams: unknown[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAMrB;gBAEU,MAAM,CAAC,EAAE,YAAY;IAM1B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAIzD,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI1D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI1D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAIpE,OAAO,CAAC,KAAK;IAkDb,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,WAAW;CAoBpB"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC;CACjC;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAE5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAMrB;gBAEU,MAAM,CAAC,EAAE,YAAY;IAO1B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAIzD,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI1D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI1D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3D,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI;IAIpE,OAAO,CAAC,KAAK;IAqDb,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,WAAW;CAoBpB"}
package/dist/logger.js CHANGED
@@ -1,8 +1,11 @@
1
1
  import { Colors, getLevelColor } from './colors.js';
2
+ import { Masker } from './masking.js';
3
+ import { getTraceFields } from './trace-context.js';
2
4
  export class Logger {
3
5
  context;
4
6
  format;
5
7
  minLevel;
8
+ masker;
6
9
  levels = {
7
10
  debug: 0,
8
11
  info: 1,
@@ -14,6 +17,7 @@ export class Logger {
14
17
  this.context = config?.context ?? 'App';
15
18
  this.format = config?.format ?? 'text';
16
19
  this.minLevel = config?.minLevel ?? 'debug';
20
+ this.masker = config?.masking === false ? undefined : new Masker(config?.masking);
17
21
  }
18
22
  log(message, ...optionalParams) {
19
23
  this.info(message, ...optionalParams);
@@ -47,8 +51,10 @@ export class Logger {
47
51
  contextOverride = params[params.length - 1];
48
52
  optionalArgs = params.slice(0, params.length - 1);
49
53
  }
50
- const parsedMessage = typeof message === 'string' ? message : this.stringifyUnknown(message);
51
- const meta = this.parseParams(optionalArgs);
54
+ const rawMessage = typeof message === 'string' ? message : this.stringifyUnknown(message);
55
+ const parsedMessage = this.masker?.maskString(rawMessage) ?? rawMessage;
56
+ const rawMeta = this.parseParams(optionalArgs);
57
+ const meta = this.masker?.maskRecord(rawMeta) ?? rawMeta;
52
58
  const logMethod = level === 'error' || level === 'fatal' ? 'error' : level === 'warn' ? 'warn' : 'log';
53
59
  if (this.format === 'json') {
54
60
  const payload = {
@@ -57,6 +63,7 @@ export class Logger {
57
63
  context: contextOverride,
58
64
  message: parsedMessage,
59
65
  ...meta,
66
+ ...getTraceFields(),
60
67
  };
61
68
  console[logMethod](JSON.stringify(payload));
62
69
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export declare const DEFAULT_REDACTION = "[REDACTED]";
2
+ export declare const CIRCULAR_REFERENCE = "[Circular]";
3
+ export declare const DEFAULT_SENSITIVE_KEYS: readonly string[];
4
+ export declare const DEFAULT_SENSITIVE_PATTERNS: readonly RegExp[];
5
+ export interface MaskingConfig {
6
+ keys?: readonly string[];
7
+ patterns?: readonly RegExp[];
8
+ replacement?: string;
9
+ }
10
+ export declare class Masker {
11
+ private readonly keys;
12
+ private readonly patterns;
13
+ private readonly replacement;
14
+ constructor(config?: MaskingConfig);
15
+ maskString(value: string): string;
16
+ mask(value: unknown): unknown;
17
+ maskRecord(value: Record<string, unknown>): Record<string, unknown>;
18
+ private isSensitiveKey;
19
+ private visit;
20
+ }
21
+ //# sourceMappingURL=masking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masking.d.ts","sourceRoot":"","sources":["../src/masking.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAC9C,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAkBnD,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAIvD,CAAC;AAEF,MAAM,WAAW,aAAa;IAE5B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEzB,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,CAAC,EAAE,aAAa;IAU3B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAQjC,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAI7B,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI1E,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,KAAK;CAiCd"}
@@ -0,0 +1,86 @@
1
+ export const DEFAULT_REDACTION = '[REDACTED]';
2
+ export const CIRCULAR_REFERENCE = '[Circular]';
3
+ export const DEFAULT_SENSITIVE_KEYS = [
4
+ 'password',
5
+ 'passwd',
6
+ 'secret',
7
+ 'token',
8
+ 'authorization',
9
+ 'cookie',
10
+ 'apikey',
11
+ 'privatekey',
12
+ 'email',
13
+ 'phone',
14
+ 'firstname',
15
+ 'lastname',
16
+ 'birthdate',
17
+ 'iban',
18
+ 'creditcard',
19
+ 'cardnumber',
20
+ 'cvv',
21
+ ];
22
+ export const DEFAULT_SENSITIVE_PATTERNS = [
23
+ /[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}/g,
24
+ /eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*/g,
25
+ /Bearer\s+[A-Za-z0-9._~+/=-]+/gi,
26
+ ];
27
+ const normalizeKey = (key) => key.toLowerCase().replace(/[-_\s]/g, '');
28
+ const withGlobalFlag = (pattern) => pattern.global ? pattern : new RegExp(pattern.source, `${pattern.flags}g`);
29
+ export class Masker {
30
+ keys;
31
+ patterns;
32
+ replacement;
33
+ constructor(config) {
34
+ this.keys = [...DEFAULT_SENSITIVE_KEYS, ...(config?.keys ?? [])]
35
+ .map(normalizeKey)
36
+ .filter((key) => key.length > 0);
37
+ this.patterns = [...DEFAULT_SENSITIVE_PATTERNS, ...(config?.patterns ?? [])].map(withGlobalFlag);
38
+ this.replacement = config?.replacement ?? DEFAULT_REDACTION;
39
+ }
40
+ maskString(value) {
41
+ return this.patterns.reduce((masked, pattern) => masked.replace(pattern, this.replacement), value);
42
+ }
43
+ mask(value) {
44
+ return this.visit(value, new WeakSet());
45
+ }
46
+ maskRecord(value) {
47
+ return this.visit(value, new WeakSet());
48
+ }
49
+ isSensitiveKey(key) {
50
+ const normalized = normalizeKey(key);
51
+ return this.keys.some((fragment) => normalized.includes(fragment));
52
+ }
53
+ visit(value, ancestors) {
54
+ if (typeof value === 'string') {
55
+ return this.maskString(value);
56
+ }
57
+ if (typeof value !== 'object' || value === null || value instanceof Date) {
58
+ return value;
59
+ }
60
+ if (ancestors.has(value)) {
61
+ return CIRCULAR_REFERENCE;
62
+ }
63
+ ancestors.add(value);
64
+ try {
65
+ if (Array.isArray(value)) {
66
+ return value.map((item) => this.visit(item, ancestors));
67
+ }
68
+ if (value instanceof Error) {
69
+ return {
70
+ name: value.name,
71
+ message: this.maskString(value.message),
72
+ stack: value.stack === undefined ? undefined : this.maskString(value.stack),
73
+ };
74
+ }
75
+ const masked = {};
76
+ for (const [key, child] of Object.entries(value)) {
77
+ masked[key] = this.isSensitiveKey(key) ? this.replacement : this.visit(child, ancestors);
78
+ }
79
+ return masked;
80
+ }
81
+ finally {
82
+ ancestors.delete(value);
83
+ }
84
+ }
85
+ }
86
+ //# sourceMappingURL=masking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masking.js","sourceRoot":"","sources":["../src/masking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logger-masking.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-masking.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/core/logger-masking.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { jest, describe, it, expect, beforeEach, afterEach } from '@jest/globals';
2
+ import { Logger } from '../../logger.js';
3
+ import { DEFAULT_REDACTION } from '../../masking.js';
4
+ describe('Logger masking', () => {
5
+ let consoleLogSpy;
6
+ let consoleErrorSpy;
7
+ beforeEach(() => {
8
+ consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
9
+ consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
10
+ });
11
+ afterEach(() => {
12
+ jest.restoreAllMocks();
13
+ });
14
+ const lastOutput = () => consoleLogSpy.mock.calls[0][0];
15
+ it('should mask metadata in json format', () => {
16
+ const logger = new Logger({ format: 'json' });
17
+ logger.info('Login', { email: 'jane@example.com', password: 'hunter2', userId: 7 });
18
+ const payload = JSON.parse(lastOutput());
19
+ expect(payload).toMatchObject({
20
+ email: DEFAULT_REDACTION,
21
+ password: DEFAULT_REDACTION,
22
+ userId: 7,
23
+ });
24
+ expect(lastOutput()).not.toContain('hunter2');
25
+ expect(lastOutput()).not.toContain('jane@example.com');
26
+ });
27
+ it('should mask metadata in text format', () => {
28
+ const logger = new Logger({ format: 'text' });
29
+ logger.info('Login', { nested: { token: 'abc123' } });
30
+ expect(lastOutput()).toContain(DEFAULT_REDACTION);
31
+ expect(lastOutput()).not.toContain('abc123');
32
+ });
33
+ it('should mask patterns inside the message and error details', () => {
34
+ const logger = new Logger({ format: 'json' });
35
+ logger.error('Failed for jane@example.com', new Error('boom jane@example.com'));
36
+ const output = consoleErrorSpy.mock.calls[0][0];
37
+ expect(output).toContain(DEFAULT_REDACTION);
38
+ expect(output).not.toContain('jane@example.com');
39
+ });
40
+ it('should mask positional params', () => {
41
+ const logger = new Logger({ format: 'json' });
42
+ logger.info('Params', 'a@b.io', 3);
43
+ expect(lastOutput()).not.toContain('a@b.io');
44
+ });
45
+ it('should not mutate the metadata passed by the caller', () => {
46
+ const logger = new Logger({ format: 'json' });
47
+ const meta = { password: 'hunter2' };
48
+ logger.info('Login', meta);
49
+ expect(meta.password).toBe('hunter2');
50
+ });
51
+ it('should apply the configured keys and replacement', () => {
52
+ const logger = new Logger({ format: 'json', masking: { keys: ['ssn'], replacement: '***' } });
53
+ logger.info('Profile', { ssn: '123', password: 'x' });
54
+ expect(JSON.parse(lastOutput())).toMatchObject({ ssn: '***', password: '***' });
55
+ });
56
+ it('should let masking be disabled explicitly', () => {
57
+ const logger = new Logger({ format: 'json', masking: false });
58
+ logger.info('Login', { password: 'hunter2' });
59
+ expect(JSON.parse(lastOutput())).toMatchObject({ password: 'hunter2' });
60
+ });
61
+ });
62
+ //# sourceMappingURL=logger-masking.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-masking.unit.spec.js","sourceRoot":"","sources":["../../../src/test/core/logger-masking.unit.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=masking.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masking.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/core/masking.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,117 @@
1
+ import { describe, it, expect } from '@jest/globals';
2
+ import { CIRCULAR_REFERENCE, DEFAULT_REDACTION, Masker } from '../../masking.js';
3
+ const JWT = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U';
4
+ describe('Masker', () => {
5
+ describe('keys', () => {
6
+ it('should mask sensitive keys whatever their casing or separators', () => {
7
+ const masked = new Masker().mask({
8
+ password: 'hunter2',
9
+ 'x-internal-token': 'abc',
10
+ Authorization: 'Bearer abc',
11
+ refresh_token: 'def',
12
+ userEmail: 'jane@example.com',
13
+ phoneNumber: '0612345678',
14
+ });
15
+ expect(masked).toEqual({
16
+ password: DEFAULT_REDACTION,
17
+ 'x-internal-token': DEFAULT_REDACTION,
18
+ Authorization: DEFAULT_REDACTION,
19
+ refresh_token: DEFAULT_REDACTION,
20
+ userEmail: DEFAULT_REDACTION,
21
+ phoneNumber: DEFAULT_REDACTION,
22
+ });
23
+ });
24
+ it('should keep non sensitive keys untouched', () => {
25
+ const input = { port: 3000, host: 'localhost', ok: true, nothing: null };
26
+ expect(new Masker().mask(input)).toEqual(input);
27
+ });
28
+ it('should accept extra keys and a custom replacement', () => {
29
+ const masker = new Masker({ keys: ['ssn'], replacement: '***' });
30
+ expect(masker.mask({ SSN: '123', password: 'x' })).toEqual({ SSN: '***', password: '***' });
31
+ });
32
+ });
33
+ describe('patterns', () => {
34
+ it('should mask emails and JWTs found inside strings', () => {
35
+ const masked = new Masker().maskString(`user jane.doe+tag@example.co.uk sent ${JWT}`);
36
+ expect(masked).toBe(`user ${DEFAULT_REDACTION} sent ${DEFAULT_REDACTION}`);
37
+ });
38
+ it('should mask bearer credentials', () => {
39
+ expect(new Masker().maskString('header Bearer abc.def-123')).toBe(`header ${DEFAULT_REDACTION}`);
40
+ });
41
+ it('should accept extra patterns, even without the global flag', () => {
42
+ const masker = new Masker({ patterns: [/\d{4}-\d{4}/] });
43
+ expect(masker.maskString('a 1234-5678 b 8765-4321')).toBe(`a ${DEFAULT_REDACTION} b ${DEFAULT_REDACTION}`);
44
+ });
45
+ it('should be stable across repeated calls', () => {
46
+ const masker = new Masker();
47
+ expect(masker.maskString('a@b.io')).toBe(DEFAULT_REDACTION);
48
+ expect(masker.maskString('a@b.io')).toBe(DEFAULT_REDACTION);
49
+ });
50
+ });
51
+ describe('nested structures', () => {
52
+ it('should mask recursively in objects and arrays', () => {
53
+ const masked = new Masker().mask({
54
+ request: {
55
+ headers: { authorization: 'secret-value', accept: 'json' },
56
+ users: [
57
+ { id: 1, email: 'a@b.io' },
58
+ { id: 2, note: 'contact c@d.io' },
59
+ ],
60
+ },
61
+ });
62
+ expect(masked).toEqual({
63
+ request: {
64
+ headers: { authorization: DEFAULT_REDACTION, accept: 'json' },
65
+ users: [
66
+ { id: 1, email: DEFAULT_REDACTION },
67
+ { id: 2, note: `contact ${DEFAULT_REDACTION}` },
68
+ ],
69
+ },
70
+ });
71
+ });
72
+ it('should not mutate the original object', () => {
73
+ const input = { password: 'hunter2', nested: { token: 'abc' }, list: ['a@b.io'] };
74
+ const snapshot = JSON.stringify(input);
75
+ new Masker().mask(input);
76
+ expect(JSON.stringify(input)).toBe(snapshot);
77
+ });
78
+ it('should mask class instances', () => {
79
+ class UserDto {
80
+ id;
81
+ email;
82
+ constructor(id, email) {
83
+ this.id = id;
84
+ this.email = email;
85
+ }
86
+ }
87
+ expect(new Masker().mask(new UserDto(1, 'a@b.io'))).toEqual({
88
+ id: 1,
89
+ email: DEFAULT_REDACTION,
90
+ });
91
+ });
92
+ it('should mask errors and keep their shape', () => {
93
+ const error = new Error('failed for a@b.io');
94
+ const masked = new Masker().mask(error);
95
+ expect(masked.name).toBe('Error');
96
+ expect(masked.message).toBe(`failed for ${DEFAULT_REDACTION}`);
97
+ });
98
+ it('should keep dates and primitives', () => {
99
+ const date = new Date('2026-10-07T00:00:00.000Z');
100
+ expect(new Masker().mask({ date, count: 3, flag: false })).toEqual({
101
+ date,
102
+ count: 3,
103
+ flag: false,
104
+ });
105
+ });
106
+ it('should survive circular references', () => {
107
+ const input = { id: 1 };
108
+ input.self = input;
109
+ expect(new Masker().mask(input)).toEqual({ id: 1, self: CIRCULAR_REFERENCE });
110
+ });
111
+ it('should not flag a shared reference as circular', () => {
112
+ const shared = { id: 1 };
113
+ expect(new Masker().mask({ a: shared, b: shared })).toEqual({ a: shared, b: shared });
114
+ });
115
+ });
116
+ });
117
+ //# sourceMappingURL=masking.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masking.unit.spec.js","sourceRoot":"","sources":["../../../src/test/core/masking.unit.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=trace-context.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/core/trace-context.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { jest, describe, it, expect, beforeEach, afterEach } from '@jest/globals';
2
+ import { trace } from '@opentelemetry/api';
3
+ import { Logger } from '../../logger.js';
4
+ import { getTraceFields } from '../../trace-context.js';
5
+ import { SPAN_ID_HEX, TRACE_ID_HEX, createSpanContext } from '../factories/span-context.factory.js';
6
+ const DD_TRACE_ID = '9532127138774266268';
7
+ const DD_SPAN_ID = '13235353014750950193';
8
+ describe('Trace correlation', () => {
9
+ let consoleLogSpy;
10
+ beforeEach(() => {
11
+ consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
12
+ });
13
+ afterEach(() => {
14
+ jest.restoreAllMocks();
15
+ });
16
+ const activateSpan = (overrides) => {
17
+ jest
18
+ .spyOn(trace, 'getActiveSpan')
19
+ .mockReturnValue(trace.wrapSpanContext(createSpanContext(overrides)));
20
+ };
21
+ describe('getTraceFields', () => {
22
+ it('should return undefined without an active span', () => {
23
+ expect(getTraceFields()).toBeUndefined();
24
+ });
25
+ it('should convert the ids to the Datadog decimal format', () => {
26
+ activateSpan();
27
+ expect(getTraceFields()).toEqual({
28
+ trace_id: TRACE_ID_HEX,
29
+ 'dd.trace_id': DD_TRACE_ID,
30
+ 'dd.span_id': DD_SPAN_ID,
31
+ });
32
+ });
33
+ it('should ignore an invalid span context', () => {
34
+ activateSpan({ traceId: '0'.repeat(32), spanId: '0'.repeat(16) });
35
+ expect(getTraceFields()).toBeUndefined();
36
+ });
37
+ });
38
+ describe('Logger json output', () => {
39
+ const lastPayload = () => JSON.parse(consoleLogSpy.mock.calls[0][0]);
40
+ it('should add the trace fields inside an active span', () => {
41
+ activateSpan();
42
+ new Logger({ format: 'json' }).info('inside span');
43
+ expect(lastPayload()).toMatchObject({
44
+ message: 'inside span',
45
+ trace_id: TRACE_ID_HEX,
46
+ 'dd.trace_id': DD_TRACE_ID,
47
+ 'dd.span_id': DD_SPAN_ID,
48
+ });
49
+ });
50
+ it('should not add the trace fields outside a span', () => {
51
+ new Logger({ format: 'json' }).info('outside span');
52
+ const payload = lastPayload();
53
+ expect(payload).not.toHaveProperty('trace_id');
54
+ expect(payload).not.toHaveProperty('dd.trace_id');
55
+ expect(payload).not.toHaveProperty('dd.span_id');
56
+ });
57
+ it('should not let caller metadata override the trace fields', () => {
58
+ activateSpan();
59
+ new Logger({ format: 'json' }).info('spoof', { 'dd.trace_id': '1' });
60
+ expect(lastPayload()['dd.trace_id']).toBe(DD_TRACE_ID);
61
+ });
62
+ it('should leave the text format untouched', () => {
63
+ activateSpan();
64
+ new Logger({ format: 'text' }).info('text');
65
+ expect(consoleLogSpy.mock.calls[0][0]).not.toContain(SPAN_ID_HEX);
66
+ });
67
+ });
68
+ });
69
+ //# sourceMappingURL=trace-context.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.unit.spec.js","sourceRoot":"","sources":["../../../src/test/core/trace-context.unit.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { SpanContext } from '@opentelemetry/api';
2
+ export declare const TRACE_ID_HEX = "0af7651916cd43dd8448eb211c80319c";
3
+ export declare const SPAN_ID_HEX = "b7ad6b7169203331";
4
+ export declare const createSpanContext: (overrides?: Partial<SpanContext>) => SpanContext;
5
+ //# sourceMappingURL=span-context.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-context.factory.d.ts","sourceRoot":"","sources":["../../../src/test/factories/span-context.factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,eAAO,MAAM,YAAY,qCAAqC,CAAC;AAC/D,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,eAAO,MAAM,iBAAiB,eAAe,OAAO,CAAC,WAAW,CAAC,KAAQ,WAKvE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { TraceFlags } from '@opentelemetry/api';
2
+ export const TRACE_ID_HEX = '0af7651916cd43dd8448eb211c80319c';
3
+ export const SPAN_ID_HEX = 'b7ad6b7169203331';
4
+ export const createSpanContext = (overrides = {}) => ({
5
+ traceId: TRACE_ID_HEX,
6
+ spanId: SPAN_ID_HEX,
7
+ traceFlags: TraceFlags.SAMPLED,
8
+ ...overrides,
9
+ });
10
+ //# sourceMappingURL=span-context.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-context.factory.js","sourceRoot":"","sources":["../../../src/test/factories/span-context.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,MAAM,CAAC,MAAM,YAAY,GAAG,kCAAkC,CAAC;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,YAAkC,EAAE,EAAe,EAAE,CAAC,CAAC;IACvF,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,UAAU,EAAE,UAAU,CAAC,OAAO;IAC9B,GAAG,SAAS;CACb,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface TraceFields {
2
+ trace_id: string;
3
+ 'dd.trace_id': string;
4
+ 'dd.span_id': string;
5
+ }
6
+ export declare function getTraceFields(): TraceFields | undefined;
7
+ //# sourceMappingURL=trace-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.d.ts","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAQD,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAYxD"}
@@ -0,0 +1,15 @@
1
+ import { trace } from '@opentelemetry/api';
2
+ const DATADOG_ID_HEX_LENGTH = 16;
3
+ const toDatadogId = (hex) => BigInt(`0x${hex.slice(-DATADOG_ID_HEX_LENGTH)}`).toString();
4
+ export function getTraceFields() {
5
+ const spanContext = trace.getActiveSpan()?.spanContext();
6
+ if (spanContext === undefined || !trace.isSpanContextValid(spanContext)) {
7
+ return undefined;
8
+ }
9
+ return {
10
+ trace_id: spanContext.traceId,
11
+ 'dd.trace_id': toDatadogId(spanContext.traceId),
12
+ 'dd.span_id': toDatadogId(spanContext.spanId),
13
+ };
14
+ }
15
+ //# sourceMappingURL=trace-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.js","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQ3C,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAGjC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAC1C,MAAM,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAE9D,MAAM,UAAU,cAAc;IAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,EAAE,EAAE,WAAW,EAAE,CAAC;IAEzD,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,WAAW,CAAC,OAAO;QAC7B,aAAa,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC;QAC/C,YAAY,EAAE,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC;KAC9C,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volontariapp/logger",
3
- "version": "0.2.6",
3
+ "version": "0.3.0-snap-271697b",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -33,11 +33,14 @@
33
33
  "test": "node --experimental-vm-modules $(yarn bin jest)",
34
34
  "test:coverage": "node --experimental-vm-modules $(yarn bin jest) --coverage --coverageReporters=\"text\" --coverageReporters=\"json-summary\" --coverageReporters=\"lcov\""
35
35
  },
36
+ "dependencies": {
37
+ "@opentelemetry/api": "^1.9.0"
38
+ },
36
39
  "devDependencies": {
37
40
  "@jest/globals": "^30.3.0",
38
41
  "@types/jest": "^30.0.0",
39
42
  "@types/node": "^25.5.2",
40
- "@volontariapp/testing": "1.0.2",
43
+ "@volontariapp/testing": "1.0.3",
41
44
  "jest": "^30.3.0",
42
45
  "ts-jest": "^29.4.9",
43
46
  "typescript": "5.7.3"