@warlock.js/logger 4.1.15 → 4.2.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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +146 -145
- package/cjs/index.cjs +276 -11
- package/cjs/index.cjs.map +1 -1
- package/esm/channels/console-log.d.mts +1 -1
- package/esm/channels/console-log.d.mts.map +1 -1
- package/esm/channels/console-log.mjs +4 -1
- package/esm/channels/console-log.mjs.map +1 -1
- package/esm/channels/file-log.d.mts +13 -3
- package/esm/channels/file-log.d.mts.map +1 -1
- package/esm/channels/file-log.mjs +15 -1
- package/esm/channels/file-log.mjs.map +1 -1
- package/esm/channels/index.mjs +1 -0
- package/esm/channels/json-file-log.d.mts +1 -1
- package/esm/channels/json-file-log.d.mts.map +1 -1
- package/esm/channels/json-file-log.mjs +1 -1
- package/esm/channels/json-file-log.mjs.map +1 -1
- package/esm/channels/sentry-log.d.mts +182 -0
- package/esm/channels/sentry-log.d.mts.map +1 -0
- package/esm/channels/sentry-log.mjs +202 -0
- package/esm/channels/sentry-log.mjs.map +1 -0
- package/esm/index.d.mts +2 -1
- package/esm/index.mjs +2 -1
- package/esm/log-channel.d.mts +9 -1
- package/esm/log-channel.d.mts.map +1 -1
- package/esm/log-channel.mjs +1 -1
- package/esm/log-channel.mjs.map +1 -1
- package/esm/logger.d.mts +32 -1
- package/esm/logger.d.mts.map +1 -1
- package/esm/logger.mjs +44 -2
- package/esm/logger.mjs.map +1 -1
- package/esm/redact/redact.d.mts +1 -1
- package/esm/redact/redact.d.mts.map +1 -1
- package/esm/redact/redact.mjs +1 -1
- package/esm/redact/redact.mjs.map +1 -1
- package/esm/types.d.mts +19 -3
- package/esm/types.d.mts.map +1 -1
- package/esm/utils/capture-unhandled-errors.d.mts +9 -1
- package/esm/utils/capture-unhandled-errors.d.mts.map +1 -1
- package/esm/utils/capture-unhandled-errors.mjs +10 -2
- package/esm/utils/capture-unhandled-errors.mjs.map +1 -1
- package/esm/utils/clear-message.d.mts +1 -1
- package/esm/utils/clear-message.d.mts.map +1 -1
- package/esm/utils/clear-message.mjs +1 -1
- package/esm/utils/clear-message.mjs.map +1 -1
- package/esm/utils/safe-json-stringify.d.mts +1 -1
- package/esm/utils/safe-json-stringify.d.mts.map +1 -1
- package/esm/utils/safe-json-stringify.mjs +1 -1
- package/esm/utils/safe-json-stringify.mjs.map +1 -1
- package/llms-full.txt +1497 -1296
- package/llms.txt +20 -19
- package/package.json +5 -2
- package/skills/capture-unhandled-errors/SKILL.md +103 -103
- package/skills/filter-log-entries/SKILL.md +120 -120
- package/skills/flush-logs-on-shutdown/SKILL.md +117 -91
- package/skills/logger-basics/SKILL.md +88 -85
- package/skills/overview/SKILL.md +90 -86
- package/skills/pick-log-channel/SKILL.md +155 -139
- package/skills/ship-logs-to-sentry/SKILL.md +118 -0
- package/skills/write-custom-log-channel/SKILL.md +190 -160
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog — @warlock.js/logger
|
|
2
|
+
|
|
3
|
+
All notable changes to `@warlock.js/logger` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## 4.2.0
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `log.flush()` — awaitable async counterpart to `flushSync()`. Drains every channel that implements `flush()` via `Promise.allSettled` with per-channel isolation, so one channel's failure can't break shutdown. `FileLog` / `JSONFileLog` implement it; `ConsoleLog` writes synchronously and doesn't need it.
|
|
14
|
+
- `SentryLog` channel — forwards entries to Sentry. `eventLevels` (`fatal` / `error` / `warn` by default) become events (`captureException` for `Error` messages, `captureMessage` otherwise); every other level becomes a breadcrumb. `module` / `action` are tags, `context` is a structured Sentry context. `@sentry/node` is an **optional peer**, lazily imported — pass an existing `client` or `options`.
|
|
15
|
+
- `log.fatal()` + `fatal` log level — ranked strictly above `error` for unrecoverable failures (failed bootstrap, `uncaughtException`). Does not auto-flush or exit; caller decides.
|
|
16
|
+
- `ConsoleLog` renders `fatal` with a `☠` icon on a bright-red background and bold red-bright message, distinct from `error`'s `✗`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `captureAnyUnhandledRejection()` now escalates `uncaughtException` to `log.fatal` (was `log.error`). Node terminates the process by default, so it's semantically fatal — makes "page only on fatal" alerting clean. `unhandledRejection` stays at `error`.
|
|
21
|
+
- `LoggingData.type` is now typed as `LogLevel` (was a duplicated inline union — code-standards cleanup).
|
|
22
|
+
- `LogContract` and the `LogChannel` base now expose an optional `flush?()` alongside the existing `flushSync?()`.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- `@sentry/node` is now referenced only via local minimal types + an indirect dynamic import, so source-served consumers (the package's `main` → `./src/index.ts`) no longer get a `TS2307: Cannot find module '@sentry/node'` when they (correctly) don't install the optional peer. Proven by pruning the SDK and running the full suite + `tsc --noEmit` clean.
|
|
27
|
+
|
|
28
|
+
## 4.1.15
|
|
29
|
+
|
|
30
|
+
- Baseline — per-package changelog tracking starts at this version.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Hassan Zohdy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,145 +1,146 @@
|
|
|
1
|
-
# @warlock.js/logger
|
|
2
|
-
|
|
3
|
-
Structured, multi-channel logging for Node.js —
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @warlock.js/logger
|
|
9
|
-
# or
|
|
10
|
-
yarn add @warlock.js/logger
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## 30-second tour
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { log, ConsoleLog, FileLog } from "@warlock.js/logger";
|
|
17
|
-
|
|
18
|
-
log.setChannels([
|
|
19
|
-
new ConsoleLog(),
|
|
20
|
-
new FileLog({ chunk: "daily" }),
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
await log.info("users", "register", "New user created");
|
|
24
|
-
await log.error("payments", "charge", new Error("Card declined"));
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
The logger starts with no channels — nothing is printed or written until you register at least one.
|
|
28
|
-
|
|
29
|
-
## The module · action · message pattern
|
|
30
|
-
|
|
31
|
-
Every call carries three pieces of context. Modules and actions become searchable keys in file and JSON channels:
|
|
32
|
-
|
|
33
|
-
```ts
|
|
34
|
-
await log.info("auth", "login", "User signed in");
|
|
35
|
-
await log.warn("api", "rateLimitApproaching", "80% of quota used");
|
|
36
|
-
await log.success("payments", "captured", "Payment of $49.99 captured");
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Pass an object instead of positional args when you need `context` metadata:
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
await log.error({
|
|
43
|
-
module: "orders",
|
|
44
|
-
action: "checkout",
|
|
45
|
-
message: "Card declined",
|
|
46
|
-
context: { orderId: "ord_9f2a", amount: 4999 },
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Levels
|
|
51
|
-
|
|
52
|
-
`debug` · `info` · `warn` · `error` · `success` — each has a shorthand method on the `log` singleton (and on every `Logger` instance).
|
|
53
|
-
|
|
54
|
-
## Built-in channels
|
|
55
|
-
|
|
56
|
-
| Channel | Name | Purpose |
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| `ConsoleLog` | `"console"` | Colorized terminal output |
|
|
59
|
-
| `FileLog` | `"file"` | Plain-text files, optional chunking + rotation + grouping |
|
|
60
|
-
| `JSONFileLog` | `"fileJson"` | Structured JSON files — ideal for aggregators |
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- **`
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
1
|
+
# @warlock.js/logger
|
|
2
|
+
|
|
3
|
+
Structured, multi-channel logging for Node.js — six severity levels (debug / info / warn / error / success / fatal), a clean three-argument API, and full TypeScript support. Non-blocking by default; synchronous or async flush on demand.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @warlock.js/logger
|
|
9
|
+
# or
|
|
10
|
+
yarn add @warlock.js/logger
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 30-second tour
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { log, ConsoleLog, FileLog } from "@warlock.js/logger";
|
|
17
|
+
|
|
18
|
+
log.setChannels([
|
|
19
|
+
new ConsoleLog(),
|
|
20
|
+
new FileLog({ chunk: "daily" }),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
await log.info("users", "register", "New user created");
|
|
24
|
+
await log.error("payments", "charge", new Error("Card declined"));
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The logger starts with no channels — nothing is printed or written until you register at least one.
|
|
28
|
+
|
|
29
|
+
## The module · action · message pattern
|
|
30
|
+
|
|
31
|
+
Every call carries three pieces of context. Modules and actions become searchable keys in file and JSON channels:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
await log.info("auth", "login", "User signed in");
|
|
35
|
+
await log.warn("api", "rateLimitApproaching", "80% of quota used");
|
|
36
|
+
await log.success("payments", "captured", "Payment of $49.99 captured");
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Pass an object instead of positional args when you need `context` metadata:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
await log.error({
|
|
43
|
+
module: "orders",
|
|
44
|
+
action: "checkout",
|
|
45
|
+
message: "Card declined",
|
|
46
|
+
context: { orderId: "ord_9f2a", amount: 4999 },
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Levels
|
|
51
|
+
|
|
52
|
+
`debug` · `info` · `warn` · `error` · `success` · `fatal` — each has a shorthand method on the `log` singleton (and on every `Logger` instance). `fatal` is strictly above `error` for unrecoverable failures where the app is going down (failed bootstrap, `uncaughtException`); it does not auto-flush or exit on its own.
|
|
53
|
+
|
|
54
|
+
## Built-in channels
|
|
55
|
+
|
|
56
|
+
| Channel | Name | Purpose |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `ConsoleLog` | `"console"` | Colorized terminal output |
|
|
59
|
+
| `FileLog` | `"file"` | Plain-text files, optional chunking + rotation + grouping |
|
|
60
|
+
| `JSONFileLog` | `"fileJson"` | Structured JSON files — ideal for aggregators |
|
|
61
|
+
| `SentryLog` | `"sentry"` | Forwards to Sentry (events + breadcrumbs); needs the optional `@sentry/node` peer |
|
|
62
|
+
|
|
63
|
+
All channels share the `BasicLogConfigurations` options (`levels`, `filter`, `dateFormat`); `FileLog` / `JSONFileLog` add storage, chunking, rotation, and grouping options, and `SentryLog` adds `client` / `options` / `eventLevels`.
|
|
64
|
+
|
|
65
|
+
## `log` and `Logger`
|
|
66
|
+
|
|
67
|
+
The package exports one default singleton and one class:
|
|
68
|
+
|
|
69
|
+
- **`log`** — a pre-instantiated `Logger`. Day-to-day logging *and* configuration both go through it: `log.info(...)`, `log.configure(...)`, `log.flush()` / `log.flushSync()`, `log.addChannel(...)`.
|
|
70
|
+
- **`Logger`** — the class. Use it when you need an isolated logger (libraries, sandboxes, parallel test suites).
|
|
71
|
+
|
|
72
|
+
`log` is a `Logger` instance, not a function — every level shortcut and configuration method is reachable on it. The bare-callable `log(data)` form was removed; use `log.log(data)` for the data-object form, or `log.info(...)` / `log.error(...)` / etc. for the positional form.
|
|
73
|
+
|
|
74
|
+
## Graceful shutdown
|
|
75
|
+
|
|
76
|
+
`FileLog` and `JSONFileLog` buffer entries. Tell the logger to drain them on exit:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
log.configure({
|
|
80
|
+
channels: [new ConsoleLog(), new FileLog({ chunk: "daily" })],
|
|
81
|
+
autoFlushOn: ["SIGINT", "SIGTERM", "beforeExit"],
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Signal events flush then re-raise (so Node exits with its normal signal semantics); `beforeExit` flushes in place. For full control, call `log.flushSync()` (sync) — or `await log.flush()` (async, for network/async channels) — inside your own handler instead.
|
|
86
|
+
|
|
87
|
+
## Capturing unhandled errors
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { captureAnyUnhandledRejection } from "@warlock.js/logger";
|
|
91
|
+
|
|
92
|
+
captureAnyUnhandledRejection();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Registers process-level handlers for `unhandledRejection` and `uncaughtException`, forwarding both to `log.error("app", ...)`. Call once at startup, after channels are registered.
|
|
96
|
+
|
|
97
|
+
## Custom channels
|
|
98
|
+
|
|
99
|
+
Extend `LogChannel` and implement `log(data)`:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { LogChannel, type LoggingData } from "@warlock.js/logger";
|
|
103
|
+
|
|
104
|
+
export class SlackLog extends LogChannel<{ webhookUrl: string }> {
|
|
105
|
+
public name = "slack";
|
|
106
|
+
|
|
107
|
+
public async log(data: LoggingData) {
|
|
108
|
+
if (!this.shouldBeLogged(data)) return;
|
|
109
|
+
await fetch(this.config("webhookUrl"), {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: { "Content-Type": "application/json" },
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
text: `[${data.type}] [${data.module}][${data.action}]: ${data.message}`,
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Set `terminal = true` on the class if your channel writes to a TTY — otherwise ANSI codes are auto-stripped from string messages.
|
|
121
|
+
|
|
122
|
+
## Full documentation
|
|
123
|
+
|
|
124
|
+
The complete guide lives in the project docs:
|
|
125
|
+
|
|
126
|
+
- Getting Started
|
|
127
|
+
- Configuration
|
|
128
|
+
- Channels (ConsoleLog, FileLog, JSONFileLog, SentryLog)
|
|
129
|
+
- Lifecycle & Flushing
|
|
130
|
+
- Capturing Unhandled Errors
|
|
131
|
+
- Custom Channels
|
|
132
|
+
- Recipes
|
|
133
|
+
- API Reference
|
|
134
|
+
- Types
|
|
135
|
+
|
|
136
|
+
## Tests
|
|
137
|
+
|
|
138
|
+
This package uses Vitest. From the repo root:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npx vitest run --root @warlock.js/logger
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|