0
# Transports
1
2
External logging system for integrating with log services, file systems, databases, and other logging destinations. Transports receive all log objects after processing and can forward them to external systems.
3
4
## Capabilities
5
6
### Transport Function Interface
7
8
Transport functions receive processed log objects and can handle them according to their specific requirements.
9
10
```typescript { .api }
11
/**
12
* Transport function interface for handling log objects
13
* @template LogObj - Type for log object structure
14
*/
15
type TransportLogger<LogObj> = (transportLogger: LogObj & ILogObjMeta) => void;
16
17
/**
18
* Log object with metadata passed to transports
19
*/
20
interface LogObj & ILogObjMeta {
21
/** User-defined log data */
22
[key: string]: unknown;
23
24
/** Metadata property containing log information */
25
[metaProperty: string]: IMeta;
26
}
27
28
interface IMeta {
29
/** Timestamp when log was created */
30
date: Date;
31
/** Numeric log level (0-6) */
32
logLevelId: number;
33
/** String log level name */
34
logLevelName: string;
35
/** Stack frame information if available */
36
path?: IStackFrame;
37
/** Logger name */
38
name?: string;
39
/** Parent logger names for hierarchical loggers */
40
parentNames?: string[];
41
/** Runtime environment identifier */
42
runtime: string;
43
}
44
```
45
46
### Attaching Transports
47
48
Method to attach external transport functions to logger instances.
49
50
```typescript { .api }
51
/**
52
* Attach external transport for log forwarding
53
* @param transportLogger - Function to handle log objects
54
*/
55
attachTransport(transportLogger: (transportLogger: LogObj & ILogObjMeta) => void): void;
56
```
57
58
**Usage Examples:**
59
60
```typescript
61
import { Logger } from "tslog";
62
63
const logger = new Logger({ name: "MyApp" });
64
65
// Simple console transport
66
logger.attachTransport((logObj) => {
67
console.log("External:", JSON.stringify(logObj));
68
});
69
70
// File transport example
71
import * as fs from "fs";
72
73
logger.attachTransport((logObj) => {
74
const logLine = JSON.stringify(logObj) + "\n";
75
fs.appendFileSync("application.log", logLine);
76
});
77
78
// Database transport example
79
logger.attachTransport(async (logObj) => {
80
await database.logs.insert({
81
timestamp: logObj._meta.date,
82
level: logObj._meta.logLevelName,
83
message: logObj[0], // First argument
84
metadata: logObj,
85
});
86
});
87
```
88
89
### Multiple Transports
90
91
Loggers can have multiple transports attached, and each log message will be sent to all attached transports.
92
93
```typescript { .api }
94
/**
95
* Multiple transports are stored in settings
96
*/
97
interface ISettings<LogObj> {
98
attachedTransports: ((transportLogger: LogObj & ILogObjMeta) => void)[];
99
}
100
```
101
102
**Usage Examples:**
103
104
```typescript
105
import { Logger } from "tslog";
106
107
const logger = new Logger({ name: "MultiTransportApp" });
108
109
// Attach multiple transports
110
logger.attachTransport((logObj) => {
111
// Send to external logging service
112
externalLogService.send(logObj);
113
});
114
115
logger.attachTransport((logObj) => {
116
// Write to file
117
fs.appendFileSync("app.log", JSON.stringify(logObj) + "\n");
118
});
119
120
logger.attachTransport((logObj) => {
121
// Send critical errors to monitoring system
122
if (logObj._meta.logLevelId >= 5) { // ERROR and FATAL
123
monitoringSystem.alert(logObj);
124
}
125
});
126
127
// All transports will receive this log
128
logger.error("Database connection failed", { database: "users" });
129
```
130
131
### Transport Configuration
132
133
Transports can be configured during logger initialization or added later.
134
135
```typescript { .api }
136
/**
137
* Configure transports during initialization
138
*/
139
interface ISettingsParam<LogObj> {
140
attachedTransports?: ((transportLogger: LogObj & ILogObjMeta) => void)[];
141
}
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import { Logger } from "tslog";
148
149
// Configure transports during initialization
150
const logger = new Logger({
151
name: "PreConfiguredApp",
152
attachedTransports: [
153
(logObj) => {
154
// File transport
155
fs.appendFileSync("startup.log", JSON.stringify(logObj) + "\n");
156
},
157
(logObj) => {
158
// External service transport
159
if (logObj._meta.logLevelId >= 4) { // WARN and above
160
alertingService.send(logObj);
161
}
162
},
163
],
164
});
165
166
// Add additional transports later
167
logger.attachTransport((logObj) => {
168
// Development debugging transport
169
if (process.env.NODE_ENV === "development") {
170
debugConsole.log(logObj);
171
}
172
});
173
```
174
175
### Transport Best Practices
176
177
Guidelines for implementing robust transport functions.
178
179
```typescript { .api }
180
/**
181
* Example robust transport implementation
182
*/
183
function createRobustTransport(config: TransportConfig): TransportLogger<any> {
184
return (logObj) => {
185
try {
186
// Handle the log object
187
processLogObject(logObj, config);
188
} catch (error) {
189
// Don't let transport errors crash the application
190
console.error("Transport error:", error);
191
}
192
};
193
}
194
195
interface TransportConfig {
196
/** Maximum retries for failed sends */
197
maxRetries?: number;
198
/** Timeout for transport operations */
199
timeout?: number;
200
/** Buffer size for batching logs */
201
bufferSize?: number;
202
/** Filter function for selective logging */
203
filter?: (logObj: any) => boolean;
204
}
205
```
206
207
**Usage Examples:**
208
209
```typescript
210
import { Logger } from "tslog";
211
212
// HTTP transport with error handling
213
function createHttpTransport(endpoint: string) {
214
return (logObj: any) => {
215
try {
216
fetch(endpoint, {
217
method: "POST",
218
headers: { "Content-Type": "application/json" },
219
body: JSON.stringify(logObj),
220
}).catch((error) => {
221
// Handle network errors without crashing
222
console.error("HTTP transport failed:", error);
223
});
224
} catch (error) {
225
console.error("HTTP transport error:", error);
226
}
227
};
228
}
229
230
// Filtered transport (only errors and fatals)
231
function createErrorOnlyTransport(handler: (logObj: any) => void) {
232
return (logObj: any) => {
233
if (logObj._meta.logLevelId >= 5) { // ERROR and FATAL only
234
handler(logObj);
235
}
236
};
237
}
238
239
// Batching transport for performance
240
function createBatchTransport(sender: (batch: any[]) => void, batchSize = 10) {
241
let batch: any[] = [];
242
243
return (logObj: any) => {
244
batch.push(logObj);
245
if (batch.length >= batchSize) {
246
sender([...batch]);
247
batch = [];
248
}
249
};
250
}
251
252
const logger = new Logger({ name: "AdvancedApp" });
253
254
// Use advanced transports
255
logger.attachTransport(createHttpTransport("https://logs.example.com/api"));
256
logger.attachTransport(createErrorOnlyTransport((logObj) => {
257
alertingSystem.send(logObj);
258
}));
259
logger.attachTransport(createBatchTransport((batch) => {
260
analytics.sendBatch(batch);
261
}, 5));
262
```
263
264
### Transport Inheritance
265
266
Sub-loggers inherit transports from their parent loggers, and additional transports can be added.
267
268
```typescript { .api }
269
/**
270
* Sub-loggers inherit parent transports
271
*/
272
getSubLogger(settings?: ISettingsParam<LogObj>, logObj?: LogObj): Logger<LogObj>;
273
```
274
275
**Usage Examples:**
276
277
```typescript
278
import { Logger } from "tslog";
279
280
// Parent logger with transports
281
const parentLogger = new Logger({ name: "ParentApp" });
282
parentLogger.attachTransport((logObj) => {
283
console.log("Parent transport:", logObj._meta.name);
284
});
285
286
// Child logger inherits parent transports
287
const childLogger = parentLogger.getSubLogger({ name: "ChildModule" });
288
289
// Child logger can add its own transports
290
childLogger.attachTransport((logObj) => {
291
console.log("Child transport:", logObj._meta.name);
292
});
293
294
// This log will go to both parent and child transports
295
childLogger.info("Child logger message");
296
// Output:
297
// Parent transport: ChildModule
298
// Child transport: ChildModule
299
```
300
301
## Common Transport Patterns
302
303
### File Transport
304
305
```typescript
306
import * as fs from "fs";
307
import * as path from "path";
308
309
function createFileTransport(filePath: string) {
310
return (logObj: any) => {
311
const logLine = JSON.stringify(logObj) + "\n";
312
fs.appendFileSync(filePath, logLine);
313
};
314
}
315
```
316
317
### Syslog Transport
318
319
```typescript
320
function createSyslogTransport() {
321
return (logObj: any) => {
322
const syslogLevel = mapLogLevelToSyslog(logObj._meta.logLevelId);
323
const message = `<${syslogLevel}>${JSON.stringify(logObj)}`;
324
// Send to syslog daemon
325
sendToSyslog(message);
326
};
327
}
328
```
329
330
### Database Transport
331
332
```typescript
333
function createDatabaseTransport(database: any) {
334
return async (logObj: any) => {
335
await database.collection('logs').insertOne({
336
timestamp: logObj._meta.date,
337
level: logObj._meta.logLevelName,
338
logger: logObj._meta.name,
339
data: logObj,
340
});
341
};
342
}
343
```