@spinajs/log-common 2.0.490 → 2.0.494

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
@@ -1,132 +1,132 @@
1
- # `@spinajs/log-common`
2
-
3
- Shared, dependency-light contracts for the SpinaJS logging stack. This package
4
- holds no logging implementation of its own; it defines the abstract types that
5
- `@spinajs/log`, `@spinajs/internal-logger` and the various log-source packages
6
- implement. Depend on it when you write a **custom log target** or a **custom
7
- `Log` implementation**, and want to avoid a circular dependency on `@spinajs/log`.
8
-
9
- ## What lives here
10
-
11
- | Export | Purpose |
12
- | --- | --- |
13
- | `Log` (abstract) | The logger contract: `trace/debug/info/warn/error/fatal/security/success`, `child`, `write`, `addVariable`, `timeStart/timeEnd`. |
14
- | `LogTarget<T>` (abstract) | A sink that receives `ILogEntry` objects and writes them somewhere ( console, file, HTTP, ... ). |
15
- | `createLogMessageObject` | Builds a normalized `ILogEntry` from the many call shapes the `Log` methods accept. |
16
- | `LogLevel` / `StrToLogLevel` / `LogLevelStrings` | Level enum and string<->enum maps. |
17
- | `ILogEntry`, `ILogRule`, `ICommonTargetOptions`, `IFileTargetOptions`, `ILogOptions` | Config and payload shapes. |
18
-
19
- ## The `LogTarget` contract
20
-
21
- ```ts
22
- abstract class LogTarget<T extends ICommonTargetOptions> extends SyncService {
23
- public HasError: boolean; // true after a failed write, cleared on the next success
24
- public Error: Error | null | unknown; // the last write error, or null
25
- public Options: T; // merged options ( includes the default layout )
26
- public abstract write(data: ILogEntry): void;
27
- }
28
- ```
29
-
30
- A target receives fully-formed `ILogEntry` objects. It is responsible for:
31
-
32
- - honouring `Options.enabled` ( skip when `false` ),
33
- - rendering `data.Variables` through its `Options.layout`,
34
- - setting `HasError = true` / `Error = err` when a write fails and clearing them
35
- ( `HasError = false`, `Error = null` ) on the next successful write. Consumers
36
- can poll these fields to detect a degraded sink.
37
-
38
- ## `createLogMessageObject`
39
-
40
- ```ts
41
- createLogMessageObject(
42
- err: Error | string,
43
- message: string | any[],
44
- level: LogLevel,
45
- logger: string,
46
- variables: any,
47
- ...args: any[]
48
- ): ILogEntry
49
- ```
50
-
51
- It normalizes the two calling conventions the `Log` methods accept:
52
-
53
- - **Message overload** — `err` is the format string ( or `undefined` ) and
54
- `message` carries the format arguments, e.g. `log.info("hello %s", "world")`.
55
- - **Error overload** — `err` is an `Error` and `message` is the human message,
56
- e.g. `log.error(err, "could not connect")`.
57
-
58
- Rules it applies:
59
-
60
- - `sMsg = (err instanceof Error || !err) ? message : err` — an `err` string is
61
- itself the message body, so a bare `log.info("hi")` works.
62
- - `tMsg = args.length ? format(sMsg, ...args) : sMsg` — runs `util.format`-style
63
- substitution ( see `format.ts`; `%s %d %i %f %j %o %O %%` ) only when there are
64
- args.
65
- - `Variables.error` is set only for the `Error` overload.
66
- - `Variables.logger = logger ?? message` and `Variables.level` is the upper-cased
67
- level string.
68
-
69
- The returned entry is:
70
-
71
- ```ts
72
- {
73
- Level: LogLevel,
74
- Variables: {
75
- error, // Error | undefined
76
- level, // "INFO" | "ERROR" | ...
77
- logger, // logger name
78
- message, // formatted message
79
- ...variables
80
- }
81
- }
82
- ```
83
-
84
- ## Layout variables
85
-
86
- A target's `layout` is a template string resolved by `@spinajs/configuration`'s
87
- `format(variables, layout)`. Every key on `ILogEntry.Variables` is available as
88
- `${key}`. The always-present variables are:
89
-
90
- | Variable | Value |
91
- | --- | --- |
92
- | `${datetime}` | timestamp of the entry |
93
- | `${level}` | upper-cased level, e.g. `INFO` |
94
- | `${message}` | the formatted message |
95
- | `${error}` | the `Error` ( use `${error:message}` for its message ) |
96
- | `${logger}` | the logger name |
97
-
98
- Conditional blocks are supported, e.g. `${?error} ... ${/error}` only renders
99
- when `error` is set. Any custom variable you attach via `log.addVariable(name, value)`
100
- or the config `variables` array is also available as `${name}`.
101
-
102
- The default layout ( applied to every target unless overridden ) is:
103
-
104
- ```
105
- ${datetime} ${level} ${message}${?error} Exception: ${error:message}${/error} (${logger})
106
- ```
107
-
108
- ## Writing a custom target
109
-
110
- ```ts
111
- import { Injectable } from "@spinajs/di";
112
- import { format } from "@spinajs/configuration";
113
- import { LogTarget, ILogEntry, ICommonTargetOptions } from "@spinajs/log-common";
114
-
115
- @Injectable("MyTarget") // referenced by `type: "MyTarget"` in config
116
- export class MyTarget extends LogTarget<ICommonTargetOptions> {
117
- public write(data: ILogEntry): void {
118
- if (!this.Options.enabled) return;
119
- try {
120
- // render with the configured layout and send it somewhere
121
- send(format(data.Variables, this.Options.layout));
122
- this.HasError = false;
123
- this.Error = null;
124
- } catch (err) {
125
- this.HasError = true;
126
- this.Error = err;
127
- }
128
- }
129
- }
130
- ```
131
-
132
- See `@spinajs/log` for the concrete targets and the rules/targets configuration.
1
+ # `@spinajs/log-common`
2
+
3
+ Shared, dependency-light contracts for the SpinaJS logging stack. This package
4
+ holds no logging implementation of its own; it defines the abstract types that
5
+ `@spinajs/log`, `@spinajs/internal-logger` and the various log-source packages
6
+ implement. Depend on it when you write a **custom log target** or a **custom
7
+ `Log` implementation**, and want to avoid a circular dependency on `@spinajs/log`.
8
+
9
+ ## What lives here
10
+
11
+ | Export | Purpose |
12
+ | --- | --- |
13
+ | `Log` (abstract) | The logger contract: `trace/debug/info/warn/error/fatal/security/success`, `child`, `write`, `addVariable`, `timeStart/timeEnd`. |
14
+ | `LogTarget<T>` (abstract) | A sink that receives `ILogEntry` objects and writes them somewhere ( console, file, HTTP, ... ). |
15
+ | `createLogMessageObject` | Builds a normalized `ILogEntry` from the many call shapes the `Log` methods accept. |
16
+ | `LogLevel` / `StrToLogLevel` / `LogLevelStrings` | Level enum and string<->enum maps. |
17
+ | `ILogEntry`, `ILogRule`, `ICommonTargetOptions`, `IFileTargetOptions`, `ILogOptions` | Config and payload shapes. |
18
+
19
+ ## The `LogTarget` contract
20
+
21
+ ```ts
22
+ abstract class LogTarget<T extends ICommonTargetOptions> extends SyncService {
23
+ public HasError: boolean; // true after a failed write, cleared on the next success
24
+ public Error: Error | null | unknown; // the last write error, or null
25
+ public Options: T; // merged options ( includes the default layout )
26
+ public abstract write(data: ILogEntry): void;
27
+ }
28
+ ```
29
+
30
+ A target receives fully-formed `ILogEntry` objects. It is responsible for:
31
+
32
+ - honouring `Options.enabled` ( skip when `false` ),
33
+ - rendering `data.Variables` through its `Options.layout`,
34
+ - setting `HasError = true` / `Error = err` when a write fails and clearing them
35
+ ( `HasError = false`, `Error = null` ) on the next successful write. Consumers
36
+ can poll these fields to detect a degraded sink.
37
+
38
+ ## `createLogMessageObject`
39
+
40
+ ```ts
41
+ createLogMessageObject(
42
+ err: Error | string,
43
+ message: string | any[],
44
+ level: LogLevel,
45
+ logger: string,
46
+ variables: any,
47
+ ...args: any[]
48
+ ): ILogEntry
49
+ ```
50
+
51
+ It normalizes the two calling conventions the `Log` methods accept:
52
+
53
+ - **Message overload** — `err` is the format string ( or `undefined` ) and
54
+ `message` carries the format arguments, e.g. `log.info("hello %s", "world")`.
55
+ - **Error overload** — `err` is an `Error` and `message` is the human message,
56
+ e.g. `log.error(err, "could not connect")`.
57
+
58
+ Rules it applies:
59
+
60
+ - `sMsg = (err instanceof Error || !err) ? message : err` — an `err` string is
61
+ itself the message body, so a bare `log.info("hi")` works.
62
+ - `tMsg = args.length ? format(sMsg, ...args) : sMsg` — runs `util.format`-style
63
+ substitution ( see `format.ts`; `%s %d %i %f %j %o %O %%` ) only when there are
64
+ args.
65
+ - `Variables.error` is set only for the `Error` overload.
66
+ - `Variables.logger = logger ?? message` and `Variables.level` is the upper-cased
67
+ level string.
68
+
69
+ The returned entry is:
70
+
71
+ ```ts
72
+ {
73
+ Level: LogLevel,
74
+ Variables: {
75
+ error, // Error | undefined
76
+ level, // "INFO" | "ERROR" | ...
77
+ logger, // logger name
78
+ message, // formatted message
79
+ ...variables
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Layout variables
85
+
86
+ A target's `layout` is a template string resolved by `@spinajs/configuration`'s
87
+ `format(variables, layout)`. Every key on `ILogEntry.Variables` is available as
88
+ `${key}`. The always-present variables are:
89
+
90
+ | Variable | Value |
91
+ | --- | --- |
92
+ | `${datetime}` | timestamp of the entry |
93
+ | `${level}` | upper-cased level, e.g. `INFO` |
94
+ | `${message}` | the formatted message |
95
+ | `${error}` | the `Error` ( use `${error:message}` for its message ) |
96
+ | `${logger}` | the logger name |
97
+
98
+ Conditional blocks are supported, e.g. `${?error} ... ${/error}` only renders
99
+ when `error` is set. Any custom variable you attach via `log.addVariable(name, value)`
100
+ or the config `variables` array is also available as `${name}`.
101
+
102
+ The default layout ( applied to every target unless overridden ) is:
103
+
104
+ ```
105
+ ${datetime} ${level} ${message}${?error} Exception: ${error:message}${/error} (${logger})
106
+ ```
107
+
108
+ ## Writing a custom target
109
+
110
+ ```ts
111
+ import { Injectable } from "@spinajs/di";
112
+ import { format } from "@spinajs/configuration";
113
+ import { LogTarget, ILogEntry, ICommonTargetOptions } from "@spinajs/log-common";
114
+
115
+ @Injectable("MyTarget") // referenced by `type: "MyTarget"` in config
116
+ export class MyTarget extends LogTarget<ICommonTargetOptions> {
117
+ public write(data: ILogEntry): void {
118
+ if (!this.Options.enabled) return;
119
+ try {
120
+ // render with the configured layout and send it somewhere
121
+ send(format(data.Variables, this.Options.layout));
122
+ this.HasError = false;
123
+ this.Error = null;
124
+ } catch (err) {
125
+ this.HasError = true;
126
+ this.Error = err;
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ See `@spinajs/log` for the concrete targets and the rules/targets configuration.