Chuyển tới nội dung chính

Logger - Winston Logging System

Winston-based logging system with console and file transports, structured JSON output, and log rotation for production environments.

Overview

graph TB
subgraph Application
SRC[Source Code]
end

subgraph Logger["Winston Logger"]
FORMAT[Format Pipeline]
CONSOLE[Console Transport]
FILE[File Transport]
ERROR[Error File]
end

subgraph Output
STDOUT[stdout/stderr]
LOGS[logs/combined.log]
ERRLOGS[logs/error.log]
end

SRC --> FORMAT
FORMAT --> CONSOLE
FORMAT --> FILE
FORMAT --> ERROR
CONSOLE --> STDOUT
FILE --> LOGS
ERROR --> ERRLOGS

Features

FeatureDescription
Structured LoggingJSON format with metadata
Console OutputColorized human-readable output
File RotationDaily rotation, 14-day retention
Error IsolationSeparate error log file
Request LoggingHTTP request/response logging
PerformanceAsync I/O, buffered writes

Configuration

// utils/logger.ts
import winston from 'winston';

const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: { service: 'uip-traffic-backend' },
transports: [
// Console transport (development)
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
)
}),
// Combined log file
new winston.transports.File({
filename: 'logs/combined.log',
maxsize: 5242880, // 5MB
maxFiles: 14
}),
// Error log file
new winston.transports.File({
filename: 'logs/error.log',
level: 'error'
})
]
});

export { logger };

Log Levels

LevelPriorityDescriptionUsage
error0Error conditionsExceptions, failures
warn1Warning conditionsDeprecations, retries
info2InformationalService status, events
http3HTTP requestsRequest/response logs
verbose4Verbose infoDetailed operations
debug5Debug informationDevelopment debugging
silly6All messagesEverything

Usage Examples

Basic Logging

import { logger } from '../utils/logger';

// Simple messages
logger.info('Server started on port 5000');
logger.warn('Cache miss for entity');
logger.error('Database connection failed');
logger.debug('Processing entity batch');

// With metadata
logger.info('Camera fetched', {
cameraId: 'urn:ngsi-ld:Camera:001',
responseTime: 125
});

// Error with stack trace
try {
throw new Error('Connection refused');
} catch (error) {
logger.error('Failed to connect', { error });
}

Request Logging

// Middleware for request logging
app.use((req, res, next) => {
const start = Date.now();

res.on('finish', () => {
logger.http({
method: req.method,
url: req.originalUrl,
status: res.statusCode,
duration: Date.now() - start,
userAgent: req.get('User-Agent')
});
});

next();
});

Agent Logging

// In EcoTwinAgent
logger.info('EcoTwin processing request', {
location: { lat: 10.77, lng: 106.70 },
userProfile: profile.id
});

logger.debug('Gemini API response', {
tokens: response.usageMetadata?.totalTokenCount
});

Log Output Examples

Console Output (Development)

info: Server started on port 5000
info: ✅ Connected to Stellio Context Broker
warn: ⚠️ Cache miss for Camera:001
error: ❌ Neo4j connection failed

JSON Output (Production)

{
"level": "info",
"message": "Camera fetched",
"service": "uip-traffic-backend",
"timestamp": "2025-11-29T10:30:00.000Z",
"cameraId": "urn:ngsi-ld:Camera:001",
"responseTime": 125
}

Error Log

{
"level": "error",
"message": "Database connection failed",
"service": "uip-traffic-backend",
"timestamp": "2025-11-29T10:30:00.000Z",
"error": {
"message": "Connection refused",
"stack": "Error: Connection refused\n at PostgresService..."
}
}

Environment Configuration

# .env
LOG_LEVEL=debug # Logging level
LOG_FORMAT=json # Output format (json/simple)
LOG_DIR=./logs # Log directory

Log File Rotation

// Daily rotation with Winston DailyRotateFile
import DailyRotateFile from 'winston-daily-rotate-file';

const rotateTransport = new DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m', // Rotate at 20MB
maxFiles: '14d', // Keep 14 days
zippedArchive: true
});

References