@warlock.js/logger 5.24.0 → 5.26.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 +12 -0
- package/README.md +153 -153
- package/cjs/index.cjs.map +1 -1
- package/esm/channels/console-log.mjs.map +1 -1
- package/esm/channels/file-log.mjs.map +1 -1
- package/esm/channels/json-file-log.mjs.map +1 -1
- package/esm/channels/sentry-log.mjs.map +1 -1
- package/esm/log-channel.mjs.map +1 -1
- package/esm/logger.mjs.map +1 -1
- package/esm/utils/capture-unhandled-errors.mjs.map +1 -1
- package/esm/utils/clear-message.mjs.map +1 -1
- package/llms-full.txt +1413 -1413
- package/package.json +2 -2
- package/skills/capture-unhandled-errors/SKILL.md +111 -111
- package/skills/configure-logger/SKILL.md +105 -105
- package/skills/filter-log-entries/SKILL.md +120 -120
- package/skills/flush-logs-on-shutdown/SKILL.md +117 -117
- package/skills/overview/SKILL.md +93 -93
- package/skills/pick-log-channel/SKILL.md +155 -155
- package/skills/redact-sensitive-log-fields/SKILL.md +156 -156
- package/skills/ship-logs-to-sentry/SKILL.md +118 -118
- package/skills/test-logging-code/SKILL.md +177 -177
- package/skills/use-log-helpers/SKILL.md +66 -66
- package/skills/write-custom-log-channel/SKILL.md +190 -190
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to `@warlock.js/logger` are documented in this file.
|
|
|
4
4
|
|
|
5
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
6
|
|
|
7
|
+
## 5.26.0 - 2026-09-30
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Lockstep release; package APIs are unchanged.
|
|
12
|
+
|
|
13
|
+
## 5.25.0 - 2026-09-28
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Lockstep release; package APIs are unchanged.
|
|
18
|
+
|
|
7
19
|
## 5.24.0 - 2026-09-27
|
|
8
20
|
|
|
9
21
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,154 +1,154 @@
|
|
|
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
|
-
## Server-only package
|
|
14
|
-
|
|
15
|
-
`@warlock.js/logger`'s entire runtime surface is server-only. Its `package.json` declares `"warlock": { "environment": "server" }` — build-boundary metadata that `@warlock.js/web`'s Gate A (import resolution) and Gate C (emitted-bundle verification) read to keep it out of the browser bundle.
|
|
16
|
-
|
|
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
|
+
## Server-only package
|
|
14
|
+
|
|
15
|
+
`@warlock.js/logger`'s entire runtime surface is server-only. Its `package.json` declares `"warlock": { "environment": "server" }` — build-boundary metadata that `@warlock.js/web`'s Gate A (import resolution) and Gate C (emitted-bundle verification) read to keep it out of the browser bundle.
|
|
16
|
+
|
|
17
17
|
- App code that reaches the client bundle (including page and layout modules) must not value-import `@warlock.js/logger` — Gate A refuses the build.
|
|
18
|
-
- A type-only import (`import type { ... } from "@warlock.js/logger"`) is allowed — it carries no runtime edge.
|
|
19
|
-
- Server loaders, controllers, and modules may import it freely.
|
|
20
|
-
|
|
21
|
-
## 30-second tour
|
|
22
|
-
|
|
23
|
-
```ts
|
|
24
|
-
import { log, ConsoleLog, FileLog } from "@warlock.js/logger";
|
|
25
|
-
|
|
26
|
-
log.setChannels([
|
|
27
|
-
new ConsoleLog(),
|
|
28
|
-
new FileLog({ chunk: "daily" }),
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
await log.info("users", "register", "New user created");
|
|
32
|
-
await log.error("payments", "charge", new Error("Card declined"));
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The logger starts with no channels — nothing is printed or written until you register at least one.
|
|
36
|
-
|
|
37
|
-
## The module · action · message pattern
|
|
38
|
-
|
|
39
|
-
Every call carries three pieces of context. Modules and actions become searchable keys in file and JSON channels:
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
await log.info("auth", "login", "User signed in");
|
|
43
|
-
await log.warn("api", "rateLimitApproaching", "80% of quota used");
|
|
44
|
-
await log.success("payments", "captured", "Payment of $49.99 captured");
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Pass an object instead of positional args when you need `context` metadata:
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
await log.error({
|
|
51
|
-
module: "orders",
|
|
52
|
-
action: "checkout",
|
|
53
|
-
message: "Card declined",
|
|
54
|
-
context: { orderId: "ord_9f2a", amount: 4999 },
|
|
55
|
-
});
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Levels
|
|
59
|
-
|
|
60
|
-
`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.
|
|
61
|
-
|
|
62
|
-
## Built-in channels
|
|
63
|
-
|
|
64
|
-
| Channel | Name | Purpose |
|
|
65
|
-
|---|---|---|
|
|
66
|
-
| `ConsoleLog` | `"console"` | Colorized terminal output |
|
|
67
|
-
| `FileLog` | `"file"` | Plain-text files, optional chunking + rotation + grouping |
|
|
68
|
-
| `JSONFileLog` | `"fileJson"` | Structured JSON files — ideal for aggregators |
|
|
69
|
-
| `SentryLog` | `"sentry"` | Forwards to Sentry (events + breadcrumbs); needs the optional `@sentry/node` peer |
|
|
70
|
-
|
|
71
|
-
All channels share the `BasicLogConfigurations` options (`levels`, `filter`, `dateFormat`); `FileLog` / `JSONFileLog` add storage, chunking, rotation, and grouping options, and `SentryLog` adds `client` / `options` / `eventLevels`.
|
|
72
|
-
|
|
73
|
-
## `log` and `Logger`
|
|
74
|
-
|
|
75
|
-
The package exports one default singleton and one class:
|
|
76
|
-
|
|
77
|
-
- **`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(...)`.
|
|
78
|
-
- **`Logger`** — the class. Use it when you need an isolated logger (libraries, sandboxes, parallel test suites).
|
|
79
|
-
|
|
80
|
-
`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.
|
|
81
|
-
|
|
82
|
-
## Graceful shutdown
|
|
83
|
-
|
|
84
|
-
`FileLog` and `JSONFileLog` buffer entries. Tell the logger to drain them on exit:
|
|
85
|
-
|
|
86
|
-
```ts
|
|
87
|
-
log.configure({
|
|
88
|
-
channels: [new ConsoleLog(), new FileLog({ chunk: "daily" })],
|
|
89
|
-
autoFlushOn: ["SIGINT", "SIGTERM", "beforeExit"],
|
|
90
|
-
});
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
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.
|
|
94
|
-
|
|
95
|
-
## Capturing unhandled errors
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
import { captureAnyUnhandledRejection } from "@warlock.js/logger";
|
|
99
|
-
|
|
100
|
-
captureAnyUnhandledRejection();
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Registers process-level handlers for `unhandledRejection` (→ `log.error("app", ...)`, process kept alive) and `uncaughtException` (→ `log.fatal("app", ...)`, then `process.exit(1)` so a fatal crash is never silently swallowed into `exit 0`). Pass `{ exitOnUncaughtException: false }` to log without exiting. Call once at startup, after channels are registered.
|
|
104
|
-
|
|
105
|
-
## Custom channels
|
|
106
|
-
|
|
107
|
-
Extend `LogChannel` and implement `log(data)`:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { LogChannel, type LoggingData } from "@warlock.js/logger";
|
|
111
|
-
|
|
112
|
-
export class SlackLog extends LogChannel<{ webhookUrl: string }> {
|
|
113
|
-
public name = "slack";
|
|
114
|
-
|
|
115
|
-
public async log(data: LoggingData) {
|
|
116
|
-
if (!this.shouldBeLogged(data)) return;
|
|
117
|
-
await fetch(this.config("webhookUrl"), {
|
|
118
|
-
method: "POST",
|
|
119
|
-
headers: { "Content-Type": "application/json" },
|
|
120
|
-
body: JSON.stringify({
|
|
121
|
-
text: `[${data.type}] [${data.module}][${data.action}]: ${data.message}`,
|
|
122
|
-
}),
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Set `terminal = true` on the class if your channel writes to a TTY — otherwise ANSI codes are auto-stripped from string messages.
|
|
129
|
-
|
|
130
|
-
## Full documentation
|
|
131
|
-
|
|
132
|
-
The complete guide lives in the project docs:
|
|
133
|
-
|
|
134
|
-
- Getting Started
|
|
135
|
-
- Configuration
|
|
136
|
-
- Channels (ConsoleLog, FileLog, JSONFileLog, SentryLog)
|
|
137
|
-
- Lifecycle & Flushing
|
|
138
|
-
- Capturing Unhandled Errors
|
|
139
|
-
- Custom Channels
|
|
140
|
-
- Recipes
|
|
141
|
-
- API Reference
|
|
142
|
-
- Types
|
|
143
|
-
|
|
144
|
-
## Tests
|
|
145
|
-
|
|
146
|
-
This package uses Vitest. From the repo root:
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
npx vitest run --root @warlock.js/logger
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## License
|
|
153
|
-
|
|
154
|
-
MIT
|
|
18
|
+
- A type-only import (`import type { ... } from "@warlock.js/logger"`) is allowed — it carries no runtime edge.
|
|
19
|
+
- Server loaders, controllers, and modules may import it freely.
|
|
20
|
+
|
|
21
|
+
## 30-second tour
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { log, ConsoleLog, FileLog } from "@warlock.js/logger";
|
|
25
|
+
|
|
26
|
+
log.setChannels([
|
|
27
|
+
new ConsoleLog(),
|
|
28
|
+
new FileLog({ chunk: "daily" }),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
await log.info("users", "register", "New user created");
|
|
32
|
+
await log.error("payments", "charge", new Error("Card declined"));
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The logger starts with no channels — nothing is printed or written until you register at least one.
|
|
36
|
+
|
|
37
|
+
## The module · action · message pattern
|
|
38
|
+
|
|
39
|
+
Every call carries three pieces of context. Modules and actions become searchable keys in file and JSON channels:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
await log.info("auth", "login", "User signed in");
|
|
43
|
+
await log.warn("api", "rateLimitApproaching", "80% of quota used");
|
|
44
|
+
await log.success("payments", "captured", "Payment of $49.99 captured");
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Pass an object instead of positional args when you need `context` metadata:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
await log.error({
|
|
51
|
+
module: "orders",
|
|
52
|
+
action: "checkout",
|
|
53
|
+
message: "Card declined",
|
|
54
|
+
context: { orderId: "ord_9f2a", amount: 4999 },
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Levels
|
|
59
|
+
|
|
60
|
+
`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.
|
|
61
|
+
|
|
62
|
+
## Built-in channels
|
|
63
|
+
|
|
64
|
+
| Channel | Name | Purpose |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `ConsoleLog` | `"console"` | Colorized terminal output |
|
|
67
|
+
| `FileLog` | `"file"` | Plain-text files, optional chunking + rotation + grouping |
|
|
68
|
+
| `JSONFileLog` | `"fileJson"` | Structured JSON files — ideal for aggregators |
|
|
69
|
+
| `SentryLog` | `"sentry"` | Forwards to Sentry (events + breadcrumbs); needs the optional `@sentry/node` peer |
|
|
70
|
+
|
|
71
|
+
All channels share the `BasicLogConfigurations` options (`levels`, `filter`, `dateFormat`); `FileLog` / `JSONFileLog` add storage, chunking, rotation, and grouping options, and `SentryLog` adds `client` / `options` / `eventLevels`.
|
|
72
|
+
|
|
73
|
+
## `log` and `Logger`
|
|
74
|
+
|
|
75
|
+
The package exports one default singleton and one class:
|
|
76
|
+
|
|
77
|
+
- **`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(...)`.
|
|
78
|
+
- **`Logger`** — the class. Use it when you need an isolated logger (libraries, sandboxes, parallel test suites).
|
|
79
|
+
|
|
80
|
+
`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.
|
|
81
|
+
|
|
82
|
+
## Graceful shutdown
|
|
83
|
+
|
|
84
|
+
`FileLog` and `JSONFileLog` buffer entries. Tell the logger to drain them on exit:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
log.configure({
|
|
88
|
+
channels: [new ConsoleLog(), new FileLog({ chunk: "daily" })],
|
|
89
|
+
autoFlushOn: ["SIGINT", "SIGTERM", "beforeExit"],
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
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.
|
|
94
|
+
|
|
95
|
+
## Capturing unhandled errors
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { captureAnyUnhandledRejection } from "@warlock.js/logger";
|
|
99
|
+
|
|
100
|
+
captureAnyUnhandledRejection();
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Registers process-level handlers for `unhandledRejection` (→ `log.error("app", ...)`, process kept alive) and `uncaughtException` (→ `log.fatal("app", ...)`, then `process.exit(1)` so a fatal crash is never silently swallowed into `exit 0`). Pass `{ exitOnUncaughtException: false }` to log without exiting. Call once at startup, after channels are registered.
|
|
104
|
+
|
|
105
|
+
## Custom channels
|
|
106
|
+
|
|
107
|
+
Extend `LogChannel` and implement `log(data)`:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { LogChannel, type LoggingData } from "@warlock.js/logger";
|
|
111
|
+
|
|
112
|
+
export class SlackLog extends LogChannel<{ webhookUrl: string }> {
|
|
113
|
+
public name = "slack";
|
|
114
|
+
|
|
115
|
+
public async log(data: LoggingData) {
|
|
116
|
+
if (!this.shouldBeLogged(data)) return;
|
|
117
|
+
await fetch(this.config("webhookUrl"), {
|
|
118
|
+
method: "POST",
|
|
119
|
+
headers: { "Content-Type": "application/json" },
|
|
120
|
+
body: JSON.stringify({
|
|
121
|
+
text: `[${data.type}] [${data.module}][${data.action}]: ${data.message}`,
|
|
122
|
+
}),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Set `terminal = true` on the class if your channel writes to a TTY — otherwise ANSI codes are auto-stripped from string messages.
|
|
129
|
+
|
|
130
|
+
## Full documentation
|
|
131
|
+
|
|
132
|
+
The complete guide lives in the project docs:
|
|
133
|
+
|
|
134
|
+
- Getting Started
|
|
135
|
+
- Configuration
|
|
136
|
+
- Channels (ConsoleLog, FileLog, JSONFileLog, SentryLog)
|
|
137
|
+
- Lifecycle & Flushing
|
|
138
|
+
- Capturing Unhandled Errors
|
|
139
|
+
- Custom Channels
|
|
140
|
+
- Recipes
|
|
141
|
+
- API Reference
|
|
142
|
+
- Types
|
|
143
|
+
|
|
144
|
+
## Tests
|
|
145
|
+
|
|
146
|
+
This package uses Vitest. From the repo root:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx vitest run --root @warlock.js/logger
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|