@niceties/logger 1.1.12 → 2.0.0
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 +173 -54
- package/appender-utils.js +30 -0
- package/console-appender.js +7 -0
- package/core.js +96 -0
- package/default-formatting.js +17 -0
- package/format-utils.js +21 -0
- package/global-appender.js +15 -0
- package/index.d.ts +362 -0
- package/index.d.ts.map +48 -0
- package/index.js +40 -0
- package/package.json +24 -37
- package/simple.js +42 -0
- package/types.js +17 -0
- package/appender-utils/package.json +0 -5
- package/console-appender/package.json +0 -5
- package/core/package.json +0 -5
- package/default-formatting/package.json +0 -5
- package/dist/appender-utils.cjs +0 -22
- package/dist/appender-utils.d.ts +0 -3
- package/dist/appender-utils.mjs +0 -19
- package/dist/appender-utils.umd.js +0 -2
- package/dist/appender-utils.umd.js.map +0 -1
- package/dist/console-appender.cjs +0 -9
- package/dist/console-appender.d.ts +0 -2
- package/dist/console-appender.mjs +0 -7
- package/dist/console-appender.umd.js +0 -2
- package/dist/console-appender.umd.js.map +0 -1
- package/dist/core.cjs +0 -72
- package/dist/core.d.ts +0 -7
- package/dist/core.mjs +0 -70
- package/dist/core.umd.js +0 -2
- package/dist/core.umd.js.map +0 -1
- package/dist/default-formatting.cjs +0 -17
- package/dist/default-formatting.d.ts +0 -5
- package/dist/default-formatting.mjs +0 -12
- package/dist/format-utils.cjs +0 -21
- package/dist/format-utils.d.ts +0 -3
- package/dist/format-utils.mjs +0 -18
- package/dist/global-appender.cjs +0 -12
- package/dist/global-appender.d.ts +0 -3
- package/dist/global-appender.mjs +0 -10
- package/dist/global-appender.umd.js +0 -2
- package/dist/global-appender.umd.js.map +0 -1
- package/dist/index.cjs +0 -19
- package/dist/index.d.ts +0 -4
- package/dist/index.mjs +0 -18
- package/dist/simple.cjs +0 -25
- package/dist/simple.d.ts +0 -4
- package/dist/simple.mjs +0 -23
- package/dist/simple.umd.js +0 -2
- package/dist/simple.umd.js.map +0 -1
- package/dist/types.d.ts +0 -51
- package/format-utils/package.json +0 -5
- package/global-appender/package.json +0 -5
- package/simple/package.json +0 -5
- package/types/package.json +0 -3
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Logger that can handle async tasks.
|
|
4
4
|
|
|
5
|
-
- Provides normal logging API: log level,
|
|
5
|
+
- Provides a normal logging API: log level, tagged logger instance, custom log data
|
|
6
6
|
|
|
7
|
-
- Provides API for reporting async events that can be
|
|
7
|
+
- Provides an API for reporting async events that can later be handled by a custom appender.
|
|
8
8
|
|
|
9
|
-
- Provides a default appender that uses console for output.
|
|
9
|
+
- Provides a default appender that uses the console for output.
|
|
10
10
|
|
|
11
11
|
- Modular and configurable
|
|
12
12
|
|
|
@@ -43,46 +43,66 @@ try {
|
|
|
43
43
|
Logger factory:
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
function createLogger<ErrorContext = Error>(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
function createLogger<ErrorContext = Error>(
|
|
47
|
+
...args: [] | [string | Identity | undefined] | [string, Identity]
|
|
48
|
+
): ((
|
|
49
|
+
message: string,
|
|
50
|
+
loglevel?: LogLevel,
|
|
51
|
+
context?: ErrorContext | undefined,
|
|
52
|
+
) => void) & {
|
|
53
|
+
start(
|
|
54
|
+
message: string,
|
|
55
|
+
loglevel?: LogLevel | undefined,
|
|
56
|
+
context?: ErrorContext | undefined,
|
|
57
|
+
): void;
|
|
58
|
+
update(
|
|
59
|
+
message: string,
|
|
60
|
+
loglevel?: LogLevel | undefined,
|
|
61
|
+
context?: ErrorContext | undefined,
|
|
62
|
+
): void;
|
|
63
|
+
finish(
|
|
64
|
+
message: string,
|
|
65
|
+
loglevel?: LogLevel | undefined,
|
|
66
|
+
context?: ErrorContext | undefined,
|
|
67
|
+
): void;
|
|
68
|
+
appender(
|
|
69
|
+
appender?: Appender<ErrorContext> | undefined,
|
|
70
|
+
): (message: LogMessage<ErrorContext>) => void;
|
|
51
71
|
};
|
|
52
72
|
```
|
|
53
73
|
|
|
54
|
-
|
|
74
|
+
Returns a logger instance that can be viewed as an entry for a single async task.
|
|
55
75
|
|
|
56
76
|
```typescript
|
|
57
|
-
const logger = createLogger(
|
|
77
|
+
const logger = createLogger("tag");
|
|
58
78
|
const logger2 = createLogger(logger);
|
|
59
|
-
const logger3 = createLogger(
|
|
79
|
+
const logger3 = createLogger("tag2", logger);
|
|
60
80
|
```
|
|
61
81
|
|
|
62
82
|
`tag` can be used to distinguish between async tasks (will be provided to appender).
|
|
63
|
-
|
|
83
|
+
Logger can be used as a parent of another logger (will be provided as parentId to appender).
|
|
64
84
|
|
|
65
85
|
```typescript
|
|
66
86
|
const log = createLogger();
|
|
67
87
|
|
|
68
88
|
try {
|
|
69
89
|
// some code
|
|
70
|
-
log(
|
|
90
|
+
log("some message");
|
|
71
91
|
} catch (e) {
|
|
72
|
-
log(
|
|
92
|
+
log("some message", 1 /* LogLevel.info */, e);
|
|
73
93
|
}
|
|
74
94
|
```
|
|
75
95
|
|
|
76
|
-
Logger can be used as a function that logs message or error with context. Context type can be defined during creation of the logger (only in
|
|
96
|
+
Logger can be used as a function that logs a message or error with context. Context type can be defined during creation of the logger (only in TypeScript).
|
|
77
97
|
|
|
78
98
|
```typescript
|
|
79
99
|
const log = createLogger<Context>();
|
|
80
100
|
|
|
81
101
|
try {
|
|
82
102
|
// some code
|
|
83
|
-
log(
|
|
103
|
+
log("some message");
|
|
84
104
|
} catch (e: Context) {
|
|
85
|
-
log(
|
|
105
|
+
log("some message", LogLevel.info, e);
|
|
86
106
|
}
|
|
87
107
|
```
|
|
88
108
|
|
|
@@ -90,19 +110,19 @@ try {
|
|
|
90
110
|
start(message: string, loglevel?: LogLevel | undefined, context?: ErrorContext | undefined): void;
|
|
91
111
|
```
|
|
92
112
|
|
|
93
|
-
Emits a start event inside a logger. If loglevel provided it will be remembered and used as default loglevel in subsequent events in the same logger instance. Default loglevel (if argument is not provided) is `info`.
|
|
113
|
+
Emits a start event inside a logger. If a loglevel is provided, it will be remembered and used as the default loglevel in subsequent events in the same logger instance. Default loglevel (if the argument is not provided) is `info`.
|
|
94
114
|
|
|
95
115
|
```typescript
|
|
96
116
|
update(message: string, loglevel?: LogLevel | undefined, context?: ErrorContext | undefined): void;
|
|
97
117
|
```
|
|
98
118
|
|
|
99
|
-
Emits update event. Can be used to inform
|
|
119
|
+
Emits an update event. Can be used to inform a user that we are doing something else in the same async task. The loglevel parameter is used to redefine the default loglevel.
|
|
100
120
|
|
|
101
121
|
```typescript
|
|
102
122
|
finish(message: string, loglevel?: LogLevel | undefined, context?: ErrorContext | undefined): void;
|
|
103
123
|
```
|
|
104
124
|
|
|
105
|
-
Emits finish event. Can be used to inform
|
|
125
|
+
Emits a finish event. Can be used to inform a user that the task finished. loglevel is optional and equals the initial loglevel if omitted.
|
|
106
126
|
|
|
107
127
|
```typescript
|
|
108
128
|
const logger = createLogger();
|
|
@@ -111,6 +131,34 @@ logger.appender(someFancyAppender);
|
|
|
111
131
|
|
|
112
132
|
Sets a different appender for the specific instance of the logger.
|
|
113
133
|
|
|
134
|
+
## Appender API
|
|
135
|
+
|
|
136
|
+
Appenders can expose additional methods to the logger instance via the `api` property. When an appender with an `api` property is set on a logger, the `api` object is installed into the logger's prototype chain. This means the methods are accessible directly on the logger instance:
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
import { createLogger } from "@niceties/logger";
|
|
140
|
+
import { filterMessages } from "@niceties/logger/appender-utils";
|
|
141
|
+
|
|
142
|
+
let minLevel = 1;
|
|
143
|
+
const filtered = filterMessages(
|
|
144
|
+
(msg) => msg.loglevel >= minLevel,
|
|
145
|
+
someAppender,
|
|
146
|
+
);
|
|
147
|
+
filtered.api = {
|
|
148
|
+
setMinLevel(level) {
|
|
149
|
+
minLevel = level;
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const logger = createLogger();
|
|
154
|
+
logger.appender(filtered);
|
|
155
|
+
|
|
156
|
+
// Method is available directly on the logger:
|
|
157
|
+
logger.setMinLevel(0);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
When the appender is swapped, old `api` methods are automatically cleaned up - they are removed from the logger and replaced with the new appender's `api` (if any).
|
|
161
|
+
|
|
114
162
|
```typescript
|
|
115
163
|
const logger = createLogger();
|
|
116
164
|
const appender = logger.appender();
|
|
@@ -125,7 +173,7 @@ const enum LogLevel {
|
|
|
125
173
|
verbose, // for debugging logs, not for displaying on screen in normal cases
|
|
126
174
|
info, // should be printed to user but not an error
|
|
127
175
|
warn, // something is probably wrong, but we can continue
|
|
128
|
-
error // operation completely failed
|
|
176
|
+
error, // operation completely failed
|
|
129
177
|
}
|
|
130
178
|
```
|
|
131
179
|
|
|
@@ -134,39 +182,71 @@ const enum LogLevel {
|
|
|
134
182
|
User or another library can set another appender by calling:
|
|
135
183
|
|
|
136
184
|
```typescript
|
|
137
|
-
function appender<ErrorContext = Error>(
|
|
185
|
+
function appender<ErrorContext = Error>(
|
|
186
|
+
appender?: Appender<ErrorContext>,
|
|
187
|
+
): Appender<any>;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
If the appender has an `api` property, its methods are installed into the `appender` function's prototype chain, making them directly accessible:
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
import { appender } from "@niceties/logger";
|
|
194
|
+
import { filterMessages } from "@niceties/logger/appender-utils";
|
|
195
|
+
|
|
196
|
+
let minLevel = 1;
|
|
197
|
+
const filtered = filterMessages(
|
|
198
|
+
(msg) => msg.loglevel >= minLevel,
|
|
199
|
+
someAppender,
|
|
200
|
+
);
|
|
201
|
+
filtered.api = {
|
|
202
|
+
setMinLevel(level) {
|
|
203
|
+
minLevel = level;
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
appender(filtered);
|
|
207
|
+
|
|
208
|
+
// Method is available directly on the appender function:
|
|
209
|
+
appender.setMinLevel(0);
|
|
138
210
|
```
|
|
139
211
|
|
|
140
|
-
|
|
212
|
+
When a new global appender is set, old `api` methods are automatically cleaned up and replaced.
|
|
213
|
+
|
|
214
|
+
The appender is a function with the following type:
|
|
141
215
|
|
|
142
216
|
```typescript
|
|
143
|
-
|
|
217
|
+
type Appender<ErrorContext = Error> = ((
|
|
218
|
+
message: LogMessage<ErrorContext>,
|
|
219
|
+
) => void) & {
|
|
220
|
+
api?: object;
|
|
221
|
+
};
|
|
144
222
|
|
|
145
223
|
const enum Action {
|
|
146
224
|
start,
|
|
147
225
|
update,
|
|
148
|
-
|
|
149
|
-
|
|
226
|
+
finish,
|
|
227
|
+
log,
|
|
150
228
|
}
|
|
151
229
|
|
|
152
|
-
type LogMessage<ErrorContext = Error> =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
230
|
+
type LogMessage<ErrorContext = Error> =
|
|
231
|
+
| {
|
|
232
|
+
inputId: number;
|
|
233
|
+
loglevel: LogLevel;
|
|
234
|
+
message: string;
|
|
235
|
+
action: Action.start | Action.update | Action.finish;
|
|
236
|
+
tag?: string;
|
|
237
|
+
parentId?: string;
|
|
238
|
+
ref: WeakRef<never>;
|
|
239
|
+
}
|
|
240
|
+
| {
|
|
241
|
+
inputId?: number;
|
|
242
|
+
loglevel: LogLevel;
|
|
243
|
+
message: string;
|
|
244
|
+
action: Action.log;
|
|
245
|
+
tag?: string;
|
|
246
|
+
parentId?: string;
|
|
247
|
+
ref?: WeakRef<never>;
|
|
248
|
+
context?: ErrorContext;
|
|
249
|
+
};
|
|
170
250
|
```
|
|
171
251
|
|
|
172
252
|
Same appender function without arguments can be used to get the current appender.
|
|
@@ -175,7 +255,7 @@ Same appender function without arguments can be used to get the current appender
|
|
|
175
255
|
|
|
176
256
|
## Can I use more than 4 log levels
|
|
177
257
|
|
|
178
|
-
Despite the fact loglevel defined as an enum it is just a number. Logger does not make assumptions about loglevels besides defining default loglevel as 1 (LogLevel.info).
|
|
258
|
+
Despite the fact that loglevel is defined as an enum, it is just a number. Logger does not make assumptions about loglevels besides defining the default loglevel as 1 (LogLevel.info).
|
|
179
259
|
|
|
180
260
|
It is generally safe to expand loglevels into both positive and negative range (finer debug messages) as far as appender takes them into account.
|
|
181
261
|
|
|
@@ -184,10 +264,10 @@ As an example:
|
|
|
184
264
|
```typescript
|
|
185
265
|
const log = createLogger();
|
|
186
266
|
|
|
187
|
-
log(
|
|
267
|
+
log("some message", -1);
|
|
188
268
|
```
|
|
189
269
|
|
|
190
|
-
will send a log message with finer loglevel than verbose through appender but default appender will ignore it.
|
|
270
|
+
will send a log message with a finer loglevel than verbose through the appender, but the default appender will ignore it.
|
|
191
271
|
|
|
192
272
|
## Can I use multiple appenders?
|
|
193
273
|
|
|
@@ -200,22 +280,63 @@ import { combineAppenders } from "@niceties/logger/appender-utils";
|
|
|
200
280
|
appender(combineAppenders(appender(), appender2));
|
|
201
281
|
```
|
|
202
282
|
|
|
203
|
-
|
|
283
|
+
If any of the combined appenders have an `api` property, their methods are merged into the combined appender's `api`.
|
|
284
|
+
|
|
285
|
+
## Can I set a filter for a certain loglevel?
|
|
204
286
|
|
|
205
287
|
It is possible using filterMessages and appender functions:
|
|
206
288
|
|
|
207
289
|
```javascript
|
|
290
|
+
import { appender } from "@niceties/logger";
|
|
208
291
|
import { filterMessages } from "@niceties/logger/appender-utils";
|
|
209
292
|
|
|
210
293
|
let desiredLoglevel = 0;
|
|
211
294
|
|
|
212
|
-
|
|
295
|
+
const filtered = filterMessages(
|
|
296
|
+
(msg) => msg.loglevel >= desiredLoglevel,
|
|
297
|
+
appender(),
|
|
298
|
+
);
|
|
299
|
+
filtered.api = {
|
|
300
|
+
setLoglevel(loglevel) {
|
|
301
|
+
desiredLoglevel = loglevel;
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
appender(filtered);
|
|
213
305
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
306
|
+
// Available directly on the appender function:
|
|
307
|
+
appender.setLoglevel(0);
|
|
217
308
|
```
|
|
218
309
|
|
|
310
|
+
## How does `filterMessages` handle the `api` property?
|
|
311
|
+
|
|
312
|
+
`filterMessages` automatically forwards the `api` property from the inner (wrapped) appender. If the inner appender has an `api`, the filtered appender will inherit it. You can extend it further by setting your own `api` on the result:
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
const inner = createConsoleAppender(formatter);
|
|
316
|
+
inner.api = {
|
|
317
|
+
someMethod() {
|
|
318
|
+
/* ... */
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const filtered = filterMessages((msg) => msg.loglevel >= 1, inner);
|
|
323
|
+
// filtered.api === inner.api (forwarded automatically)
|
|
324
|
+
|
|
325
|
+
// To add more methods while preserving the inner api:
|
|
326
|
+
filtered.api = {
|
|
327
|
+
...filtered.api,
|
|
328
|
+
anotherMethod() {
|
|
329
|
+
/* ... */
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Appender API: authoring guidelines
|
|
335
|
+
|
|
336
|
+
When an appender exposes an `api` object, the `api` is installed into the prototype chain of the logger instance or the global `appender` function. Because built-in logger methods (`start`, `update`, `finish`, `appender`) and properties (`id`) are own properties of the logger, they naturally take precedence over prototype properties. This means that even if an `api` object accidentally contains a property with the same name as a built-in, the built-in will not be overwritten.
|
|
337
|
+
|
|
338
|
+
However, appender authors should still avoid using built-in names in the `api` object, as the `api` methods would be silently shadowed and inaccessible.
|
|
339
|
+
|
|
219
340
|
# Sub-packages
|
|
220
341
|
|
|
221
342
|
Default sub-package `'@niceties/logger'` exports types, `createLogger()` factory and `appender()` function.
|
|
@@ -234,8 +355,6 @@ Sub-package `'@niceties/logger/global-appender'` exports `appender()` and `globa
|
|
|
234
355
|
|
|
235
356
|
Sub-package `'@niceties/logger/appender-utils'` exports `combineAppenders()` and `filterMessages()`.
|
|
236
357
|
|
|
237
|
-
`simple` (default), `core` and `console-appender` exist as umd packages as well but probably require some effort to consume them.
|
|
238
|
-
|
|
239
358
|
# Prior art
|
|
240
359
|
|
|
241
360
|
- [loglevel](https://github.com/pimterry/loglevel)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const filterMessages = (predicate, appender) => {
|
|
2
|
+
|
|
3
|
+
const result = logMessage => {
|
|
4
|
+
if (predicate(logMessage)) {
|
|
5
|
+
appender(logMessage);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
if (appender.api) {
|
|
9
|
+
result.api = appender.api;
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const combineAppenders = (...appenders) => {
|
|
15
|
+
|
|
16
|
+
const result = ( message) => {
|
|
17
|
+
for (const appender of appenders) {
|
|
18
|
+
try {
|
|
19
|
+
appender(message);
|
|
20
|
+
} catch {
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const apis = appenders.map(a => a.api).filter(Boolean);
|
|
26
|
+
if (apis.length > 0) {
|
|
27
|
+
result.api = (Object.assign({}, ...apis));
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
};
|
package/core.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { globalAppender } from './global-appender.js';
|
|
2
|
+
import { Action, LogLevel } from './types.js';
|
|
3
|
+
|
|
4
|
+
let globalInputId = 0;
|
|
5
|
+
|
|
6
|
+
const getOptions = options => {
|
|
7
|
+
|
|
8
|
+
let parentId;
|
|
9
|
+
|
|
10
|
+
let tag;
|
|
11
|
+
if (options.length === 1) {
|
|
12
|
+
if (typeof options[0] === 'string') {
|
|
13
|
+
tag = options[0];
|
|
14
|
+
} else {
|
|
15
|
+
parentId = options[0]?.id;
|
|
16
|
+
}
|
|
17
|
+
} else if (options.length === 2) {
|
|
18
|
+
tag = options[0];
|
|
19
|
+
parentId = options[1]?.id;
|
|
20
|
+
}
|
|
21
|
+
return { parentId, tag };
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const createLogger = (...args) => {
|
|
25
|
+
let initialLogLevel = LogLevel.info;
|
|
26
|
+
|
|
27
|
+
let myAppender = message => {
|
|
28
|
+
globalAppender?.(message);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const inputId = globalInputId++;
|
|
32
|
+
|
|
33
|
+
const { tag, parentId } = getOptions( (args));
|
|
34
|
+
|
|
35
|
+
const append = (message, action, loglevel, context) => {
|
|
36
|
+
myAppender?.(
|
|
37
|
+
({
|
|
38
|
+
action,
|
|
39
|
+
inputId,
|
|
40
|
+
message,
|
|
41
|
+
loglevel,
|
|
42
|
+
tag,
|
|
43
|
+
parentId,
|
|
44
|
+
ref,
|
|
45
|
+
context,
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const loggerInstance = Object.assign(
|
|
51
|
+
|
|
52
|
+
(message, loglevel = LogLevel.info, context) => {
|
|
53
|
+
append(message, Action.log, loglevel, context);
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
|
|
57
|
+
start(message, loglevel, context) {
|
|
58
|
+
if (loglevel !== undefined) {
|
|
59
|
+
initialLogLevel = loglevel;
|
|
60
|
+
}
|
|
61
|
+
append(message, Action.start, initialLogLevel, context);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
update(message, loglevel, context) {
|
|
65
|
+
append(message, Action.update, loglevel ?? initialLogLevel, context);
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
finish(message, loglevel, context) {
|
|
69
|
+
append(message, Action.finish, loglevel ?? initialLogLevel, context);
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
appender(appender) {
|
|
73
|
+
if (appender !== undefined) {
|
|
74
|
+
myAppender = appender;
|
|
75
|
+
const api = appender.api;
|
|
76
|
+
if (api != null) {
|
|
77
|
+
Object.setPrototypeOf(api, Function.prototype);
|
|
78
|
+
Object.setPrototypeOf(loggerInstance, api);
|
|
79
|
+
} else {
|
|
80
|
+
Object.setPrototypeOf(loggerInstance, Function.prototype);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return myAppender;
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
Object.defineProperty(loggerInstance, 'id', {
|
|
89
|
+
value: inputId,
|
|
90
|
+
writable: false,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const ref = new WeakRef(loggerInstance);
|
|
94
|
+
|
|
95
|
+
return (loggerInstance);
|
|
96
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import kleur from 'kleur';
|
|
2
|
+
|
|
3
|
+
const { green, red, yellow, blue, cyan, grey } = kleur;
|
|
4
|
+
|
|
5
|
+
export const unicodePrefixes = [`${green('✓')}`, `${green('✓')}`, '⚠', '✕'];
|
|
6
|
+
|
|
7
|
+
export const asciiPrefixes = [`${green('+')}`, `${green('+')}`, '!', 'x'];
|
|
8
|
+
|
|
9
|
+
export const unicodeLogPrefixes = [grey('ℹ'), `${cyan('ℹ')}`, 'ℹ', 'ℹ'];
|
|
10
|
+
|
|
11
|
+
export const asciiLogPrefixes = [grey('i'), `${cyan('i')}`, 'i', 'i'];
|
|
12
|
+
|
|
13
|
+
export const colors = [, , yellow, red];
|
|
14
|
+
|
|
15
|
+
export const tagFactory = tag => {
|
|
16
|
+
return `[${blue(tag)}]`;
|
|
17
|
+
};
|
package/format-utils.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Action, LogLevel } from './types.js';
|
|
2
|
+
|
|
3
|
+
export const createFormatter = (colors, prefixes, logPrefixes, tagFactory) => {
|
|
4
|
+
return ({ loglevel, message, context, action, tag }, usePrefix, indentation = 0) => {
|
|
5
|
+
const prefix =
|
|
6
|
+
usePrefix === true
|
|
7
|
+
? `${prefixes[loglevel]} `
|
|
8
|
+
: typeof usePrefix === 'string'
|
|
9
|
+
? `${usePrefix} `
|
|
10
|
+
: action === Action.log && logPrefixes[loglevel]
|
|
11
|
+
? `${logPrefixes[loglevel]} `
|
|
12
|
+
: '';
|
|
13
|
+
const color = colors[loglevel];
|
|
14
|
+
const text = `${prefix}${loglevel === LogLevel.verbose && action === Action.log && tag !== undefined ? `${tagFactory(tag)} ` : ''}${message}${context != null ? ` ${context}` : ''}`;
|
|
15
|
+
return `${' '.repeat(indentation)}${color ? color(text) : text}`;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const terminalSupportsUnicode = () => {
|
|
20
|
+
return process.platform !== 'win32' || process.env.TERM_PROGRAM === 'vscode' || !!process.env.WT_SESSION;
|
|
21
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export let globalAppender;
|
|
2
|
+
|
|
3
|
+
export const appender = newAppender => {
|
|
4
|
+
if (newAppender !== undefined) {
|
|
5
|
+
globalAppender = (newAppender);
|
|
6
|
+
const api = newAppender != null ? newAppender.api : undefined;
|
|
7
|
+
if (api != null) {
|
|
8
|
+
Object.setPrototypeOf(api, Function.prototype);
|
|
9
|
+
Object.setPrototypeOf(appender, api);
|
|
10
|
+
} else {
|
|
11
|
+
Object.setPrototypeOf(appender, Function.prototype);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return globalAppender;
|
|
15
|
+
};
|