@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 +132 -132
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +57 -57
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.
|