@mmutils/logger 0.1.0 → 0.1.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 +159 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,6 +78,8 @@ Requires Node.js 20 or newer.
|
|
|
78
78
|
|
|
79
79
|
## Quick start
|
|
80
80
|
|
|
81
|
+
<!-- code:quick-start -->
|
|
82
|
+
|
|
81
83
|
```ts
|
|
82
84
|
import { Logger, messagePlugin, graphPlugin } from '@mmutils/logger';
|
|
83
85
|
|
|
@@ -92,8 +94,12 @@ logger.error(new Error('Connection lost'));
|
|
|
92
94
|
logger.infoGraph([1, 3, 8, 21, 8, 3], { title: 'CPU', unit: '%' });
|
|
93
95
|
```
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
<!-- /code -->
|
|
98
|
+
|
|
99
|
+
This prints the sample at the top
|
|
100
|
+
([`examples/quick-start.js`](examples/quick-start.js)); every feature has
|
|
101
|
+
its own example, see [Examples](#examples). Plugins can also be chained,
|
|
102
|
+
with the same typing:
|
|
97
103
|
|
|
98
104
|
```ts
|
|
99
105
|
const logger = new Logger().use(messagePlugin()).use(graphPlugin());
|
|
@@ -291,6 +297,36 @@ logger.infoGraph(values, {
|
|
|
291
297
|
});
|
|
292
298
|
```
|
|
293
299
|
|
|
300
|
+
For example, from [`examples/graphs.js`](examples/graphs.js), with the
|
|
301
|
+
datasets of [`examples/data.js`](examples/data.js):
|
|
302
|
+
|
|
303
|
+
<!-- code:graph -->
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
logger.infoGraph(latency, {
|
|
307
|
+
title: 'Latency',
|
|
308
|
+
unit: 'ms',
|
|
309
|
+
precision: 0,
|
|
310
|
+
aggregate: 'max', // the slowest request of each bar
|
|
311
|
+
axis: { start: 0, end: 1032.4, unit: 'ms', capTo: 1 }, // a time axis
|
|
312
|
+
});
|
|
313
|
+
logger.warningGraph(queue, {
|
|
314
|
+
title: 'Queue',
|
|
315
|
+
rows: 2,
|
|
316
|
+
axis: { start: 'Mon', end: 'Fri' },
|
|
317
|
+
});
|
|
318
|
+
logger.infoGraph(temperatures, {
|
|
319
|
+
title: 'Temperature',
|
|
320
|
+
unit: '°C',
|
|
321
|
+
precision: 1,
|
|
322
|
+
rows: 4,
|
|
323
|
+
baseline: 20, // warmer days grow up, colder days down
|
|
324
|
+
axis: { start: 'Mar 2', end: 'Mar 15' },
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
<!-- /code -->
|
|
329
|
+
|
|
294
330
|

|
|
295
331
|
|
|
296
332
|
<details>
|
|
@@ -300,14 +336,14 @@ logger.infoGraph(values, {
|
|
|
300
336
|
|
|
301
337
|
```text
|
|
302
338
|
2026/03/16 15:35:00 [i] info
|
|
303
|
-
Latency
|
|
304
|
-
│
|
|
305
|
-
│
|
|
306
|
-
|
|
339
|
+
Latency 370 ms
|
|
340
|
+
│ ▇ ▇ ▃ ▆ █ ▃ │
|
|
341
|
+
│▃▄█▅▅▄█▃▂ █ ▁▂█▄▅▅█▄▃▂▁█ │
|
|
342
|
+
│████████████▇█████████████▇▇▇█│
|
|
307
343
|
0ms 1s 32ms
|
|
308
|
-
average:
|
|
309
|
-
min:
|
|
310
|
-
max:
|
|
344
|
+
average: 154 ms 0 ms
|
|
345
|
+
min: 105 ms
|
|
346
|
+
max: 370 ms
|
|
311
347
|
2026/03/16 15:35:00 /!\ warning
|
|
312
348
|
Queue 9.00
|
|
313
349
|
│ ▁▁▃▃▄▆▆██▆▆▄▃▃▁▁ │
|
|
@@ -317,16 +353,16 @@ average: 4.76 0.00
|
|
|
317
353
|
min: 1.00
|
|
318
354
|
max: 9.00
|
|
319
355
|
2026/03/16 15:35:00 [i] info
|
|
320
|
-
Temperature 25.
|
|
321
|
-
│
|
|
322
|
-
|
|
323
|
-
│
|
|
324
|
-
│
|
|
356
|
+
Temperature 25.8 °C
|
|
357
|
+
│ ▂▃▆▇██▆▄▁ │
|
|
358
|
+
│▄▄█████████▄▃ ▁▁▁▁│
|
|
359
|
+
│ ▀▀████████▀▔▔ │
|
|
360
|
+
│ ▔▔▀▀▀▀▔ │
|
|
325
361
|
Mar 2 Mar 15
|
|
326
|
-
average:
|
|
362
|
+
average: 20.4 °C 15.4 °C
|
|
327
363
|
baseline: 20.0 °C
|
|
328
|
-
min:
|
|
329
|
-
max: 25.
|
|
364
|
+
min: 15.4 °C
|
|
365
|
+
max: 25.8 °C
|
|
330
366
|
```
|
|
331
367
|
|
|
332
368
|
<!-- /output -->
|
|
@@ -388,6 +424,38 @@ from -10 to 10:
|
|
|
388
424
|
| `'max'` | only down, from 10 |
|
|
389
425
|
| `20` (any value) | only down, from 20: the range holds it |
|
|
390
426
|
|
|
427
|
+
The first three on a wave from -8 to 8
|
|
428
|
+
([`examples/graph-baseline.js`](examples/graph-baseline.js) has a realistic
|
|
429
|
+
case for each):
|
|
430
|
+
|
|
431
|
+

|
|
432
|
+
|
|
433
|
+
<details>
|
|
434
|
+
<summary><sub>The output above as plain text</sub></summary>
|
|
435
|
+
|
|
436
|
+
<!-- output:baseline -->
|
|
437
|
+
|
|
438
|
+
```text
|
|
439
|
+
info | info | info
|
|
440
|
+
baseline: 0 8 | baseline: 'min' 8 | baseline: 'max' 8
|
|
441
|
+
│ ▄▆██▆▄ │ | │ ▄▆██▆▄ │ | │███▀▔ ▔▀█████████████│
|
|
442
|
+
│ ▄████████▄ │ | │ ▄████████▄ │ | │█▀ ▀███████████│
|
|
443
|
+
│ ▀████████▀│ | │████████████▄ ▄│ | │ ▀████████▀│
|
|
444
|
+
│ ▀▀██▀▀ │ | │██████████████▄▂ ▂▄██│ | │ ▀▀██▀▀ │
|
|
445
|
+
average: 0 -8 | average: 0 -8 | average: 0 -8
|
|
446
|
+
baseline: 0 | min: -8 | min: -8
|
|
447
|
+
min: -8 | max: 8 | max: 8
|
|
448
|
+
max: 8 | |
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
<!-- /output -->
|
|
452
|
+
|
|
453
|
+
<sub><i>Bars and frames may not line up in this text if your font lacks the block characters; the image shows the real alignment.</i></sub>
|
|
454
|
+
|
|
455
|
+
</details>
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
391
459
|
```ts
|
|
392
460
|
logger.infoGraph(temperatures, {
|
|
393
461
|
title: 'Temperature',
|
|
@@ -469,6 +537,8 @@ ignored)` if the plugin has none. A `max` below a numeric baseline is
|
|
|
469
537
|
`columnsPlugin()` lays out messages and graphs side by side. Each log is a
|
|
470
538
|
cell of a grid; `column()` picks the column the next logs go to:
|
|
471
539
|
|
|
540
|
+
<!-- code:columns -->
|
|
541
|
+
|
|
472
542
|
```ts
|
|
473
543
|
const logger = new Logger({ timestamp: 'HH:mm:ss' }) // short, for narrow columns
|
|
474
544
|
.use(messagePlugin())
|
|
@@ -488,6 +558,8 @@ for (const column of [0, 1]) {
|
|
|
488
558
|
logger.endColumns();
|
|
489
559
|
```
|
|
490
560
|
|
|
561
|
+
<!-- /code -->
|
|
562
|
+
|
|
491
563
|

|
|
492
564
|
|
|
493
565
|
<details>
|
|
@@ -608,20 +680,31 @@ collectors, and becomes the default kind. Use it **instead of**
|
|
|
608
680
|
one output style (e.g. JSON in production, `messagePlugin` in development).
|
|
609
681
|
If both set the default kind, the last one used wins:
|
|
610
682
|
|
|
683
|
+
<!-- code:json -->
|
|
684
|
+
|
|
611
685
|
```ts
|
|
612
686
|
import { Logger, jsonPlugin } from '@mmutils/logger';
|
|
613
687
|
|
|
614
688
|
const logger = new Logger({ plugins: [jsonPlugin()] });
|
|
689
|
+
const err = Object.assign(new Error('connect ECONNREFUSED 127.0.0.1:5432'), {
|
|
690
|
+
code: 'ECONNREFUSED',
|
|
691
|
+
});
|
|
615
692
|
|
|
616
693
|
logger.info({ msg: 'Server started', port: 8080 });
|
|
617
694
|
logger.error({ msg: 'Query failed', err });
|
|
618
695
|
```
|
|
619
696
|
|
|
620
|
-
|
|
697
|
+
<!-- /code -->
|
|
698
|
+
|
|
699
|
+
<!-- output:json -->
|
|
700
|
+
|
|
701
|
+
```text
|
|
621
702
|
{"id":1,"time":"2026-03-16T15:35:00.000Z","type":"info","data":{"msg":"Server started","port":8080}}
|
|
622
|
-
{"id":2,"time":"2026-03-16T15:35:00.
|
|
703
|
+
{"id":2,"time":"2026-03-16T15:35:00.000Z","type":"error","data":{"msg":"Query failed","err":{"name":"Error","message":"connect ECONNREFUSED 127.0.0.1:5432","stack":"Error: connect ECONNREFUSED 127.0.0.1:5432\n at main (file:///app/server.js:12:16)","code":"ECONNREFUSED"}}}
|
|
623
704
|
```
|
|
624
705
|
|
|
706
|
+
<!-- /output -->
|
|
707
|
+
|
|
625
708
|
```ts
|
|
626
709
|
jsonPlugin({
|
|
627
710
|
kind: 'json', // kind written by the plugin
|
|
@@ -761,7 +844,32 @@ plugins use:
|
|
|
761
844
|
The level colors are the terminal's 16 basic colors, so they follow its
|
|
762
845
|
theme: red for `fatal` (its badge is white on red), bright red for `error`,
|
|
763
846
|
yellow for `warning`, blue for `info`, magenta for `debug`, cyan for
|
|
764
|
-
`trace`, gray for `verbose
|
|
847
|
+
`trace`, gray for `verbose`
|
|
848
|
+
([`examples/levels.js`](examples/levels.js),
|
|
849
|
+
[`examples/styles.js`](examples/styles.js)):
|
|
850
|
+
|
|
851
|
+

|
|
852
|
+
|
|
853
|
+
<details>
|
|
854
|
+
<summary><sub>The output above as plain text</sub></summary>
|
|
855
|
+
|
|
856
|
+
<!-- output:levels -->
|
|
857
|
+
|
|
858
|
+
```text
|
|
859
|
+
2026/03/16 15:35:00 [X] fatal Out of memory: the process exits now
|
|
860
|
+
2026/03/16 15:35:00 [!] error Payment failed: card declined for order 1042
|
|
861
|
+
2026/03/16 15:35:00 /!\ warning Disk 91% full on /var, cleanup starts at 95%
|
|
862
|
+
2026/03/16 15:35:00 [i] info Server listening on http://localhost:8080
|
|
863
|
+
2026/03/16 15:35:00 (?) debug Cache miss for user:42, loading from the database
|
|
864
|
+
2026/03/16 15:35:00 /\/ trace GET /api/orders → 200 in 34 ms
|
|
865
|
+
2026/03/16 15:35:00 ... verbose Pool: 3 of 10 connections in use
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
<!-- /output -->
|
|
869
|
+
|
|
870
|
+
</details>
|
|
871
|
+
|
|
872
|
+
---
|
|
765
873
|
|
|
766
874
|
### Symbols
|
|
767
875
|
|
|
@@ -879,14 +987,43 @@ Re-declaring an existing logger method in `M` replaces its signature and docs
|
|
|
879
987
|
in autocomplete. That's how `messagePlugin` changes `info(data: unknown)` to
|
|
880
988
|
`info(message: string)`.
|
|
881
989
|
|
|
990
|
+
## Examples
|
|
991
|
+
|
|
992
|
+
Each file in [`examples/`](examples) shows one topic, with comments on what
|
|
993
|
+
to look for in its output. Build first, then run one, or all of them with
|
|
994
|
+
`npm run demo`:
|
|
995
|
+
|
|
996
|
+
```sh
|
|
997
|
+
npm run build
|
|
998
|
+
node examples/graphs.js
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
| File | Shows |
|
|
1002
|
+
| ------------------------------------------------- | ------------------------------------------------------------ |
|
|
1003
|
+
| [`quick-start.js`](examples/quick-start.js) | The quick start above |
|
|
1004
|
+
| [`levels.js`](examples/levels.js) | The seven log types, filtering with `level` |
|
|
1005
|
+
| [`messages.js`](examples/messages.js) | Text, objects, arrays, errors, values JSON can't represent |
|
|
1006
|
+
| [`timestamps.js`](examples/timestamps.js) | Patterns, UTC, the precise clock, elapsed time, a fixed time |
|
|
1007
|
+
| [`graphs.js`](examples/graphs.js) | Size, `aggregate`, axis labels, statistics |
|
|
1008
|
+
| [`graph-baseline.js`](examples/graph-baseline.js) | `baseline`, `min` and `max` on realistic data |
|
|
1009
|
+
| [`columns.js`](examples/columns.js) | Call for call, wrap modes, graph widths, `row(n)` |
|
|
1010
|
+
| [`live.js`](examples/live.js) | A status board redrawn in place (run it in a terminal) |
|
|
1011
|
+
| [`json.js`](examples/json.js) | JSON lines, time formats, limits, an audit kind |
|
|
1012
|
+
| [`safety.js`](examples/safety.js) | Sanitizing, output limits, data that can't be read |
|
|
1013
|
+
| [`styles.js`](examples/styles.js) | Level colors, symbols, overrides, `useStyles: false` |
|
|
1014
|
+
| [`custom-plugin.js`](examples/custom-plugin.js) | A new kind with a method, a transformer |
|
|
1015
|
+
|
|
1016
|
+
The images in this README are drawn from the same files
|
|
1017
|
+
(`npm run images`), so they show what the examples print.
|
|
1018
|
+
|
|
882
1019
|
## Development
|
|
883
1020
|
|
|
884
1021
|
```sh
|
|
885
1022
|
npm install
|
|
886
1023
|
npm run check # format, lint, typecheck, tests
|
|
887
1024
|
npm run build # dist/esm, dist/cjs, dist/types
|
|
888
|
-
npm run demo #
|
|
889
|
-
npm run images # README images
|
|
1025
|
+
npm run demo # every example, one after the other (after build)
|
|
1026
|
+
npm run images # README images, their text and code, from examples/ (after build)
|
|
890
1027
|
```
|
|
891
1028
|
|
|
892
1029
|
## AI use
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmutils/logger",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Plugin-extensible TypeScript logger: a transformer pipeline, baked ANSI styles, styled messages, terminal bar graphs, side-by-side columns and JSON lines.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logger",
|