scribelog 1.1.1 β†’ 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.
Files changed (53) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +384 -142
  3. package/dist/adapters/express.d.ts +17 -0
  4. package/dist/adapters/express.js +56 -0
  5. package/dist/adapters/express.js.map +1 -0
  6. package/dist/adapters/fastify.d.ts +17 -0
  7. package/dist/adapters/fastify.js +81 -0
  8. package/dist/adapters/fastify.js.map +1 -0
  9. package/dist/adapters/koa.d.ts +17 -0
  10. package/dist/adapters/koa.js +74 -0
  11. package/dist/adapters/koa.js.map +1 -0
  12. package/dist/adapters/nest.d.ts +16 -0
  13. package/dist/adapters/nest.js +78 -0
  14. package/dist/adapters/nest.js.map +1 -0
  15. package/dist/adapters/next.d.ts +14 -0
  16. package/dist/adapters/next.js +54 -0
  17. package/dist/adapters/next.js.map +1 -0
  18. package/dist/format.d.ts +25 -8
  19. package/dist/format.js +178 -69
  20. package/dist/format.js.map +1 -1
  21. package/dist/index.d.ts +45 -0
  22. package/dist/index.js +33 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/logger.d.ts +4 -14
  25. package/dist/logger.js +98 -85
  26. package/dist/logger.js.map +1 -1
  27. package/dist/requestContext.d.ts +10 -0
  28. package/dist/requestContext.js +33 -0
  29. package/dist/requestContext.js.map +1 -0
  30. package/dist/transports/asyncBatch.d.ts +24 -0
  31. package/dist/transports/asyncBatch.js +57 -0
  32. package/dist/transports/asyncBatch.js.map +1 -0
  33. package/dist/transports/http.d.ts +27 -0
  34. package/dist/transports/http.js +117 -0
  35. package/dist/transports/http.js.map +1 -0
  36. package/dist/transports/mongodb.d.ts +19 -0
  37. package/dist/transports/mongodb.js +51 -0
  38. package/dist/transports/mongodb.js.map +1 -0
  39. package/dist/transports/sql.d.ts +22 -0
  40. package/dist/transports/sql.js +56 -0
  41. package/dist/transports/sql.js.map +1 -0
  42. package/dist/transports/tcp.d.ts +22 -0
  43. package/dist/transports/tcp.js +111 -0
  44. package/dist/transports/tcp.js.map +1 -0
  45. package/dist/transports/udp.d.ts +18 -0
  46. package/dist/transports/udp.js +75 -0
  47. package/dist/transports/udp.js.map +1 -0
  48. package/dist/transports/websocket.d.ts +21 -0
  49. package/dist/transports/websocket.js +110 -0
  50. package/dist/transports/websocket.js.map +1 -0
  51. package/dist/types.d.ts +21 -14
  52. package/dist/types.js.map +1 -1
  53. package/package.json +75 -70
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 tolongames
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
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tolongames
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
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,142 +1,384 @@
1
-
2
- # Scribelog πŸͺ΅πŸ“
3
-
4
- [![npm version](https://img.shields.io/npm/v/scribelog.svg)](https://www.npmjs.com/package/scribelog)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
- [![Build Status](https://github.com/tolongames/scribelog/actions/workflows/node.js.yml/badge.svg)](https://github.com/tolongames/scribelog/actions/workflows/node.js.yml) <!-- Zaktualizuj URL, jeΕ›li trzeba -->
7
-
8
- **Scribelog** is an advanced, highly configurable logging library for Node.js applications, written in TypeScript. It offers flexible formatting, support for multiple destinations (transports like Console and File), child loggers, automatic error catching, and printf-style interpolation, aiming for a great developer experience.
9
-
10
- ---
11
-
12
- ## ✨ Key Features
13
-
14
- * **Standard Logging Levels:** Uses familiar levels (`error`, `warn`, `info`, `http`, `verbose`, `debug`, `silly`).
15
- * **Highly Flexible Formatting:** Combine powerful formatters (`simple`, `json`, `timestamp`, `metadata`, `errors`, `splat`) using a composable API (`format.combine`). Customize outputs easily.
16
- * **Printf-Style Logging:** Use `printf`-like placeholders (`%s`, `%d`, `%j`) via `format.splat()` for easy message interpolation.
17
- * **Console Color Support:** Automatic, readable colorization for the `simple` format in TTY environments.
18
- * **Multiple Transports:** Log to different destinations. Built-in `ConsoleTransport` and `FileTransport` with rotation options.
19
- * **Child Loggers:** Easily create contextual loggers (`logger.child({...})`) that inherit settings but add specific metadata (like `requestId`).
20
- * **Automatic Error Handling:** Optionally catch and log `uncaughtException` and `unhandledRejection` events, including stack traces.
21
- * **TypeScript First:** Written entirely in TypeScript for type safety and excellent editor autocompletion.
22
-
23
- ---
24
-
25
- ## πŸ“¦ Installation
26
-
27
- ```bash
28
- # Core library
29
- npm install scribelog
30
- # or
31
- yarn add scribelog
32
- # or
33
- pnpm add scribelog
34
- ```
35
-
36
- ---
37
-
38
- ## πŸš€ Quick Start
39
-
40
- Get up and running in seconds:
41
-
42
- ```ts
43
- import { createLogger } from 'scribelog';
44
-
45
- // Logger with default settings:
46
- // - Level: 'info'
47
- // - Format: Simple, colored output (if TTY)
48
- // - Transport: Console
49
- const logger = createLogger();
50
-
51
- logger.info('Scribelog is ready!');
52
- logger.warn('Something seems off...', { detail: 'Cache size exceeded limit' });
53
-
54
- const userId = 'user-42';
55
- const action = 'login';
56
- logger.info('User %s performed action: %s', userId, action); // Printf-style
57
-
58
- try {
59
- // Simulate an error
60
- throw new Error('Failed to retrieve data');
61
- } catch(error) {
62
- // Log the error object correctly
63
- logger.error('Data retrieval failed', { error: error as Error });
64
- }
65
- ```
66
-
67
- **Default Console Output (example):**
68
-
69
- ```bash
70
- 2024-05-01T12:00:00.123Z [INFO]: Scribelog is ready!
71
- 2024-05-01T12:00:00.125Z [WARN]: Something seems off... { detail: 'Cache size exceeded limit' }
72
- 2024-05-01T12:00:00.127Z [INFO]: User user-42 performed action: login
73
- 2024-05-01T12:00:00.129Z [ERROR]: Failed to retrieve data { errorName: 'Error', exception: true }
74
- Error: Failed to retrieve data
75
- at <anonymous>:... (stack trace)
76
- ```
77
-
78
- ---
79
-
80
- ## πŸ“˜ Full Documentation
81
-
82
- This README covers the basics. For a comprehensive guide covering **all configuration options, formatters (like `json`, custom `timestamp` formats), transports (`FileTransport` with rotation), child loggers, error handling details, and advanced examples**, please see the:
83
-
84
- ➑️ **[Detailed Documentation](./DOCUMENTATION.md)** ⬅️
85
-
86
- ---
87
-
88
- ## βš™οΈ Basic Configuration (Overview)
89
-
90
- Configure your logger via `createLogger(options)`. Key options:
91
-
92
- * `level`: `'info'` (default), `'debug'`, `'warn'`, etc.
93
- * `format`: Use `format.combine(...)` with formatters like `format.simple()`, `format.json()`, `format.timestamp()`, `format.splat()`, `format.errors()`, `format.metadata()`. Default is `format.defaultSimpleFormat`.
94
- * `transports`: Array of `new transports.Console({...})` or `new transports.File({...})`. Default is one Console transport.
95
- * `defaultMeta`: An object with data to add to every log message.
96
- * `handleExceptions`, `handleRejections`, `exitOnError`: For automatic error catching.
97
-
98
- **Example: Logging JSON to a File**
99
-
100
- ```ts
101
- import { createLogger, format, transports } from 'scribelog';
102
-
103
- const fileJsonLogger = createLogger({
104
- level: 'debug',
105
- // Use the predefined JSON format (includes error handling, splat, timestamp etc.)
106
- format: format.defaultJsonFormat,
107
- transports: [
108
- new transports.File({
109
- filename: 'application.log', // Log to application.log
110
- level: 'debug', // Log debug and above to the file
111
- size: '10M', // Rotate at 10 MB
112
- maxFiles: 5 // Keep 5 rotated files
113
- })
114
- ],
115
- defaultMeta: { service: 'file-writer' }
116
- });
117
-
118
- fileJsonLogger.debug('Writing JSON log to file', { id: 1 });
119
- fileJsonLogger.error('File write error occurred', { error: new Error('Disk full'), file: 'data.txt'});
120
- ```
121
-
122
- ---
123
-
124
- ## πŸ“š Future Work
125
-
126
- * More built-in formatters (e.g., customizable color themes).
127
- * Ability to define custom logging levels.
128
- * Improved handling of asynchronous operations in transports (especially for `exitOnError`).
129
-
130
- ---
131
-
132
- ## 🀝 Contributing
133
-
134
- Contributions are welcome! Please feel free to submit issues and pull requests on the [GitHub repository](https://github.com/tolongames/scribelog).
135
-
136
- ---
137
-
138
- ## πŸ“„ License
139
-
140
- MIT License
141
- Copyright (c) 2024 tolongames
142
- See [LICENSE](./LICENSE) for details.
1
+ # Scribelog πŸͺ΅πŸ“
2
+
3
+ [![npm version](https://img.shields.io/npm/v/scribelog.svg)](https://www.npmjs.com/package/scribelog)
4
+ [![npm downloads](https://img.shields.io/npm/dm/scribelog.svg)](https://www.npmjs.com/package/scribelog)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Build Status](https://github.com/tolongames/scribelog/actions/workflows/node.js.yml/badge.svg)](https://github.com/tolongames/scribelog/actions/workflows/node.js.yml) <!-- Zaktualizuj URL, jeΕ›li trzeba -->
7
+
8
+ **Scribelog** is an advanced, highly configurable logging library for Node.js applications, written in TypeScript. It offers flexible formatting, support for multiple destinations (transports like Console and File), child loggers, automatic error catching, and printf-style interpolation, aiming for a great developer experience.
9
+
10
+ ---
11
+
12
+ ## ✨ Key Features
13
+
14
+ **Standard & Custom Logging Levels:** Use familiar levels (`error`, `warn`, `info`, etc.) or define your own custom levels.
15
+
16
+ - **Highly Flexible Formatting:** Combine powerful formatters (`simple`, `json`, `timestamp`, `metadata`, `errors`, `splat`) using a composable API (`format.combine`). Customize outputs easily, including color themes.
17
+ - **Printf-Style Logging:** Use `printf`-like placeholders (`%s`, `%d`, `%j`) via `format.splat()` for easy message interpolation.
18
+ - **Console Color Support:** Automatic, readable colorization for the `simple` format in TTY environments, with customizable themes.
19
+ - **Multiple Transports:** Log to different destinations. Built-in `ConsoleTransport` and `FileTransport` with rotation options.
20
+ - **Child Loggers:** Easily create contextual loggers (`logger.child({...})`) that inherit settings but add specific metadata (like `requestId`).
21
+ - **Framework adapters (Express, Koa, Fastify, NestJS, Next.js):**
22
+ Ready-to-use middleware/hooks/interceptors for request/response logging with automatic requestId (AsyncLocalStorage), duration, status, and framework tags. Minimal boilerplate.
23
+ - **Automatic Error Handling:** Optionally catch and log `uncaughtException` and `unhandledRejection` events, including stack traces.
24
+ - **Remote Transports (HTTP, WebSocket, TCP, UDP):**
25
+ Send logs over the network to ELK/Logstash, Graylog, Datadog, or custom collectors. Supports batching (AsyncBatch) and gzip (HTTP).
26
+ - **Tagging & Context:** Add tags to log messages for easy filtering and richer context. See examples in Quick Start.
27
+ - **Asynchronous Batch Logging:** Buffer and batch log messages before sending them to a target transport to reduce I/O overhead. See examples in Basic Configuration.
28
+ - **Automatic Request/Trace ID Propagation:** Automatically attaches a request/trace ID to every log message using AsyncLocalStorage. See usage in Basic Configuration.
29
+ - **Sensitive Data Masking:** Mask sensitive fields (passwords, tokens, API keys) with the built‑in `format.maskSensitive` formatter. See usage in Basic Configuration.
30
+ - **TypeScript First:** Written entirely in TypeScript for type safety and excellent editor autocompletion.
31
+
32
+ ---
33
+
34
+ ## πŸ“¦ Installation
35
+
36
+ ```bash
37
+ # Core library
38
+ npm install scribelog
39
+ # or
40
+ yarn add scribelog
41
+ # or
42
+ pnpm add scribelog
43
+ ```
44
+
45
+ ---
46
+
47
+ ## πŸš€ Quick Start
48
+
49
+ Get up and running in seconds:
50
+
51
+ ```ts
52
+ import { createLogger, format } from 'scribelog';
53
+ import chalk from 'chalk';
54
+
55
+ // Logger with custom color theme and default settings
56
+ const logger = createLogger({
57
+ level: 'debug',
58
+ format: format.combine(
59
+ format.timestamp(),
60
+ format.simple({
61
+ colors: true,
62
+ levelColors: {
63
+ error: chalk.bgRed.white,
64
+ warn: chalk.yellow.bold,
65
+ info: chalk.green,
66
+ debug: chalk.blue,
67
+ },
68
+ })
69
+ ),
70
+ });
71
+
72
+ logger.info('Scribelog is ready!');
73
+ logger.warn('Something seems off...', { detail: 'Cache size exceeded limit' });
74
+ logger.error('An error occurred!', { error: new Error('Test error') });
75
+
76
+ // --- NEW: Logging with tags ---
77
+ logger.info('User login', { tags: ['auth', 'user'], userId: 123 });
78
+ ```
79
+
80
+ **Default Console Output (example):**
81
+
82
+ ```bash
83
+ 2025-05-01T12:00:00.123Z [INFO]: Scribelog is ready!
84
+ 2025-05-01T12:00:00.125Z [WARN]: Something seems off... { detail: 'Cache size exceeded limit' }
85
+ 2025-05-01T12:00:00.127Z [ERROR]: An error occurred! { errorName: 'Error', exception: true }
86
+ Error: Test error
87
+ at <anonymous>:... (stack trace)
88
+ 2025-05-01T12:00:00.130Z [INFO] [auth, user]: User login { userId: 123 }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## πŸ“˜ Full Documentation
94
+
95
+ This README covers the basics. For a comprehensive guide covering **all configuration options, formatters (like `json`, custom `timestamp` formats), transports (`FileTransport` with rotation), child loggers, error handling details, and advanced examples**, please see the:
96
+
97
+ ➑️ **[Detailed Documentation](./DOCUMENTATION.md)** ⬅️
98
+
99
+ ---
100
+
101
+ ## βš™οΈ Basic Configuration (Overview)
102
+
103
+ Configure your logger via `createLogger(options)`. Key options:
104
+
105
+ - `level`: `'info'` (default), `'debug'`, `'warn'`, etc., or **custom levels** (e.g., `'critical'`, `'trace'`).
106
+ - `format`: Use `format.combine(...)` with formatters like `format.simple()`, `format.json()`, `format.timestamp()`, `format.splat()`, `format.errors()`, `format.metadata()`. Default is `format.defaultSimpleFormat`. You can also define **custom color themes** for log levels.
107
+ - `transports`: Array of `new transports.Console({...})` or `new transports.File({...})`. Default is one Console transport.
108
+ - `defaultMeta`: An object with data to add to every log message.
109
+ - `handleExceptions`, `handleRejections`, `exitOnError`: For automatic error catching.
110
+
111
+ **Example 1: Logging JSON to a File**
112
+
113
+ ```ts
114
+ import { createLogger, format, transports } from 'scribelog';
115
+
116
+ const fileJsonLogger = createLogger({
117
+ level: 'debug',
118
+ // Use the predefined JSON format (includes error handling, splat, timestamp etc.)
119
+ format: format.defaultJsonFormat,
120
+ transports: [
121
+ new transports.File({
122
+ filename: 'application.log', // Log to application.log
123
+ level: 'debug', // Log debug and above to the file
124
+ size: '10M', // Rotate at 10 MB
125
+ maxFiles: 5, // Keep 5 rotated files
126
+ }),
127
+ ],
128
+ defaultMeta: { service: 'file-writer' },
129
+ });
130
+
131
+ fileJsonLogger.debug('Writing JSON log to file', { id: 1 });
132
+ fileJsonLogger.error('File write error occurred', {
133
+ error: new Error('Disk full'),
134
+ file: 'data.txt',
135
+ });
136
+ ```
137
+
138
+ **Example 2: Using Custom Levels and Colors**
139
+
140
+ ```ts
141
+ import { createLogger, format } from 'scribelog';
142
+ import chalk from 'chalk';
143
+
144
+ const customLevels = {
145
+ critical: 0,
146
+ error: 1,
147
+ warn: 2,
148
+ info: 3,
149
+ debug: 4,
150
+ trace: 5,
151
+ };
152
+
153
+ const logger = createLogger({
154
+ levels: customLevels,
155
+ level: 'trace',
156
+ format: format.combine(
157
+ format.timestamp(),
158
+ format.simple({
159
+ colors: true,
160
+ levelColors: {
161
+ critical: chalk.bgRed.white.bold,
162
+ error: chalk.red,
163
+ warn: chalk.yellow,
164
+ info: chalk.green,
165
+ debug: chalk.blue,
166
+ trace: chalk.cyan,
167
+ },
168
+ })
169
+ ),
170
+ });
171
+
172
+ logger.critical('Critical issue!');
173
+ logger.trace('Trace message for debugging.');
174
+ ```
175
+
176
+ **Example 3: Batching logs (AsyncBatch)**
177
+
178
+ ```ts
179
+ import { createLogger, transports } from 'scribelog';
180
+
181
+ const fileTransport = new transports.File({ filename: 'batched.log' });
182
+
183
+ const asyncBatch = new transports.AsyncBatch({
184
+ target: fileTransport,
185
+ batchSize: 5, // Send logs in batches of 5
186
+ flushIntervalMs: 2000, // Or every 2 seconds
187
+ });
188
+
189
+ const logger = createLogger({ transports: [asyncBatch] });
190
+
191
+ logger.info('First log');
192
+ logger.info('Second log');
193
+ // ...more logs
194
+ ```
195
+
196
+ **Example 4: Request/Trace ID propagation**
197
+
198
+ ```ts
199
+ import { runWithRequestContext, setRequestId, createLogger } from 'scribelog';
200
+ const logger = createLogger();
201
+
202
+ // In your middleware:
203
+ app.use((req, res, next) => {
204
+ const reqId = req.headers['x-request-id'] || generateRandomId();
205
+ runWithRequestContext({ requestId: String(reqId) }, () => {
206
+ next();
207
+ });
208
+ });
209
+
210
+ // Anywhere later in the same async flow:
211
+ logger.info('Handled request'); // requestId is attached automatically
212
+ ```
213
+
214
+ **Example 5: Sensitive data masking**
215
+
216
+ ```ts
217
+ import { createLogger, format } from 'scribelog';
218
+
219
+ const logger = createLogger({
220
+ format: format.combine(
221
+ format.maskSensitive(['password', 'token', 'apiKey']),
222
+ format.simple()
223
+ ),
224
+ });
225
+
226
+ logger.info('User login', {
227
+ username: 'bob',
228
+ password: 'sekret123',
229
+ token: 'abc',
230
+ profile: { apiKey: 'xyz' },
231
+ });
232
+ // Output (example): password: '***', token: '***', profile: { apiKey: '***' }
233
+ ```
234
+
235
+ ## Framework adapters (quick integration)
236
+
237
+ Express:
238
+
239
+ ```ts
240
+ import express from 'express';
241
+ import { createLogger, adapters } from 'scribelog';
242
+
243
+ const app = express();
244
+ const logger = createLogger();
245
+ app.use(adapters.express.createMiddleware({ logger }));
246
+ ```
247
+
248
+ Koa:
249
+
250
+ ```ts
251
+ import Koa from 'koa';
252
+ import { createLogger, adapters } from 'scribelog';
253
+
254
+ const app = new Koa();
255
+ const logger = createLogger();
256
+ app.use(adapters.koa.createMiddleware({ logger }));
257
+ ```
258
+
259
+ Fastify:
260
+
261
+ ```ts
262
+ import Fastify from 'fastify';
263
+ import { createLogger, adapters } from 'scribelog';
264
+
265
+ const app = Fastify();
266
+ const logger = createLogger();
267
+ const register = adapters.fastify.createPlugin({ logger });
268
+ register(app);
269
+ ```
270
+
271
+ NestJS (global interceptor):
272
+
273
+ ```ts
274
+ import { adapters, createLogger } from 'scribelog';
275
+ const app = await NestFactory.create(AppModule);
276
+ const logger = createLogger();
277
+ app.useGlobalInterceptors(adapters.nest.createInterceptor({ logger }));
278
+ ```
279
+
280
+ Next.js (API Route):
281
+
282
+ ```ts
283
+ import { adapters, createLogger } from 'scribelog';
284
+ const logger = createLogger();
285
+ export default adapters.next.createApiHandler(
286
+ async (req, res) => {
287
+ res.statusCode = 200;
288
+ res.end('OK');
289
+ },
290
+ { logger }
291
+ );
292
+ ```
293
+
294
+ ## Remote transports (network logging)
295
+
296
+ HTTP (+ batching + gzip):
297
+
298
+ ```ts
299
+ import { createLogger, transports, format } from 'scribelog';
300
+
301
+ const httpT = new transports.Http({
302
+ url: 'https://logs.example.com/ingest',
303
+ headers: { 'x-api-key': 'your-key' },
304
+ compress: true, // gzip the body
305
+ timeoutMs: 8000,
306
+ // format defaults to format.defaultJsonFormat if not provided
307
+ });
308
+
309
+ const batched = new transports.AsyncBatch({
310
+ target: httpT,
311
+ batchSize: 20,
312
+ flushIntervalMs: 1000,
313
+ });
314
+
315
+ const logger = createLogger({
316
+ transports: [batched],
317
+ format: format.defaultJsonFormat,
318
+ });
319
+ logger.info('Remote log', { service: 'api' });
320
+ ```
321
+
322
+ WebSocket (requires ws: npm i ws):
323
+
324
+ ```ts
325
+ import { createLogger, transports } from 'scribelog';
326
+
327
+ const wsT = new transports.WebSocket({ url: 'wss://logs.example.com/stream' });
328
+ const logger = createLogger({ transports: [wsT] });
329
+ logger.error('Streamed error', { code: 500 });
330
+ ```
331
+
332
+ TCP (newline-delimited JSON) + batching:
333
+
334
+ ```ts
335
+ import { createLogger, transports } from 'scribelog';
336
+
337
+ const tcp = new transports.Tcp({ host: '127.0.0.1', port: 5000 });
338
+ const batched = new transports.AsyncBatch({
339
+ target: tcp,
340
+ batchSize: 50,
341
+ flushIntervalMs: 500,
342
+ });
343
+ const logger = createLogger({ transports: [batched] });
344
+ logger.info('Hello over TCP', { env: 'prod' });
345
+ ```
346
+
347
+ UDP (best-effort, e.g., GELF-like):
348
+
349
+ ```ts
350
+ import { createLogger, transports } from 'scribelog';
351
+
352
+ const udp = new transports.Udp({ host: '127.0.0.1', port: 12201 });
353
+ const logger = createLogger({ transports: [udp] });
354
+ logger.warn('Warning via UDP');
355
+ ```
356
+
357
+ Notes:
358
+
359
+ - Prefer JSON format for collectors: use format.defaultJsonFormat.
360
+ - Use AsyncBatch to reduce network overhead and smooth bursts.
361
+ - Redact secrets before sending: format.maskSensitive([...]).
362
+ - requestId from async context is automatically attached to logs.
363
+
364
+ ---
365
+
366
+ ## πŸ“š Future Work
367
+
368
+ - Profiling & timing: simple profiler (logger.profile('db') ... logger.profileEnd('db')).
369
+ - Syslog/journald: transports for system logs on Linux/Unix.
370
+ - OpenTelemetry integration: automatic trace/span ID
371
+
372
+ ---
373
+
374
+ ## 🀝 Contributing
375
+
376
+ Contributions are welcome! Please feel free to submit issues and pull requests on the [GitHub repository](https://github.com/tolongames/scribelog).
377
+
378
+ ---
379
+
380
+ ## πŸ“„ License
381
+
382
+ MIT License
383
+ Copyright (c) 2025 tolongames
384
+ See [LICENSE](./LICENSE) for details.
@@ -0,0 +1,17 @@
1
+ import type { LoggerInterface, LogLevel } from '../types';
2
+ export interface ExpressLoggerOptions {
3
+ logger?: LoggerInterface;
4
+ headerName?: string;
5
+ generateId?: () => string;
6
+ redactHeaders?: string[];
7
+ logRequest?: boolean;
8
+ logResponse?: boolean;
9
+ levelRequest?: LogLevel;
10
+ levelResponse?: LogLevel;
11
+ tags?: string[];
12
+ maxHeaderValueLength?: number;
13
+ }
14
+ /**
15
+ * Express middleware: automatyczne ustawienie requestId + logi start/stop.
16
+ */
17
+ export declare function createExpressMiddleware(opts?: ExpressLoggerOptions): (req: any, res: any, next: any) => void;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createExpressMiddleware = createExpressMiddleware;
4
+ const requestContext_1 = require("../requestContext");
5
+ const logger_1 = require("../logger");
6
+ function defaultId() {
7
+ return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
8
+ }
9
+ function redactHeaders(headers, redact, maxLen) {
10
+ const out = {};
11
+ if (!headers)
12
+ return out;
13
+ const redactSet = new Set(redact.map((h) => h.toLowerCase()));
14
+ for (const [k, v] of Object.entries(headers)) {
15
+ const key = k.toLowerCase();
16
+ let val = typeof v === 'string' ? v : Array.isArray(v) ? v.join(', ') : String(v);
17
+ if (redactSet.has(key))
18
+ val = '***';
19
+ if (maxLen > 0 && val.length > maxLen)
20
+ val = val.slice(0, maxLen) + '…';
21
+ out[key] = val;
22
+ }
23
+ return out;
24
+ }
25
+ /**
26
+ * Express middleware: automatyczne ustawienie requestId + logi start/stop.
27
+ */
28
+ function createExpressMiddleware(opts = {}) {
29
+ const { logger = (0, logger_1.createLogger)(), headerName = 'x-request-id', generateId = defaultId, redactHeaders: redact = ['authorization', 'cookie', 'set-cookie'], logRequest = true, logResponse = true, levelRequest = 'http', levelResponse = 'info', tags = ['express'], maxHeaderValueLength = 256, } = opts;
30
+ return function expressLogger(req, res, next) {
31
+ const rid = (req.headers && req.headers[headerName]) || generateId();
32
+ const start = process.hrtime.bigint();
33
+ const baseMeta = {
34
+ requestId: rid,
35
+ method: req.method,
36
+ url: req.originalUrl || req.url,
37
+ tags,
38
+ };
39
+ (0, requestContext_1.runWithRequestContext)({ requestId: rid }, () => {
40
+ if (logRequest) {
41
+ const safeHeaders = redactHeaders(req.headers, redact, maxHeaderValueLength);
42
+ logger[levelRequest]('HTTP request', Object.assign(Object.assign({}, baseMeta), { headers: safeHeaders }));
43
+ }
44
+ res.on('finish', () => {
45
+ var _a;
46
+ const durationMs = Number(process.hrtime.bigint() - start) / 1e6;
47
+ const contentLength = (_a = res.getHeader) === null || _a === void 0 ? void 0 : _a.call(res, 'content-length');
48
+ if (logResponse) {
49
+ logger[levelResponse]('HTTP response', Object.assign(Object.assign({}, baseMeta), { statusCode: res.statusCode, durationMs: Math.round(durationMs), contentLength: contentLength ? Number(contentLength) : undefined }));
50
+ }
51
+ });
52
+ next();
53
+ });
54
+ };
55
+ }
56
+ //# sourceMappingURL=express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"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"}