@warlock.js/logger 4.0.174 → 4.1.2

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.
Files changed (135) hide show
  1. package/README.md +145 -422
  2. package/cjs/index.cjs +1003 -0
  3. package/cjs/index.cjs.map +1 -0
  4. package/esm/channels/console-log.d.mts +40 -0
  5. package/esm/channels/console-log.d.mts.map +1 -0
  6. package/esm/channels/console-log.mjs +51 -0
  7. package/esm/channels/console-log.mjs.map +1 -0
  8. package/esm/channels/file-log.d.mts +194 -0
  9. package/esm/channels/file-log.d.mts.map +1 -0
  10. package/esm/channels/file-log.mjs +267 -0
  11. package/esm/channels/file-log.mjs.map +1 -0
  12. package/esm/channels/index.mjs +5 -0
  13. package/esm/channels/json-file-log.d.mts +33 -0
  14. package/esm/channels/json-file-log.d.mts.map +1 -0
  15. package/esm/channels/json-file-log.mjs +137 -0
  16. package/esm/channels/json-file-log.mjs.map +1 -0
  17. package/esm/index.d.mts +11 -0
  18. package/esm/index.mjs +13 -0
  19. package/esm/log-channel.d.mts +78 -0
  20. package/esm/log-channel.d.mts.map +1 -0
  21. package/esm/log-channel.mjs +75 -0
  22. package/esm/log-channel.mjs.map +1 -0
  23. package/esm/logger.d.mts +184 -0
  24. package/esm/logger.d.mts.map +1 -0
  25. package/esm/logger.mjs +282 -0
  26. package/esm/logger.mjs.map +1 -0
  27. package/esm/redact/redact.d.mts +25 -0
  28. package/esm/redact/redact.d.mts.map +1 -0
  29. package/esm/redact/redact.mjs +109 -0
  30. package/esm/redact/redact.mjs.map +1 -0
  31. package/esm/types.d.mts +129 -0
  32. package/esm/types.d.mts.map +1 -0
  33. package/esm/utils/capture-unhandled-errors.d.mts +16 -0
  34. package/esm/utils/capture-unhandled-errors.d.mts.map +1 -0
  35. package/esm/utils/capture-unhandled-errors.mjs +26 -0
  36. package/esm/utils/capture-unhandled-errors.mjs.map +1 -0
  37. package/esm/utils/clear-message.d.mts +8 -0
  38. package/esm/utils/clear-message.d.mts.map +1 -0
  39. package/esm/utils/clear-message.mjs +12 -0
  40. package/esm/utils/clear-message.mjs.map +1 -0
  41. package/esm/utils/index.mjs +5 -0
  42. package/esm/utils/safe-json-stringify.d.mts +14 -0
  43. package/esm/utils/safe-json-stringify.d.mts.map +1 -0
  44. package/esm/utils/safe-json-stringify.mjs +35 -0
  45. package/esm/utils/safe-json-stringify.mjs.map +1 -0
  46. package/llms-full.txt +1296 -0
  47. package/llms.txt +19 -0
  48. package/package.json +39 -39
  49. package/skills/capture-unhandled-errors/SKILL.md +103 -0
  50. package/skills/configure-logger/SKILL.md +105 -0
  51. package/skills/filter-log-entries/SKILL.md +120 -0
  52. package/skills/flush-logs-on-shutdown/SKILL.md +91 -0
  53. package/skills/logger-basics/SKILL.md +85 -0
  54. package/skills/overview/SKILL.md +86 -0
  55. package/skills/pick-log-channel/SKILL.md +139 -0
  56. package/skills/redact-sensitive-log-fields/SKILL.md +122 -0
  57. package/skills/test-logging-code/SKILL.md +169 -0
  58. package/skills/use-log-helpers/SKILL.md +66 -0
  59. package/skills/write-custom-log-channel/SKILL.md +160 -0
  60. package/cjs/channels/console-log.d.ts +0 -17
  61. package/cjs/channels/console-log.d.ts.map +0 -1
  62. package/cjs/channels/console-log.js +0 -47
  63. package/cjs/channels/console-log.js.map +0 -1
  64. package/cjs/channels/file-log.d.ts +0 -171
  65. package/cjs/channels/file-log.d.ts.map +0 -1
  66. package/cjs/channels/file-log.js +0 -293
  67. package/cjs/channels/file-log.js.map +0 -1
  68. package/cjs/channels/index.d.ts +0 -4
  69. package/cjs/channels/index.d.ts.map +0 -1
  70. package/cjs/channels/json-file-log.d.ts +0 -33
  71. package/cjs/channels/json-file-log.d.ts.map +0 -1
  72. package/cjs/channels/json-file-log.js +0 -164
  73. package/cjs/channels/json-file-log.js.map +0 -1
  74. package/cjs/index.d.ts +0 -6
  75. package/cjs/index.d.ts.map +0 -1
  76. package/cjs/index.js +0 -1
  77. package/cjs/index.js.map +0 -1
  78. package/cjs/log-channel.d.ts +0 -67
  79. package/cjs/log-channel.d.ts.map +0 -1
  80. package/cjs/log-channel.js +0 -88
  81. package/cjs/log-channel.js.map +0 -1
  82. package/cjs/logger.d.ts +0 -62
  83. package/cjs/logger.d.ts.map +0 -1
  84. package/cjs/logger.js +0 -124
  85. package/cjs/logger.js.map +0 -1
  86. package/cjs/types.d.ts +0 -104
  87. package/cjs/types.d.ts.map +0 -1
  88. package/cjs/utils/capture-unhandled-errors.d.ts +0 -2
  89. package/cjs/utils/capture-unhandled-errors.d.ts.map +0 -1
  90. package/cjs/utils/capture-unhandled-errors.js +0 -12
  91. package/cjs/utils/capture-unhandled-errors.js.map +0 -1
  92. package/cjs/utils/clear-message.d.ts +0 -5
  93. package/cjs/utils/clear-message.d.ts.map +0 -1
  94. package/cjs/utils/clear-message.js +0 -9
  95. package/cjs/utils/clear-message.js.map +0 -1
  96. package/cjs/utils/index.d.ts +0 -3
  97. package/cjs/utils/index.d.ts.map +0 -1
  98. package/esm/channels/console-log.d.ts +0 -17
  99. package/esm/channels/console-log.d.ts.map +0 -1
  100. package/esm/channels/console-log.js +0 -47
  101. package/esm/channels/console-log.js.map +0 -1
  102. package/esm/channels/file-log.d.ts +0 -171
  103. package/esm/channels/file-log.d.ts.map +0 -1
  104. package/esm/channels/file-log.js +0 -293
  105. package/esm/channels/file-log.js.map +0 -1
  106. package/esm/channels/index.d.ts +0 -4
  107. package/esm/channels/index.d.ts.map +0 -1
  108. package/esm/channels/json-file-log.d.ts +0 -33
  109. package/esm/channels/json-file-log.d.ts.map +0 -1
  110. package/esm/channels/json-file-log.js +0 -164
  111. package/esm/channels/json-file-log.js.map +0 -1
  112. package/esm/index.d.ts +0 -6
  113. package/esm/index.d.ts.map +0 -1
  114. package/esm/index.js +0 -1
  115. package/esm/index.js.map +0 -1
  116. package/esm/log-channel.d.ts +0 -67
  117. package/esm/log-channel.d.ts.map +0 -1
  118. package/esm/log-channel.js +0 -88
  119. package/esm/log-channel.js.map +0 -1
  120. package/esm/logger.d.ts +0 -62
  121. package/esm/logger.d.ts.map +0 -1
  122. package/esm/logger.js +0 -124
  123. package/esm/logger.js.map +0 -1
  124. package/esm/types.d.ts +0 -104
  125. package/esm/types.d.ts.map +0 -1
  126. package/esm/utils/capture-unhandled-errors.d.ts +0 -2
  127. package/esm/utils/capture-unhandled-errors.d.ts.map +0 -1
  128. package/esm/utils/capture-unhandled-errors.js +0 -12
  129. package/esm/utils/capture-unhandled-errors.js.map +0 -1
  130. package/esm/utils/clear-message.d.ts +0 -5
  131. package/esm/utils/clear-message.d.ts.map +0 -1
  132. package/esm/utils/clear-message.js +0 -9
  133. package/esm/utils/clear-message.js.map +0 -1
  134. package/esm/utils/index.d.ts +0 -3
  135. package/esm/utils/index.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,422 +1,145 @@
1
- # Warlock Logger
2
-
3
- A powerful yet simple logger for Node.js
4
-
5
- ## Features
6
-
7
- - Fully async and non-blocking which doesn't affect the performance of your application.
8
- - Easy to use and configure.
9
- - Has multiple channels to log the messages to.
10
- - You can add your own custom channels for logging.
11
-
12
- ## Installation
13
-
14
- `yarn add @warlock.js/logger`
15
-
16
- Or
17
-
18
- `npm i @warlock.js/logger`
19
-
20
- ## Usage
21
-
22
- At an early point of the application, you need to initialize the logger:
23
-
24
- ```ts
25
- import logger, { FileLog } from "@warlock.js/logger";
26
-
27
- logger.configure({
28
- channels: [new FileLog(), new ConsoleLog()],
29
- });
30
- ```
31
-
32
- Here we declared our logger configurations to use the `FileLog` and `ConsoleLog` channels, the file log channel will log all the logs to a file, and the console log channel will log all the logs to the console.
33
-
34
- ## Logging Strategy
35
-
36
- To go any value simple use `log` function, it mainly receives 4 parameters:
37
-
38
- - `module`: the module name, it's used to group the logs, for example, if you have a module called `request`, all the logs related to the request module will be grouped under the `request` module.
39
- - `action`: the action name, it's used to group the logs, for example, if you have an action called `create`, all the logs related to the `create` action will be grouped under the `create` action.
40
- - `message`: the message to log.
41
- - `level`: there are 4 types of logging `warn`, `info`, `error`, `debug`, the default is `info`.
42
-
43
- ## Examples
44
-
45
- ```ts
46
- import { log } from "@warlock.js/logger";
47
-
48
- log("request", "create", "user created successfully", "info");
49
- ```
50
-
51
- You can also use `log.info` `log.warn` `log.error` `log.debug` `log.success` functions to log the message.
52
-
53
- ```ts
54
- import { log } from "@warlock.js/logger";
55
-
56
- log.info("request", "create", "user created successfully");
57
-
58
- if (somethingWentWrong) {
59
- log.error("request", "create", "something went wrong");
60
- }
61
-
62
- database.on("connection", () => {
63
- log.success("database", "connection", "database connected successfully");
64
- });
65
- ```
66
-
67
- ## Console Log Channel
68
-
69
- The console log channel will log all the logs to the console, the message appears in the console will be colored based on the log level using [copper](https://www.npmjs.com/package/@mongez/copper).
70
-
71
- ```ts
72
- import logger, { ConsoleLog } from "@warlock.js/logger";
73
-
74
- logger.configure({
75
- channels: [new ConsoleLog()],
76
- });
77
- ```
78
-
79
- ## File Log Channel
80
-
81
- The file log channel will log all the logs to a **single file**, the file will be created in the `logs` directory in `/storage` directory with name `app` by default, and extension is set to `log` however, you can change the file name and the directory path.
82
-
83
- ```ts
84
- import logger, { FileLog } from "@warlock.js/logger";
85
-
86
- logger.configure({
87
- channels: [
88
- new FileLog({
89
- storageDirectory: process.cwd() + "/logs",
90
- fileName: "app",
91
- extension: "log",
92
- }),
93
- ],
94
- });
95
- ```
96
-
97
- The message time is stored by default prefixed with current date/time in this format `YYYY-MM-DD HH:mm:ss`, however, you can change the format by passing the `dateFormat` option.
98
-
99
- ```ts
100
- import logger, { FileLog } from "@warlock.js/logger";
101
-
102
- logger.configure({
103
- channels: [
104
- new FileLog({
105
- dateFormat: {
106
- date: "DD-MM-YYYY",
107
- time: "HH:mm:ss",
108
- },
109
- }),
110
- ],
111
- });
112
- ```
113
-
114
- > You can see the available date/time formats in [dayjs](https://day.js.org/docs/en/display/format) documentation.
115
-
116
- This could be useful with small projects, but it's not recommended to use it if the application is large, because the file will be very large and it will affect the performance of the application, you can use the following channels to solve this problem.
117
-
118
- ## Chunk mode Log Channel
119
-
120
- In the file log channel, there are three types of chunk modes:
121
-
122
- 1. `single`: this is the default mode, all the logs will be stored in a single file.
123
- 2. `daily`: the logs will be stored in a file based on the date, for example, if the date is `2021-01-01`, the file name will be `2021-01-01.log`.
124
- 3. `hourly`: the logs will be stored in a file based on the date and hour, for example, if the hour is `14`, the file name will be `2021-01-01-14.log`.
125
-
126
- > Please note the hourly mode is set to 24 hours mode.
127
-
128
- ```ts
129
- import logger, { FileLog } from "@warlock.js/logger";
130
-
131
- logger.configure({
132
- channels: [
133
- new FileLog({
134
- chunk: "daily", // default is single
135
- }),
136
- ],
137
- });
138
- ```
139
-
140
- For better performance, the file will be created in the `logs` directory in `/storage`, each file will be named based on the date, for example, if the date is `2021-01-01`, the file name will be `2021-01-01.log`, and the message time is stored by default prefixed with current date/time in this format `YYYY-MM-DD HH:mm:ss`, however, you can change the format by passing the `dateFormat` option.
141
-
142
- ## Allow certain levels
143
-
144
- You can allow certain levels to be logged, for example, if you want to log only the `info` and `error` messages, you can use the `levels` option.
145
-
146
- ```ts
147
- import logger, { FileLog } from "@warlock.js/logger";
148
-
149
- logger.configure({
150
- channels: [
151
- new FileLog({
152
- levels: ["info", "error"],
153
- }),
154
- ],
155
- });
156
- ```
157
-
158
- This allows only the `info` and `error` messages to be logged.
159
-
160
- ## Advanced Filter messages
161
-
162
- Another way to filter the messages is to use the `filter` option, the filter function will receive the message info and you can return `true` to log the message or `false` to ignore it.
163
-
164
- ```ts
165
- import logger, { FileLog } from "@warlock.js/logger";
166
-
167
- logger.configure({
168
- channels: [
169
- new FileLog({
170
- filter: ({ level, module, action }) => level !== "debug",
171
- }),
172
- ],
173
- });
174
- ```
175
-
176
- This will log all the messages except the `debug` messages.
177
-
178
- ## JSON File Log Channel
179
-
180
- Works exactly in the same sense of [File Log Channel](#file-log-channel), but the difference is that the logs will be stored in JSON format.
181
-
182
- ```ts
183
- import logger, { JSONFileLog } from "@warlock.js/logger";
184
-
185
- logger.configure({
186
- channels: [new JSONFileLog()],
187
- });
188
- ```
189
-
190
- Example of output log file
191
-
192
- `/storage/logs/app.json`
193
-
194
- ```json
195
- {
196
- "messages": [
197
- {
198
- "module": "request",
199
- "action": "create",
200
- "message": "user created successfully",
201
- "level": "info",
202
- "date": "01-04-2023",
203
- "time": "12:00:00"
204
- }
205
- ]
206
- }
207
- ```
208
-
209
- If the log is an `error` log, the trace will also be included:
210
-
211
- `/storage/logs/01-04-2023.json`
212
-
213
- ```json
214
- {
215
- "date": "01-04-2023",
216
- "logs": [
217
- {
218
- "module": "request",
219
- "action": "create",
220
- "message": "user created successfully",
221
- "level": "error",
222
- "date": "01-04-2023",
223
- "time": "12:00:00",
224
- "trace": "Error: something went wrong...."
225
- }
226
- ]
227
- }
228
- ```
229
-
230
- ## Group Log Channel by level, module or action
231
-
232
- Another way to reduce file sizes is to group the logs by level, module, or action, you can use the `groupBy` option to group the logs.
233
-
234
- The files in this case will be added in folders with the grouped names, for example, if the group is `level`, the files will be added in folders with the names `info`, `warn`, `error`, and `debug`.
235
-
236
- ```ts
237
- import logger, { FileLog } from "@warlock.js/logger";
238
-
239
- logger.configure({
240
- channels: [
241
- new FileLog({
242
- groupBy: ["level"],
243
- }),
244
- ],
245
- });
246
- ```
247
-
248
- This will create the following structure:
249
-
250
- ```
251
- logs
252
- ├── info
253
- │ └── app.log
254
- ├── warn
255
- │ └── app.log
256
- ├── error
257
- │ └── app.log
258
- ├── debug
259
- │ └── app.log
260
- ├── success
261
- │ └── app.log
262
- ```
263
-
264
- If the group is `module`, the files will be added in folders with the module names.
265
-
266
- ```ts
267
- import logger, { FileLog } from "@warlock.js/logger";
268
-
269
- logger.configure({
270
- channels: [
271
- new FileLog({
272
- groupBy: ["module"],
273
- }),
274
- ],
275
- });
276
- ```
277
-
278
- This will create the following structure:
279
-
280
- ```
281
- logs
282
- ├── request
283
- │ └── app.log
284
- ├── database
285
- │ └── app.log
286
- ```
287
-
288
- ### Group by multiple options
289
-
290
- You can group the logs by multiple options, for example, if you want to group the logs by `level` and `module`, you can pass the options
291
-
292
- ```ts
293
- import logger, { FileLog } from "@warlock.js/logger";
294
-
295
- logger.configure({
296
- channels: [
297
- new FileLog({
298
- groupBy: ["level", "module"],
299
- }),
300
- ],
301
- });
302
- ```
303
-
304
- This will create the following structure:
305
-
306
- ```
307
- logs
308
- ├── info
309
- │ ├── request
310
- │ │ └── app.log
311
- ...
312
- ```
313
-
314
- > The order you set in the groupBy array will be the order of the folders.
315
-
316
- ## Create Custom Log Channel
317
-
318
- You can create your own log channel by extending the `LogChannel` class
319
-
320
- ```ts
321
- import {
322
- LogChannel,
323
- type LogContract,
324
- type LogLevel,
325
- type BasicLogConfigurations,
326
- } from "@warlock.js/logger";
327
-
328
- export type CustomLogOptions = BasicLogConfigurations & {
329
- // your custom options
330
- };
331
-
332
- export default class CustomLogChannel
333
- extends LogChannel<CustomLogOptions>
334
- implements LogContract
335
- {
336
- /**
337
- * Channel name
338
- */
339
- public name = "custom";
340
-
341
- /**
342
- * Log the message
343
- *
344
- * @param module
345
- * @param action
346
- * @param message
347
- * @param level
348
- */
349
- public async log(
350
- module: string,
351
- action: string,
352
- message: string,
353
- level: LogLevel
354
- ) {
355
- // first check if the message should be logged or not
356
- if (!this.shouldBeLogged({ module, action, level })) return;
357
-
358
- // log the message
359
- }
360
- }
361
- ```
362
-
363
- The `CustomLogChannel` class extends the `LogChannel` class and implements the `LogContract` interface, you can add your custom options by extending the `BasicLogConfigurations` interface.
364
-
365
- The `BasicLogConfigurations` interface has the following options:
366
-
367
- - `levels`: an array of levels to log, the default is `["info", "warn", "error", "debug"]`.
368
- - `filter`: a function to filter the messages, the default is `() => true`.
369
-
370
- These options are used in `shouldBeLogged` method to check if the message should be logged or not.
371
-
372
- If the log channel will output something in the terminal, mark the `terminal` property as `true`.
373
-
374
- ```ts
375
- import { type LogContract, LogChannel, LogLevel } from "@warlock.js/logger";
376
-
377
- export default class CustomLogChannel
378
- extends LogChannel
379
- implements LogContract
380
- {
381
- /**
382
- * Whether the log channel will output something in the terminal
383
- */
384
- public terminal = true;
385
-
386
- /**
387
- * Channel name
388
- */
389
- public name = "custom";
390
- // ...
391
- }
392
- ```
393
-
394
- This will automatically parse and remove the ANSI color codes from the message.
395
-
396
- Now you can use the custom log channel in your application.
397
-
398
- ```ts
399
- import logger, { CustomLogChannel } from "@warlock.js/logger";
400
-
401
- logger.configure({
402
- channels: [new CustomLogChannel()],
403
- });
404
- ```
405
-
406
- ## Capture Uncaught Errors
407
-
408
- If you want automatically capture any unhandled errors, you can import `captureAnyUnhandledRejection` helper function and call it in your application entry point.
409
-
410
- ```ts
411
- import { captureAnyUnhandledRejection } from "@warlock.js/logger";
412
-
413
- captureAnyUnhandledRejection();
414
- ```
415
-
416
- ## Tests
417
-
418
- To run the tests, you need to run the following command:
419
-
420
- ```bash
421
- yarn test
422
- ```
1
+ # @warlock.js/logger
2
+
3
+ Structured, multi-channel logging for Node.js — five severity levels, a clean three-argument API, and full TypeScript support. Non-blocking by default; synchronous 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` — 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
+ All three share the `BasicLogConfigurations` options (`levels`, `filter`, `dateFormat`); `FileLog` / `JSONFileLog` add storage, chunking, rotation, and grouping options on top.
63
+
64
+ ## `log` and `Logger`
65
+
66
+ The package exports one default singleton and one class:
67
+
68
+ - **`log`** — a pre-instantiated `Logger`. Day-to-day logging *and* configuration both go through it: `log.info(...)`, `log.configure(...)`, `log.flushSync()`, `log.addChannel(...)`.
69
+ - **`Logger`** the class. Use it when you need an isolated logger (libraries, sandboxes, parallel test suites).
70
+
71
+ `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.
72
+
73
+ ## Graceful shutdown
74
+
75
+ `FileLog` and `JSONFileLog` buffer entries. Tell the logger to drain them on exit:
76
+
77
+ ```ts
78
+ log.configure({
79
+ channels: [new ConsoleLog(), new FileLog({ chunk: "daily" })],
80
+ autoFlushOn: ["SIGINT", "SIGTERM", "beforeExit"],
81
+ });
82
+ ```
83
+
84
+ Signal events flush then re-raise (so Node exits with its normal signal semantics); `beforeExit` flushes in place. For full control, call `log.flushSync()` manually inside your own handler instead.
85
+
86
+ ## Capturing unhandled errors
87
+
88
+ ```ts
89
+ import { captureAnyUnhandledRejection } from "@warlock.js/logger";
90
+
91
+ captureAnyUnhandledRejection();
92
+ ```
93
+
94
+ Registers process-level handlers for `unhandledRejection` and `uncaughtException`, forwarding both to `log.error("app", ...)`. Call once at startup, after channels are registered.
95
+
96
+ ## Custom channels
97
+
98
+ Extend `LogChannel` and implement `log(data)`:
99
+
100
+ ```ts
101
+ import { LogChannel, type LoggingData } from "@warlock.js/logger";
102
+
103
+ export class SlackLog extends LogChannel<{ webhookUrl: string }> {
104
+ public name = "slack";
105
+
106
+ public async log(data: LoggingData) {
107
+ if (!this.shouldBeLogged(data)) return;
108
+ await fetch(this.config("webhookUrl"), {
109
+ method: "POST",
110
+ headers: { "Content-Type": "application/json" },
111
+ body: JSON.stringify({
112
+ text: `[${data.type}] [${data.module}][${data.action}]: ${data.message}`,
113
+ }),
114
+ });
115
+ }
116
+ }
117
+ ```
118
+
119
+ Set `terminal = true` on the class if your channel writes to a TTY — otherwise ANSI codes are auto-stripped from string messages.
120
+
121
+ ## Full documentation
122
+
123
+ The complete guide lives in the project docs:
124
+
125
+ - Getting Started
126
+ - Configuration
127
+ - Channels (ConsoleLog, FileLog, JSONFileLog)
128
+ - Lifecycle & Flushing
129
+ - Capturing Unhandled Errors
130
+ - Custom Channels
131
+ - Recipes
132
+ - API Reference
133
+ - Types
134
+
135
+ ## Tests
136
+
137
+ This package uses Vitest. From the repo root:
138
+
139
+ ```bash
140
+ npx vitest run --root @warlock.js/logger
141
+ ```
142
+
143
+ ## License
144
+
145
+ MIT