/ shared / logger / src / composite.ts
composite.ts
 1  import type { LoggerFactory, Logger } from './types';
 2  
 3  export class CompositeLoggerFactory implements LoggerFactory {
 4      private readonly factories: LoggerFactory[];
 5  
 6      constructor(factories: LoggerFactory[]) {
 7          this.factories = factories;
 8      }
 9  
10      loggerFor(name: string): Logger {
11          return new CompositeLogger(
12              this.factories.map((factory) => factory.loggerFor(name)),
13          );
14      }
15  }
16  
17  export class CompositeLogger implements Logger {
18      private readonly loggers: Logger[];
19  
20      constructor(loggers: Logger[]) {
21          this.loggers = loggers;
22      }
23  
24      /**
25       * Log a debug level message.
26       * Appropriate for verbose logging that explains steps/details of the inner state of
27       * a code unit.
28       *
29       * Example uses include in a size-constrain datastructure, logging when the size
30       * exceeds the threshold and elements are removed, or in a virtual scrolling
31       * component logging when a scroll event causes a new page of elements to be loaded.
32       *
33       * @param args Arguments to log (same as console.debug)
34       * @return empty string (for use in brackets {} in svelte components)
35       */
36      debug(...args: unknown[]): string {
37          return this.callAll('debug', args);
38      }
39  
40      /**
41       * Log an info level message.
42       * Appropriate for informational messages that may be relevant to consumers of a code
43       * unit.
44       *
45       * Example uses include a router logging when transitions occur or a button logging
46       * clicks.
47       *
48       * @param args Arguments to log (same as console.info)
49       * @return empty string (for use in brackets {} in svelte components)
50       */
51      info(...args: unknown[]): string {
52          return this.callAll('info', args);
53      }
54  
55      /**
56       * Log a warn level message.
57       * Appropriate for situations where state has been (or likely will be) corrupted or
58       * invariants have been broken.
59       *
60       * Example uses include a data structure warning when it is used before being fully
61       * initialized.
62       *
63       * @param args Arguments to log (same as console.warn)
64       * @return empty string (for use in brackets {} in svelte components)
65       */
66      warn(...args: unknown[]): string {
67          return this.callAll('warn', args);
68      }
69  
70      /**
71       * Log an error message.
72       * Appropriate for thrown errors or situations where the apps breaks or has to
73       * engage in fallback behavior to avoid a more catastrophic failure.
74       *
75       * @param args Arguments to log (same as console.error)
76       * @return empty string (for use in brackets {} in svelte components)
77       */
78      error(...args: unknown[]): string {
79          return this.callAll('error', args);
80      }
81  
82      private callAll(
83          method: 'debug' | 'info' | 'warn' | 'error',
84          args: unknown[],
85      ): string {
86          for (const logger of this.loggers) {
87              logger[method](...args);
88          }
89  
90          return '';
91      }
92  }