NekoBot uses loguru for logging management, providing powerful log recording and viewing capabilities.
| Level | Description | Use Case |
|---|---|---|
| TRACE | Most detailed trace info | Debugging and performance analysis |
| DEBUG | Debug information | Development and debugging |
| INFO | General information | Normal operation information |
| WARNING | Warning information | Potential issues |
| ERROR | Error information | Errors and exceptions |
| CRITICAL | Critical errors | System cannot continue |
Configure logging in main.py:
logger.remove()
logger.add(
sys.stdout,
format="{time:YYYY-MM-DD HH:mm:ss.SSS} <level>[{level}]</level> {message}",
level="DEBUG",
colorize=True,
)logger.add(
"logs/nekobot_{time:YYYY-MM-DD}.log",
rotation="00:00", # Rotate daily at midnight
retention="30 days", # Keep for 30 days
level="INFO",
compression="zip", # Compress old logs
encoding="utf-8"
)| Option | Description | Example |
|---|---|---|
| format | Log format | "{time} - {level} - {message}" |
| level | Log level | "DEBUG" |
| rotation | Log rotation | "00:00", "500 MB" |
| retention | Retention period | "30 days", "1 week" |
| compression | Compression format | "zip", "gzip" |
| encoding | File encoding | "utf-8" |
| colorize | Colored output | True, False |
from loguru import logger
class MyPlugin(BasePlugin):
async def on_load(self):
logger.info(f"{self.name} loaded")
@register("hello", "Say hello")
async def hello_command(self, args, message):
logger.debug(f"Received command: /hello from {message['user_id']}")
try:
await self.send_group_message(
message['group_id'],
message['user_id'],
"Hello!"
)
logger.info("Message sent successfully")
except Exception as e:
logger.error(f"Failed to send message: {e}")2025-01-01 12:00:00.123 [INFO] NekoBot startedlogger.add(
"logs/nekobot.log",
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>"
)| Variable | Description | Example |
|---|---|---|
| Time | 2025-01-01 12:00:00 | |
| Log level | INFO | |
| Log message | NekoBot started | |
| Module name | __main__ | |
| Function name | main | |
| Line number | 42 | |
| File name | main.py | |
| Exception info | Exception stack trace |
Connect WebSocket to receive real-time logs:
const ws = new WebSocket("ws://localhost:6285/ws");
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe", channels: ["logs"] }));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.channel === "logs") {
console.log(data.data);
}
};# View logs in real-time
tail -f logs/nekobot_*.log
# Filter logs by level
grep ERROR logs/nekobot_*.log
# View last 100 lines
tail -n 100 logs/nekobot_*.loglogger.add(
"logs/nekobot.log",
rotation="00:00", # Rotate daily at midnight
retention="7 days" # Keep for 7 days
)logger.add(
"logs/nekobot.log",
rotation="100 MB", # Rotate every 100MB
retention="10 files" # Keep last 10 files
)def should_rotate(message, file):
return message.record["exception"] is not None
logger.add(
"logs/nekobot.log",
rotation=should_rotate # Rotate on exception
)logger.add(
"logs/nekobot.log",
rotation="00:00",
compression="zip" # Auto-compress old logs
)Supported compression formats:
zipgztarlogger.add(
"logs/nekobot.log",
filter=lambda record: record["level"].name in ["INFO", "WARNING", "ERROR"]
)logger.add(
"logs/nekobot.log",
filter=lambda record: "my_plugin" not in record["name"]
)def custom_filter(record):
return record["message"].startswith("IMPORTANT")
logger.add(
"logs/important.log",
filter=custom_filter
)try:
await some_async_operation()
except Exception as e:
logger.exception("Operation failed")
# or
logger.opt(exception=True).error("Operation failed")logger.opt(depth=2).info("Logging from caller")Reduce log level or increase rotation frequency.
Check log configuration and file permissions.
Ensure file encoding is utf-8.
Use INFO or higher level in production environment.