diff --git a/bot.py b/bot.py index c8bc39e..2c7b0cd 100644 --- a/bot.py +++ b/bot.py @@ -13,6 +13,7 @@ from cogs.utils.localizer import Localizer from cogs.utils.localizer import LocalizerWrapper from cogs.utils.alias import Aliaser from cogs.utils.context import Context +from cogs.utils.logger import BotLogger from cogs.helpformatter import commandhelper from cogs.utils.paginator import Scroller @@ -57,12 +58,15 @@ class Bot(commands.Bot): self.session = aiohttp.ClientSession(loop=self.loop) self.debug = debug + self.main_logger = logger + self.logger = self.main_logger.bot_logger.getChild("Bot") + self.logger.debug("Debug: %s" % debug) for extension in initial_extensions: try: self.load_extension(extension) - except Exception as e: - print(e) + except Exception: + self.logger.exception("Loading of extension %s failed" % extension) async def on_command_error(self, ctx, err): if not self.debug: @@ -73,16 +77,21 @@ class Bot(commands.Bot): await scroller.start_scrolling() if isinstance(err, commands.CommandInvokeError): + self.logger.debug("Error running command: %s\n Traceback: %s" + % (ctx.command, traceback.format_exception(err.__traceback__))) pass elif isinstance(err, commands.NoPrivateMessage): + self.logger.debug("Error running command: %s\n Traceback: %s" + % (ctx.command, traceback.format_exception(err.__traceback__))) await ctx.send('That command is not available in DMs') elif isinstance(err, commands.CommandOnCooldown): await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. Try again in `{err.retry_after:.1f}` seconds.") elif isinstance(err, commands.CheckFailure): - print('check failure') + self.logger.debug("Error running command: %s\n Traceback: %s" + % (ctx.command, traceback.format_exception(err.__traceback__))) pass elif isinstance(err, commands.CommandNotFound): @@ -114,14 +123,13 @@ class Bot(commands.Bot): async def on_ready(self): if not hasattr(self, 'uptime'): self.uptime = time.time() - if self.debug: - print('\n\nDebug mode') for extension in on_ready_extensions: try: + self.logger.debug("Loading extension %s" % extension) self.load_extension(extension) except Exception as e: - print(e) + self.logger.exception("Loading of extension %s failed" % extension) print(f'\nLogged in as: {self.user.name}' + f' in {len(self.guilds)} servers.') @@ -144,8 +152,10 @@ def run_bot(debug: bool=False): bot = Bot(debug=debug) bot.run() + if __name__ == '__main__': + state = False if 'debug' in sys.argv: - run_bot(debug=True) - else: - run_bot(debug=False) + state = True + logger = BotLogger(state, conf.get('log_path', '/data/logs')) + run_bot(debug=state) diff --git a/cogs/music.py b/cogs/music.py index 929b610..0c4178f 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -29,7 +29,7 @@ url_rx = re.compile('https?:\\/\\/(?:www\\.)?.+') class Music(commands.Cog): def __init__(self, bot): self.bot = bot - + self.logger = self.bot.main_logger.bot_logger.getChild("Music") if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads. bot.lavalink = lavalink.Client(bot.user.id, player=MixPlayer) @@ -37,6 +37,7 @@ class Music(commands.Cog): conf = yaml.load(f, Loader=yaml.SafeLoader) bot.lavalink.add_node(**conf['lavalink nodes']['main']) + self.logger.debug("Adding Lavalink node") bot.add_listener(bot.lavalink.voice_update_handler, 'on_socket_response') async def cog_check(self, ctx): diff --git a/cogs/utils/logger.py b/cogs/utils/logger.py new file mode 100644 index 0000000..a34d12c --- /dev/null +++ b/cogs/utils/logger.py @@ -0,0 +1,38 @@ +import logging.handlers +import logging +import os + +class BotLogger(object): + def __init__(self, debug=None, data_location=None): + self.log_location = data_location + self.log_level = debug + + if self.log_level: + self.log_level = logging.DEBUG + + else: + self.log_level = logging.INFO + + self.bot_logger = logging.getLogger("logger") + self.bot_logger.setLevel(logging.DEBUG) + + log_formatter = logging.Formatter("%(asctime)s:%(name)s:%(levelname)s:%(message)s") + + if self.log_location is not None: + if not os.path.isdir(self.log_location): + os.mkdir(self.log_location) + print(f"Creating logging directory: {self.log_location}") + if self.log_level: + print(os.path.abspath(self.log_location)) + file_logger = logging.handlers.RotatingFileHandler(f'{self.log_location}/bot.log', + mode='a', maxBytes=50000, encoding=None, delay=0, backupCount=5) + file_logger.setLevel(self.log_level) + file_logger.setFormatter(log_formatter) + self.bot_logger.addHandler(file_logger) + + console_handler = logging.StreamHandler() + console_handler.setLevel(self.log_level) + console_handler.setFormatter(log_formatter) + + self.bot_logger.addHandler(console_handler) + diff --git a/data/config.yaml.example b/data/config.yaml.example index 88402be..f1f4f8b 100644 --- a/data/config.yaml.example +++ b/data/config.yaml.example @@ -6,6 +6,9 @@ bot: # Where the bot will look for translations locale_path: ./localization +# Where the bot will place logs +log_path: ./data/logs + # Settings used if server settings aren't specified default server settings: prefix: