0
# winston-transport
1
2
winston-transport provides the base TransportStream implementation for winston logging library version 3 and above. It serves as the foundational building block for creating custom winston transports with a standardized stream-based interface.
3
4
## Package Information
5
6
- **Package Name**: winston-transport
7
- **Package Type**: npm
8
- **Language**: JavaScript (with TypeScript definitions)
9
- **Installation**: `npm install winston-transport`
10
11
## Core Imports
12
13
Default export (main TransportStream class):
14
15
```javascript
16
const Transport = require('winston-transport');
17
```
18
19
Named exports (legacy transport):
20
21
```javascript
22
const { LegacyTransportStream } = require('winston-transport');
23
```
24
25
TypeScript import patterns:
26
27
```typescript
28
import TransportStream = require('winston-transport');
29
import { LegacyTransportStream } from 'winston-transport';
30
```
31
32
ESM imports (Node.js with "type": "module"):
33
34
```javascript
35
import Transport from 'winston-transport';
36
import { LegacyTransportStream } from 'winston-transport';
37
```
38
39
## Basic Usage
40
41
```javascript
42
const Transport = require('winston-transport');
43
44
class CustomTransport extends Transport {
45
constructor(opts) {
46
super(opts);
47
// Custom initialization
48
}
49
50
log(info, callback) {
51
setImmediate(() => {
52
this.emit('logged', info);
53
});
54
55
// Perform the writing to the remote service
56
console.log(info.message);
57
58
callback();
59
}
60
}
61
62
module.exports = CustomTransport;
63
```
64
65
## Architecture
66
67
winston-transport is designed around several key components:
68
69
- **TransportStream**: Modern stream-based transport extending Node.js Writable
70
- **Stream Integration**: Full winston v3+ logger pipe compatibility with level filtering
71
- **Format Support**: Integration with logform formatting system
72
- **Exception Handling**: Built-in support for exception and rejection handling
73
- **Legacy Compatibility**: LegacyTransportStream wrapper for winston v2 transports
74
75
## Types
76
77
```javascript { .api }
78
/** Log information object structure */
79
interface LogInfo {
80
/** Log level (error, warn, info, debug, etc.) */
81
level: string;
82
/** Log message content */
83
message: string;
84
/** Exception flag for error handling */
85
exception?: boolean;
86
/** Timestamp (added by format) */
87
timestamp?: string;
88
/** Additional metadata */
89
[key: string]: any;
90
}
91
92
/** Logform format interface for log transformation */
93
interface LogformFormat {
94
/** Transform log info object */
95
transform: (info: LogInfo, options?: any) => LogInfo | false;
96
/** Format options */
97
options?: any;
98
}
99
100
/** Log levels mapping (set by winston logger) */
101
interface LogLevels {
102
[level: string]: number;
103
}
104
105
/** Node.js stream namespace reference */
106
declare namespace stream {
107
class Writable {
108
constructor(options?: any);
109
write(chunk: any, encoding?: string, callback?: Function): boolean;
110
end(chunk?: any, encoding?: string, callback?: Function): void;
111
on(event: string, listener: Function): this;
112
emit(event: string, ...args: any[]): boolean;
113
}
114
}
115
```
116
117
## Capabilities
118
119
### Transport Stream Implementation
120
121
Core transport functionality providing a stream-based interface that integrates with winston v3+ logging architecture. Handles log level filtering, formatting, and lifecycle management.
122
123
```javascript { .api }
124
/**
125
* Base class for winston v3+ transports extending readable-stream's Writable
126
* @param {TransportStreamOptions} options - Configuration options
127
*/
128
class TransportStream extends stream.Writable {
129
/** Log formatter instance */
130
format?: LogformFormat;
131
/** Current log level */
132
level?: string;
133
/** Silent mode flag */
134
silent?: boolean;
135
/** Exception handling flag */
136
handleExceptions?: boolean;
137
/** Rejection handling flag */
138
handleRejections?: boolean;
139
/** Log levels map (set when piped from logger) */
140
levels?: LogLevels;
141
/** Parent logger reference (set when piped from logger) */
142
parent?: any;
143
144
constructor(options?: TransportStreamOptions);
145
146
/** Log single message - must be implemented by subclasses */
147
log?(info: LogInfo, next: () => void): any;
148
149
/** Log multiple messages in batch - optional optimization */
150
logv?(info: LogInfo[], next: () => void): any;
151
152
/** Cleanup on transport removal - optional */
153
close?(): void;
154
}
155
156
interface TransportStreamOptions {
157
/** Log formatter from logform */
158
format?: LogformFormat;
159
/** Log level filter (e.g., 'info', 'error') */
160
level?: string;
161
/** Suppress all log output */
162
silent?: boolean;
163
/** Handle exception logs */
164
handleExceptions?: boolean;
165
/** Handle rejection logs */
166
handleRejections?: boolean;
167
/** Stream buffer size */
168
highWaterMark?: number;
169
/** Custom log function for simple transport creation */
170
log?(info: LogInfo, next: () => void): any;
171
/** Custom batch log function */
172
logv?(info: LogInfo[], next: () => void): any;
173
/** Custom close function */
174
close?(): void;
175
}
176
```
177
178
### Internal Stream Methods
179
180
Advanced stream methods for customizing transport behavior. Generally not needed for basic transport implementations.
181
182
```javascript { .api }
183
/**
184
* Internal write method called by stream when log data is written
185
* @param {LogInfo} info - Log information object
186
* @param {string} enc - Encoding (usually ignored in object mode)
187
* @param {Function} callback - Completion callback
188
*/
189
TransportStream.prototype._write = function(info, enc, callback) {
190
// Internal implementation - handles format transformation and level filtering
191
};
192
193
/**
194
* Internal batch write method for multiple log entries
195
* @param {Array} chunks - Array of write requests with chunk and callback
196
* @param {Function} callback - Completion callback
197
*/
198
TransportStream.prototype._writev = function(chunks, callback) {
199
// Internal implementation - handles batch processing
200
};
201
202
/**
203
* Filter predicate to determine if a write request should be accepted
204
* @param {Object} write - Write request object with chunk property
205
* @returns {boolean} - True if the write should be processed
206
*/
207
TransportStream.prototype._accept = function(write) {
208
// Internal implementation - checks level, silent mode, and exception handling
209
};
210
```
211
212
### Legacy Transport Compatibility
213
214
Wrapper functionality for winston v2 transports to work with winston v3+ logger infrastructure. Provides backward compatibility while encouraging migration to modern transport interface.
215
216
```javascript { .api }
217
/**
218
* Wrapper for winston v2 transports to work with winston v3+
219
* @param {LegacyTransportStreamOptions} options - Configuration options
220
*/
221
class LegacyTransportStream extends TransportStream {
222
/** The wrapped winston v2 transport instance */
223
transport: LegacyTransport;
224
225
constructor(options: LegacyTransportStreamOptions);
226
227
/** Cleanup legacy transport and error handlers */
228
close(): void;
229
}
230
231
interface LegacyTransportStreamOptions extends TransportStreamOptions {
232
/** winston v2 transport instance with log method */
233
transport: LegacyTransport;
234
}
235
236
/** Winston v2 transport interface */
237
interface LegacyTransport {
238
/** Transport name for identification */
239
name?: string;
240
/** Log method with v2 signature */
241
log: (level: string, message: string, meta: any, callback: () => void) => void;
242
/** Optional cleanup method */
243
close?: () => void;
244
/** Optional log level */
245
level?: string;
246
/** Optional exception handling */
247
handleExceptions?: boolean;
248
/** Event emitter methods for error handling */
249
on?: (event: string, listener: Function) => void;
250
removeListener?: (event: string, listener: Function) => void;
251
}
252
```
253
254
## Usage Examples
255
256
### Creating a Custom Transport
257
258
```javascript
259
const Transport = require('winston-transport');
260
261
class CustomTransport extends Transport {
262
constructor(opts) {
263
super(opts);
264
265
// Initialize custom transport properties
266
this.name = 'custom';
267
this.filename = opts.filename;
268
}
269
270
log(info, callback) {
271
setImmediate(() => {
272
this.emit('logged', info);
273
});
274
275
// Write log to your custom destination
276
// info object contains: { level, message, timestamp, ...metadata }
277
const logLine = `${info.timestamp} [${info.level}]: ${info.message}\n`;
278
279
// Perform actual writing (file, database, API, etc.)
280
this.writeToDestination(logLine);
281
282
callback();
283
}
284
285
close() {
286
// Cleanup resources
287
if (this.connection) {
288
this.connection.close();
289
}
290
}
291
}
292
293
module.exports = CustomTransport;
294
```
295
296
### Using with Winston Logger
297
298
```javascript
299
const winston = require('winston');
300
const CustomTransport = require('./custom-transport');
301
302
const logger = winston.createLogger({
303
level: 'info',
304
format: winston.format.combine(
305
winston.format.timestamp(),
306
winston.format.json()
307
),
308
transports: [
309
new CustomTransport({
310
filename: 'app.log',
311
level: 'error'
312
})
313
]
314
});
315
316
logger.error('This will be written by CustomTransport');
317
logger.info('This will be filtered out due to level');
318
```
319
320
### Wrapping Legacy Transport
321
322
```javascript
323
const { LegacyTransportStream } = require('winston-transport');
324
const OldTransport = require('winston-old-transport');
325
326
// Wrap a winston v2 transport for v3+ compatibility
327
const legacyTransport = new LegacyTransportStream({
328
transport: new OldTransport({
329
level: 'info',
330
filename: 'legacy.log'
331
})
332
});
333
334
// Use with winston v3+ logger
335
const logger = winston.createLogger({
336
transports: [legacyTransport]
337
});
338
```
339
340
## Error Handling
341
342
winston-transport provides comprehensive error handling through multiple mechanisms:
343
344
### Stream Error Events
345
346
Transport errors bubble up through the standard Node.js stream error event system:
347
348
```javascript
349
const transport = new CustomTransport();
350
351
transport.on('error', (err) => {
352
console.error('Transport error:', err);
353
});
354
355
// Errors in log() method will emit 'error' event
356
transport.log({ level: 'info', message: 'test' }, (err) => {
357
if (err) {
358
// Handle callback errors
359
console.error('Log callback error:', err);
360
}
361
});
362
```
363
364
### Exception and Rejection Handling
365
366
Control how the transport handles uncaught exceptions and unhandled promise rejections:
367
368
```javascript
369
const transport = new CustomTransport({
370
handleExceptions: true, // Handle uncaught exceptions
371
handleRejections: true // Handle unhandled promise rejections
372
});
373
374
// These will be captured and logged by the transport:
375
// throw new Error('Uncaught exception');
376
// Promise.reject('Unhandled rejection');
377
```
378
379
### Format Transformation Errors
380
381
Format transformation errors are trapped and re-thrown after callback invocation to ensure stream continuation:
382
383
```javascript
384
const transport = new CustomTransport({
385
format: winston.format.combine(
386
winston.format.timestamp(),
387
winston.format.printf(info => {
388
// If this throws an error, it will be caught and re-thrown
389
// after the callback is invoked
390
return `${info.timestamp} ${info.level}: ${info.message}`;
391
})
392
)
393
});
394
```
395
396
### Legacy Transport Error Forwarding
397
398
Legacy transports have automatic error event forwarding with proper cleanup:
399
400
```javascript
401
const legacyTransport = new LegacyTransportStream({
402
transport: new OldTransport()
403
});
404
405
// Errors from the wrapped transport are automatically forwarded
406
legacyTransport.on('error', (err, transport) => {
407
console.error('Legacy transport error:', err);
408
console.error('From transport:', transport.name);
409
});
410
411
// Cleanup is automatic when transport is removed
412
logger.remove(legacyTransport); // Calls close() and removes error listeners
413
```
414
415
### Silent Mode
416
417
Use silent mode to suppress all log output while maintaining error handling:
418
419
```javascript
420
const transport = new CustomTransport({
421
silent: true // No logs will be written, but errors are still handled
422
});
423
```