Find us on social media
LoggingDebugWinston5 min read
Logging and debugging your bot
Configure Winston or Pino for Node.js, Python logging module, log levels, structured logging and rotation.
Why structured logging?
console.log doesn't scale. You need log levels, timestamps, file rotation and consistent formatting to diagnose production issues.
Node.js: Winston
bash
npm install winston winston-daily-rotate-filejavascript
const winston = require('winston');
require('winston-daily-rotate-file');
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
)
}),
new winston.transports.DailyRotateFile({
filename: 'logs/bot-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '14d'
})
]
});
// Usage
logger.info('Bot started', { guilds: client.guilds.cache.size });
logger.warn('Rate limit approaching', { bucket: '/channels/123' });
logger.error('Command error', { command: 'ban', error: err.message });Node.js: Pino (faster)
bash
npm install pino pino-prettyjavascript
const pino = require('pino');
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: { colorize: true, translateTime: 'SYS:standard' }
}
});
logger.info({ event: 'ready', guilds: 42 }, 'Bot connected');Python: logging module
python
import logging
from logging.handlers import RotatingFileHandler
def setup_logging():
logger = logging.getLogger('discord_bot')
logger.setLevel(logging.INFO)
# Format
formatter = logging.Formatter(
'%(asctime)s | %(levelname)-8s | %(name)s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# Console
console = logging.StreamHandler()
console.setFormatter(formatter)
logger.addHandler(console)
# File with rotation
file_handler = RotatingFileHandler(
'logs/bot.log', maxBytes=10*1024*1024, backupCount=5
)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
logger = setup_logging()
logger.info('Bot started with %d guilds', len(bot.guilds))View logs in production
bash
# PM2 real-time logs
pm2 logs my-bot --lines 100
# Systemd/journalctl
journalctl -u discord-bot -f
journalctl -u discord-bot --since '1 hour ago'
# Search for specific errors
grep -i 'error' logs/bot-2026-01-15.logConfigure system logrotate
bash
sudo nano /etc/logrotate.d/discord-botterminal
/opt/bots/*/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
}Recommendations
- Use levels: error > warn > info > debug
- Never log tokens or sensitive data
- Configure rotation to prevent filling the disk
- In production use
infolevel; in development usedebug - Include relevant context (guild_id, user_id, command) in every log
Was this guide helpful?