Discord.py配置日志后未输出代码错误,求助排查
问题:Discord机器人加载Cog时错误不输出日志
我用discord.utils.setup_logging配置了控制台错误输出,单独运行以下代码时,语法错误、警告等各类信息都能正常显示:
discord.utils.setup_logging(level = logging.ERROR, root = False) discord.utils.setup_logging(level = logging.WARN, root = False) discord.utils.setup_logging(level = logging.WARNING, root = False) discord.utils.setup_logging(level = logging.INFO, root = False)
但新增一个Cog模块后,模块里的代码明明有错误,控制台却没输出任何错误提示,而且对应的命令也无法执行。我需要找出日志不输出的原因,同时修复Cog里的代码问题。
主文件代码
# -*- coding: utf-8 -*- import discord from discord.ext import commands from config import settings import asyncio import os import logging from time import strftime from time import gmtime import sqlite3 bot = commands.Bot(settings['prefix'], intents = discord.Intents.all()) bot.remove_command('help') discord.utils.setup_logging(level = logging.ERROR, root = False) discord.utils.setup_logging(level = logging.WARN, root = False) discord.utils.setup_logging(level = logging.WARNING, root = False) discord.utils.setup_logging(level = logging.INFO, root = False) @bot.event async def on_ready(): print(f'{bot.user.name} підключився до Discord.') async def load_extensions(): """Load cogs for main file """ for filename in os.listdir('./cogs'): if filename.endswith('.py'): await bot.load_extension(f'cogs.{filename[:-3]}') async def main(): await load_extensions() await bot.start(settings['token']) if __name__ == '__main__': asyncio.run(main())
Cog文件(cogs/test.py)代码
class test(commands.Cog, name='Інформативні команди'): def __init__(self, bot): self.bot = bot @commands.command() async def server(self, ctx): snsfwlvl = str(ctx.guild.explicit_content_filter) if snsfwlvl == 'all_members': snsfwlvl = 'Перевіряти кожного учасника' elif snsfwlvl == 'no_role': snsfwlvl = 'Перевіряти учасників без ролей' elif snsfwlvl == 'disabled': snsfwlvl = 'Не встановлено' else: snsfwlvl = 'Не знайдено' text_channels = len(ctx.guild.text_channels) voice_channels = len(ctx.guild.voice_channels) stage_channels = len(ctx.guild.stage_channels) total_channels = text_channels + voice_channels + stage_channels total_members = ctx.guild.members online = 0 idle = 0 offline = 0 humans = 0 bots = 0 for member in total_members: if member.status == 'online': online+=1 if member.status == 'idle': idle+=1 if member.status == 'oflline': oflline+=1 if member.bot is True: bot+=1 if member.bot is False: humans+=1 embed = discord.Embed( color = settings['color'], title = f"Інформація про сервер {ctx.guild.name}" ) created_at = ctx.guild.created_at embed.add_field( name = f"Власник сервера", value = f"{ctx.guild.owner.mention}", inline = True ) embed.add_field( name = "Id", value = ctx.guild.id, inline = True ) embed.add_field( name = "Створений: ", value = strftime("%d.%m.%y %H:%M:%S", created_at), inline = True ) embed.add_field( name = "Перевірка: ", value = snsfwlvl, inline = True ) embed.add_field( name = "Учасники:", value = f"<:total_members:1038376493669154836>Всього: **{total_members}**\n<:members:1038376476870979594>Учасників: **{humans}**\n<:bots:1038376472521482263>Ботів: **{bots}**", inline = True ) embed.add_field( name = "Статуси:", value = f"<:ofline:1038376481774120970>Онлайн: **{online}**\n<:idle:1038376474958381056>Відійшли: **{idle}**\n<:ofline:1038376481774120970>Не в мережі: **{offline}**", inline = True ) embed.add_field( name = "Канали:", value = f"<:total_channels:1038376491576205375>Всього: **{total_channels}**\n<:text_channels:1038376489399357504>Текстові: **{text_channels}**\n<:voice_channels:1038376495414001724>Голосові: **{voice_channels}**" ) embed.set_thumbnail(url = ctx.guild.icon) await ctx.reply(embed=embed)
问题分析与解决方案
1. 日志不输出的原因
你多次调用discord.utils.setup_logging,每次调用都会重置日志配置,且root=False意味着不会配置全局根日志器——而加载Cog时的错误通常属于根日志器的管辖范围,多次调用还会导致配置冲突。
修复方案:只调用一次setup_logging,设置需要的最高日志级别(比如logging.INFO,它会自动包含WARNING、ERROR等更低级别的日志),同时开启root=True:
# 替换原有的四次调用,只保留这一行 discord.utils.setup_logging(level=logging.INFO, root=True)
如果还是无法捕获日志,可以手动添加自定义日志处理器兜底:
import logging # 创建控制台输出处理器 handler = logging.StreamHandler() handler.setLevel(logging.INFO) # 设置日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 给discord和commands模块的日志器添加处理器 discord_logger = logging.getLogger('discord') discord_logger.addHandler(handler) discord_logger.setLevel(logging.INFO) commands_logger = logging.getLogger('discord.ext.commands') commands_logger.addHandler(handler) commands_logger.setLevel(logging.INFO)
2. Cog代码中的错误
你的Cog代码存在多处拼写、逻辑和语法错误,这也是命令无法执行的核心原因:
- 拼写错误:
oflline应为offline(两处),bot+=1应为bots+=1 - 逻辑错误:
total_members是成员对象列表,直接输出会显示内存地址,需用len(total_members)获取数量 - 依赖缺失:未导入
settings和必要模块,导致创建Embed时报错 - 缺少注册逻辑:Cog末尾没有
setup函数,Bot无法加载该模块 - 时间格式错误:
strftime需要传入时间元组,需用created_at.timetuple()转换
修复后的Cog代码:
from config import settings import discord from discord.ext import commands from time import strftime class test(commands.Cog, name='Інформативні команди'): def __init__(self, bot): self.bot = bot @commands.command() async def server(self, ctx): snsfwlvl = str(ctx.guild.explicit_content_filter) if snsfwlvl == 'all_members': snsfwlvl = 'Перевіряти кожного учасника' elif snsfwlvl == 'no_role': snsfwlvl = 'Перевіряти учасників без ролей' elif snsfwlvl == 'disabled': snsfwlvl = 'Не встановлено' else: snsfwlvl = 'Не знайдено' text_channels = len(ctx.guild.text_channels) voice_channels = len(ctx.guild.voice_channels) stage_channels = len(ctx.guild.stage_channels) total_channels = text_channels + voice_channels + stage_channels total_members = ctx.guild.members online = 0 idle = 0 offline = 0 humans = 0 bots = 0 for member in total_members: # 使用discord.Status枚举更可靠 if member.status == discord.Status.online: online += 1 elif member.status == discord.Status.idle: idle += 1 elif member.status == discord.Status.offline: offline += 1 if member.bot: bots += 1 else: humans += 1 embed = discord.Embed( color=settings['color'], title=f"Інформація про сервер {ctx.guild.name}" ) created_at = ctx.guild.created_at embed.add_field( name="Власник сервера", value=f"{ctx.guild.owner.mention}", inline=True ) embed.add_field( name="Id", value=ctx.guild.id, inline=True ) embed.add_field( name="Створений: ", value=strftime("%d.%m.%y %H:%M:%S", created_at.timetuple()), inline=True ) embed.add_field( name="Перевірка: ", value=snsfwlvl, inline=True ) embed.add_field( name="Учасники:", value=f"<:total_members:1038376493669154836>Всього: **{len(total_members)}**\n<:members:1038376476870979594>Учасників: **{humans}**\n<:bots:1038376472521482263>Ботів: **{bots}**", inline=True ) embed.add_field( name="Статуси:", value=f"<:ofline:1038376481774120970>Онлайн: **{online}**\n<:idle:1038376474958381056>Відійшли: **{idle}**\n<:ofline:1038376481774120970>Не в мережі: **{offline}**", inline=True ) embed.add_field( name="Канали:", value=f"<:total_channels:1038376491576205375>Всього: **{total_channels}**\n<:text_channels:1038376489399357504>Текстові: **{text_channels}**\n<:voice_channels:1038376495414001724>Голосові: **{voice_channels}**" ) # 防止服务器无图标时报错 if ctx.guild.icon: embed.set_thumbnail(url=ctx.guild.icon.url) await ctx.reply(embed=embed) # 必须添加的Cog注册函数 async def setup(bot): await bot.add_cog(test(bot))
内容的提问来源于stack exchange,提问作者Bohdan
相关产品推荐
相关产品推荐

