@theshelf/logging 0.1.0 → 0.2.1

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 CHANGED
@@ -9,36 +9,72 @@ The logging package provides a universal interaction layer with an actual loggin
9
9
  npm install @theshelf/logging
10
10
  ```
11
11
 
12
- ## Implementations
12
+ ## Drivers
13
13
 
14
- Currently, there are two implementations:
14
+ Currently, there are three drivers available:
15
15
 
16
- * **Void** - dummy implementation that doesn't log anything (suited for testing).
17
- * **Console** - implementation based on the Node.js console.
16
+ * **Void** - dummy driver that doesn't log anything (suited for testing).
17
+ * **Memory** - in memory logging (suited for testing).
18
+ * **Console** - driver based on the Node.js console.
19
+ * **Database** - driver that logs messages into a database.
18
20
 
19
- ## Configuration
21
+ ## How to use
22
+
23
+ The basic set up looks like this.
24
+
25
+ ```ts
26
+ import Logger, { VoidDriver | MemoryDriver | ConsoleDriver as SelectedDriver } from '@theshelf/logging';
20
27
 
21
- The used implementation needs to be configured in the `.env` file with the debug enabled setting.
28
+ const driver = new SelectedDriver(/* configuration */);
29
+ const logger = new Logger(driver);
22
30
 
23
- ```env
24
- LOGGING_IMPLEMENTATION="console" # (void | console)
25
- LOGGING_DEBUG_ENABLED=true
31
+ // Perform operations with the logger instance
26
32
  ```
27
33
 
28
- ## How to use
34
+ ### Configuration
29
35
 
30
- An instance of the configured logger implementation can be imported for performing logging operations.
36
+ #### Logger
37
+
38
+ The logger has a configurable log level.
31
39
 
32
40
  ```ts
33
- import logger from '@theshelf/logging';
41
+ import { LogLevels } from '@theshelf/logging';
34
42
 
35
- // Perform operations with the logger instance
43
+ logger.logLevel = LogLevels.DEBUG; // default level
44
+ ```
45
+
46
+ Other levels are: `INFO` | `WARN` | `ERROR` | `FATAL`.
47
+
48
+ #### Void driver
49
+
50
+ No configuration options.
51
+
52
+ #### Memory driver
53
+
54
+ No configuration options.
55
+
56
+ #### Console driver
57
+
58
+ No configuration options.
59
+
60
+ #### Database driver
61
+
62
+ The database driver requires a [database](https://github.com/MaskingTechnology/theshelf/tree/main/packages/database) from @theshelf and a table name (record type) to log messages into.
63
+
64
+ ```ts
65
+ import { database } from './your-database-instance';
66
+
67
+ const recordType = 'logs';
68
+ const driver = new DatabaseDriver(database, recordType);
69
+
70
+ const logger = new Logger(driver);
36
71
  ```
37
72
 
38
73
  ### Operations
39
74
 
40
75
  ```ts
41
- import logger from '@theshelf/logging';
76
+ // Log debug
77
+ await logger.logDebug(message);
42
78
 
43
79
  // Log info
44
80
  await logger.logInfo(message);
@@ -49,8 +85,8 @@ await logger.logWarn(message);
49
85
  // Log error
50
86
  await logger.logError(message);
51
87
 
52
- // Log debug information
53
- await logger.logDebug(message);
88
+ // Log fatal
89
+ await logger.logFatal(message);
54
90
 
55
91
  // Log multiple messages (works for all levels)
56
92
  await logger.logInfo(message1, message2, ...);
package/dist/Logger.d.ts CHANGED
@@ -1,9 +1,13 @@
1
- import type { LogProcessor } from './definitions/interfaces.js';
2
- export default class Logger implements LogProcessor {
1
+ import type { LogLevel } from './definitions/constants.js';
2
+ import type { Driver } from './definitions/interfaces.js';
3
+ export default class Logger implements Driver {
3
4
  #private;
4
- constructor(processor: LogProcessor, debugEnabled?: boolean);
5
+ constructor(driver: Driver);
6
+ set logLevel(level: LogLevel);
7
+ get logLevel(): LogLevel;
8
+ logDebug(...message: unknown[]): Promise<void>;
5
9
  logInfo(...message: unknown[]): Promise<void>;
6
10
  logWarn(...message: unknown[]): Promise<void>;
7
11
  logError(...message: unknown[]): Promise<void>;
8
- logDebug(...message: unknown[]): Promise<void>;
12
+ logFatal(...message: unknown[]): Promise<void>;
9
13
  }
package/dist/Logger.js CHANGED
@@ -1,28 +1,47 @@
1
+ import { LogLevels } from './definitions/constants.js';
1
2
  export default class Logger {
2
- #processor;
3
- #debugEnabled;
4
- constructor(processor, debugEnabled = false) {
5
- this.#processor = processor;
6
- this.#debugEnabled = debugEnabled;
3
+ #driver;
4
+ #logLevel = LogLevels.DEBUG;
5
+ constructor(driver) {
6
+ this.#driver = driver;
7
+ }
8
+ set logLevel(level) {
9
+ this.#logLevel = level;
10
+ }
11
+ get logLevel() {
12
+ return this.#logLevel;
13
+ }
14
+ logDebug(...message) {
15
+ if (this.#logLevel > LogLevels.DEBUG) {
16
+ return Promise.resolve();
17
+ }
18
+ const messageString = this.#createMessage(message);
19
+ return this.#driver.logDebug(messageString);
7
20
  }
8
21
  logInfo(...message) {
22
+ if (this.#logLevel > LogLevels.INFO) {
23
+ return Promise.resolve();
24
+ }
9
25
  const messageString = this.#createMessage(message);
10
- return this.#processor.logInfo(messageString);
26
+ return this.#driver.logInfo(messageString);
11
27
  }
12
28
  logWarn(...message) {
29
+ if (this.#logLevel > LogLevels.WARN) {
30
+ return Promise.resolve();
31
+ }
13
32
  const messageString = this.#createMessage(message);
14
- return this.#processor.logWarn(messageString);
33
+ return this.#driver.logWarn(messageString);
15
34
  }
16
35
  logError(...message) {
17
- const messageString = this.#createMessage(message);
18
- return this.#processor.logError(messageString);
19
- }
20
- logDebug(...message) {
21
- if (this.#debugEnabled === false) {
36
+ if (this.#logLevel > LogLevels.ERROR) {
22
37
  return Promise.resolve();
23
38
  }
24
39
  const messageString = this.#createMessage(message);
25
- return this.#processor.logDebug(messageString);
40
+ return this.#driver.logError(messageString);
41
+ }
42
+ logFatal(...message) {
43
+ const messageString = this.#createMessage(message);
44
+ return this.#driver.logFatal(messageString);
26
45
  }
27
46
  #createMessage(message) {
28
47
  return message.map(value => this.#interpretValue(value)).join(' ');
@@ -0,0 +1,8 @@
1
+ export declare const LogLevels: {
2
+ readonly DEBUG: 0;
3
+ readonly INFO: 1;
4
+ readonly WARN: 2;
5
+ readonly ERROR: 3;
6
+ readonly FATAL: 4;
7
+ };
8
+ export type LogLevel = typeof LogLevels[keyof typeof LogLevels];
@@ -0,0 +1,7 @@
1
+ export const LogLevels = {
2
+ DEBUG: 0,
3
+ INFO: 1,
4
+ WARN: 2,
5
+ ERROR: 3,
6
+ FATAL: 4
7
+ };
@@ -1,6 +1,7 @@
1
- export interface LogProcessor {
1
+ export interface Driver {
2
+ logDebug(message: string): Promise<void>;
2
3
  logInfo(message: string): Promise<void>;
3
4
  logWarn(message: string): Promise<void>;
4
5
  logError(message: string): Promise<void>;
5
- logDebug(message: string): Promise<void>;
6
+ logFatal(message: string): Promise<void>;
6
7
  }
@@ -1,7 +1,8 @@
1
- import type { LogProcessor } from '../../definitions/interfaces.js';
2
- export default class Console implements LogProcessor {
1
+ import type { Driver } from '../definitions/interfaces.js';
2
+ export default class Console implements Driver {
3
+ logDebug(message: string): Promise<void>;
3
4
  logInfo(message: string): Promise<void>;
4
5
  logWarn(message: string): Promise<void>;
5
6
  logError(message: string): Promise<void>;
6
- logDebug(message: string): Promise<void>;
7
+ logFatal(message: string): Promise<void>;
7
8
  }
@@ -1,4 +1,8 @@
1
+ /* eslint no-console: "off" */
1
2
  export default class Console {
3
+ async logDebug(message) {
4
+ return console.debug(message);
5
+ }
2
6
  async logInfo(message) {
3
7
  return console.info(message);
4
8
  }
@@ -8,7 +12,7 @@ export default class Console {
8
12
  async logError(message) {
9
13
  return console.error(message);
10
14
  }
11
- async logDebug(message) {
12
- return console.debug(message);
15
+ async logFatal(message) {
16
+ return console.error(message);
13
17
  }
14
18
  }
@@ -0,0 +1,12 @@
1
+ import type Database from '@theshelf/database';
2
+ import type { RecordType } from '@theshelf/database';
3
+ import type { Driver } from '../definitions/interfaces.js';
4
+ export default class DatabaseDriver implements Driver {
5
+ #private;
6
+ constructor(database: Database, recordType: RecordType);
7
+ logDebug(message: string): Promise<void>;
8
+ logInfo(message: string): Promise<void>;
9
+ logWarn(message: string): Promise<void>;
10
+ logError(message: string): Promise<void>;
11
+ logFatal(message: string): Promise<void>;
12
+ }
@@ -0,0 +1,31 @@
1
+ export default class DatabaseDriver {
2
+ #database;
3
+ #recordType;
4
+ constructor(database, recordType) {
5
+ this.#recordType = recordType;
6
+ this.#database = database;
7
+ }
8
+ logDebug(message) {
9
+ return this.#logRecord('DEBUG', message);
10
+ }
11
+ logInfo(message) {
12
+ return this.#logRecord('INFO', message);
13
+ }
14
+ logWarn(message) {
15
+ return this.#logRecord('WARN', message);
16
+ }
17
+ logError(message) {
18
+ return this.#logRecord('ERROR', message);
19
+ }
20
+ logFatal(message) {
21
+ return this.#logRecord('FATAL', message);
22
+ }
23
+ async #logRecord(level, message) {
24
+ const data = {
25
+ timestamp: new Date().toISOString(),
26
+ level,
27
+ message
28
+ };
29
+ await this.#database.createRecord(this.#recordType, data);
30
+ }
31
+ }
@@ -0,0 +1,17 @@
1
+ import type { LogLevel } from '../definitions/constants.js';
2
+ import type { Driver } from '../definitions/interfaces.js';
3
+ type Log = {
4
+ level: LogLevel;
5
+ message: string;
6
+ };
7
+ export default class Memory implements Driver {
8
+ #private;
9
+ get logs(): Log[];
10
+ logDebug(message: string): Promise<void>;
11
+ logInfo(message: string): Promise<void>;
12
+ logWarn(message: string): Promise<void>;
13
+ logError(message: string): Promise<void>;
14
+ logFatal(message: string): Promise<void>;
15
+ clear(): void;
16
+ }
17
+ export {};
@@ -0,0 +1,23 @@
1
+ import { LogLevels } from '../definitions/constants.js';
2
+ export default class Memory {
3
+ #logs = [];
4
+ get logs() { return this.#logs; }
5
+ async logDebug(message) {
6
+ this.#logs.push({ level: LogLevels.DEBUG, message });
7
+ }
8
+ async logInfo(message) {
9
+ this.#logs.push({ level: LogLevels.INFO, message });
10
+ }
11
+ async logWarn(message) {
12
+ this.#logs.push({ level: LogLevels.WARN, message });
13
+ }
14
+ async logError(message) {
15
+ this.#logs.push({ level: LogLevels.ERROR, message });
16
+ }
17
+ async logFatal(message) {
18
+ this.#logs.push({ level: LogLevels.FATAL, message });
19
+ }
20
+ clear() {
21
+ this.#logs.splice(0);
22
+ }
23
+ }
@@ -1,7 +1,8 @@
1
- import type { LogProcessor } from '../../definitions/interfaces.js';
2
- export default class Void implements LogProcessor {
1
+ import type { Driver } from '../definitions/interfaces.js';
2
+ export default class Void implements Driver {
3
+ logDebug(message: string): Promise<void>;
3
4
  logInfo(message: string): Promise<void>;
4
5
  logWarn(message: string): Promise<void>;
5
6
  logError(message: string): Promise<void>;
6
- logDebug(message: string): Promise<void>;
7
+ logFatal(message: string): Promise<void>;
7
8
  }
@@ -1,18 +1,18 @@
1
+ /* eslint @typescript-eslint/no-unused-vars: "off" */
1
2
  export default class Void {
2
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3
+ logDebug(message) {
4
+ return Promise.resolve();
5
+ }
3
6
  logInfo(message) {
4
7
  return Promise.resolve();
5
8
  }
6
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
7
9
  logWarn(message) {
8
10
  return Promise.resolve();
9
11
  }
10
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
12
  logError(message) {
12
13
  return Promise.resolve();
13
14
  }
14
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
- logDebug(message) {
15
+ logFatal(message) {
16
16
  return Promise.resolve();
17
17
  }
18
18
  }
@@ -1,2 +1,3 @@
1
1
  export default class LogError extends Error {
2
+ constructor(message?: string);
2
3
  }
@@ -1,2 +1,9 @@
1
1
  export default class LogError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = this.constructor.name;
5
+ if (Error.captureStackTrace) {
6
+ Error.captureStackTrace(this, this.constructor);
7
+ }
8
+ }
2
9
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
- import Logger from './Logger.js';
2
- declare const logger: Logger;
3
- export default logger;
1
+ export * from './definitions/constants.js';
2
+ export type * from './definitions/constants.js';
3
+ export type * from './definitions/interfaces.js';
4
+ export { default as LogError } from './errors/LogError.js';
5
+ export { default as ConsoleDriver } from './drivers/Console.js';
6
+ export { default as DatabaseDriver } from './drivers/Database.js';
7
+ export { default as MemoryDriver } from './drivers/Memory.js';
8
+ export { default as VoidDriver } from './drivers/Void.js';
9
+ export { default } from './Logger.js';
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import Logger from './Logger.js';
2
- import implementation from './implementation.js';
3
- const debugEnabled = process.env.LOGGING_DEBUG_ENABLED === 'true';
4
- const logger = new Logger(implementation, debugEnabled);
5
- export default logger;
1
+ export * from './definitions/constants.js';
2
+ export { default as LogError } from './errors/LogError.js';
3
+ export { default as ConsoleDriver } from './drivers/Console.js';
4
+ export { default as DatabaseDriver } from './drivers/Database.js';
5
+ export { default as MemoryDriver } from './drivers/Memory.js';
6
+ export { default as VoidDriver } from './drivers/Void.js';
7
+ export { default } from './Logger.js';
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@theshelf/logging",
3
3
  "private": false,
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "type": "module",
6
6
  "repository": {
7
- "url": "https://github.com/MaskingTechnology/theshelf"
7
+ "url": "git+https://github.com/MaskingTechnology/theshelf.git"
8
8
  },
9
9
  "scripts": {
10
10
  "build": "tsc",
11
11
  "clean": "rimraf dist",
12
+ "test": "vitest run",
13
+ "test-coverage": "vitest run --coverage",
12
14
  "lint": "eslint",
13
15
  "review": "npm run build && npm run lint",
14
16
  "prepublishOnly": "npm run clean && npm run build"
@@ -18,5 +20,14 @@
18
20
  "dist"
19
21
  ],
20
22
  "types": "dist/index.d.ts",
21
- "exports": "./dist/index.js"
23
+ "exports": "./dist/index.js",
24
+ "peerDependencies": {
25
+ "@theshelf/database": "^0.2.1"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "@theshelf/database":
29
+ {
30
+ "optional": true
31
+ }
32
+ }
22
33
  }
@@ -1,4 +0,0 @@
1
- import LogError from './LogError.js';
2
- export default class UnknownImplementation extends LogError {
3
- constructor(name: string);
4
- }
@@ -1,6 +0,0 @@
1
- import LogError from './LogError.js';
2
- export default class UnknownImplementation extends LogError {
3
- constructor(name) {
4
- super(`Unknown logger implementation: ${name}`);
5
- }
6
- }
@@ -1,3 +0,0 @@
1
- import type { LogProcessor } from './definitions/interfaces.js';
2
- declare const _default: LogProcessor;
3
- export default _default;
@@ -1,14 +0,0 @@
1
- import UnknownImplementation from './errors/UnknownImplementation.js';
2
- import createConsole from './implementations/console/create.js';
3
- import createVoid from './implementations/void/create.js';
4
- const implementations = new Map([
5
- ['console', createConsole],
6
- ['void', createVoid]
7
- ]);
8
- const DEFAULT_LOGGING_IMPLEMENTATION = 'void';
9
- const implementationName = process.env.LOGGING_IMPLEMENTATION ?? DEFAULT_LOGGING_IMPLEMENTATION;
10
- const creator = implementations.get(implementationName.toLowerCase());
11
- if (creator === undefined) {
12
- throw new UnknownImplementation(implementationName);
13
- }
14
- export default creator();
@@ -1,2 +0,0 @@
1
- import Console from './Console.js';
2
- export default function create(): Console;
@@ -1,4 +0,0 @@
1
- import Console from './Console.js';
2
- export default function create() {
3
- return new Console();
4
- }
@@ -1,2 +0,0 @@
1
- import Void from './Void.js';
2
- export default function create(): Void;
@@ -1,4 +0,0 @@
1
- import Void from './Void.js';
2
- export default function create() {
3
- return new Void();
4
- }