A reusable, production-ready Winston-based logger module with clean architecture
npm install vanta-loggerA production-ready, reusable Winston-based logger module with clean architecture, structured error logging, and comprehensive transport support.
- ✨ Clean Architecture - Modular design with clear separation of concerns
- 🎯 Scoped Loggers - Create isolated logger instances that share transports
- 🔒 Type-Safe - Full TypeScript support with branded types for IDs
- 📊 Structured Logging - Consistent log entry format across all transports
- 🚨 Automatic Error IDs - Auto-generates error IDs for all error-level logs
- 🔄 Multiple Transports - Console, File, Discord, Sentry, Google Cloud Logging
- ⚡ Discord Rate Limiting - Built-in rate limiting and failover for Discord webhooks
- 🎨 Configurable Components - Filter which log fields each transport receives
- 🛡️ Error Serialization - Robust error handling with truncation and depth limiting
``bash`
npm install
npm run build
`typescript
import { Logger } from "vanta-logger";
// Create logger instance
const logger = new Logger({
service: "my-app",
transports: {
console: {
enabled: true,
level: "info",
entries: "default",
},
},
});
// Create scoped logger
const log = logger.createLogger("MyModule");
// Log messages
log.info("Application started", "startup");
log.error("Something went wrong", "error-handler", {
error: new Error("Database connection failed"),
});
`
Always create a single Logger instance and share it across your application:
`typescript
// logger.ts
import { Logger } from "vanta-logger";
const logger = new Logger({
service: "my-service",
transports: {
/ ... /
},
});
export default logger;
`
Create scoped loggers for different modules/files:
`typescript
// user-service.ts
import logger from "./logger";
const log = logger.createLogger("UserService");
log.info("User created", "create-user", {
meta: { userId: 123 },
});
`
All log methods follow the same signature:
`typescript`
logger.
- message (string, required): Primary log message
- identifier (string, required): Short code location identifier
- entries (object, optional): Additional log data
Generate IDs for tracking sessions and errors:
`typescript
const sessionID = Logger.createSessionID(); // sid-a3f2d8c1b4e5f6a7
const errorID = Logger.createErrorID(); // eid-9d4c2b7a8e1f3c6d
log.info("User logged in", "login", {
sessionID,
meta: { username: "john" },
});
log.error("Login failed", "login-error", {
error: err,
errorID,
sessionID,
});
`
Note: Error-level logs automatically generate an errorID if not provided.
`typescript`
console: {
enabled: true,
level: 'info',
colorize: true,
entries: ['timestamp', 'origin', 'identifier', 'message', 'errorID'],
}
`typescript`
file: {
enabled: true,
filename: 'app.log',
level: 'silly',
entries: 'default',
maxsize: 5242880, // 5MB
maxFiles: 5,
tailable: true,
zippedArchive: true,
}
`typescript`
discord: {
enabled: true,
webhookUrls: [
'https://discord.com/api/webhooks/PRIMARY/TOKEN',
'https://discord.com/api/webhooks/BACKUP/TOKEN',
],
level: 'error',
entries: 'default',
maxRetries: 3,
}
Only sends logs where sendDiscordWebhook: true:
`typescript`
log.error("Critical error", "system", {
error: err,
sendDiscordWebhook: true, // Sends to Discord
});
`typescript`
sentry: {
enabled: true,
dsn: 'https://your-dsn@sentry.io/project',
environment: 'production',
level: 'error',
entries: 'default',
}
`typescript`
gcp: {
enabled: true,
projectId: 'your-gcp-project',
keyFilename: '/path/to/key.json',
logName: 'app-logs',
entries: 'default',
}
`typescript`
try {
// risky operation
} catch (err) {
log.error("Operation failed", "operation", {
error: err, // Automatically serialized
});
}
The logger extracts HTTP response details:
`typescript
const httpError = new Error("Request failed");
httpError.response = {
status: 500,
statusText: "Internal Server Error",
data: { message: "Database error" },
};
log.error("API call failed", "api-client", {
error: httpError,
});
`
For complex or unknown errors, use serializeError:
`typescript
import { serializeError } from "vanta-logger";
log.error("Unknown error", "handler", {
error: serializeError(unknownValue),
});
`
Control how errors are truncated:
`typescript`
limits: {
stackLimit: 1000, // Stack trace truncation
responseDataLimit: 500, // HTTP response data truncation
causeMaxDepth: 3, // Error cause chain depth
}
Control which fields each transport receives:
`typescript`
console: {
enabled: true,
entries: ['timestamp', 'level', 'message', 'errorID'], // Only these fields
}
Use 'default' for transport-specific defaults.
See the examples/ directory for complete examples:
- basic-usage.ts - Basic logging patterns
- advanced-config.ts - Advanced configuration
- express-integration.ts - Express.js integration
- API Reference
- Configuration Guide
- Transport Guide
- Error Handling
- Usage Examples
`bashInstall dependencies
npm install
The logger follows a layered architecture:
1. Core Layer - Types and interfaces
2. Utility Layer - ID generation, serialization, validation
3. Transport Layer - Individual transport implementations
4. Logger Layer - Main logger and scoped logger classes
MIT