feat: enhanced logging to file support, redirecting all stdout and stderr to log file.
This feature woulb be useful for troubleshooting daemonized bots since now all exceptions are also wrote to log file.
This commit is contained in:
parent
aba9eea336
commit
a58af46f15
@ -700,6 +700,7 @@ if __name__ == '__main__':
|
|||||||
var.db = SettingsDatabase(var.dbfile)
|
var.db = SettingsDatabase(var.dbfile)
|
||||||
|
|
||||||
# Setup logger
|
# Setup logger
|
||||||
|
|
||||||
bot_logger = logging.getLogger("bot")
|
bot_logger = logging.getLogger("bot")
|
||||||
formatter = logging.Formatter('[%(asctime)s %(levelname)s %(threadName)s] %(message)s', "%b %d %H:%M:%S")
|
formatter = logging.Formatter('[%(asctime)s %(levelname)s %(threadName)s] %(message)s', "%b %d %H:%M:%S")
|
||||||
bot_logger.setLevel(logging.INFO)
|
bot_logger.setLevel(logging.INFO)
|
||||||
@ -714,7 +715,10 @@ if __name__ == '__main__':
|
|||||||
logfile = util.solve_filepath(var.config.get('bot', 'logfile'))
|
logfile = util.solve_filepath(var.config.get('bot', 'logfile'))
|
||||||
handler = None
|
handler = None
|
||||||
if logfile:
|
if logfile:
|
||||||
|
print(f"Redirecting stdout and stderr to log file: {logfile}")
|
||||||
handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB
|
handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB
|
||||||
|
sys.stdout = util.LoggerIOWrapper(bot_logger, logging.INFO, fallback_io_buffer=sys.stdout.buffer)
|
||||||
|
sys.stderr = util.LoggerIOWrapper(bot_logger, logging.ERROR, fallback_io_buffer=sys.stderr.buffer)
|
||||||
else:
|
else:
|
||||||
handler = logging.StreamHandler()
|
handler = logging.StreamHandler()
|
||||||
|
|
||||||
@ -755,3 +759,4 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Start the main loop.
|
# Start the main loop.
|
||||||
var.bot.loop()
|
var.bot.loop()
|
||||||
|
|
||||||
|
14
util.py
14
util.py
@ -4,6 +4,7 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import magic
|
import magic
|
||||||
import os
|
import os
|
||||||
|
import io
|
||||||
import sys
|
import sys
|
||||||
import variables as var
|
import variables as var
|
||||||
import zipfile
|
import zipfile
|
||||||
@ -335,3 +336,16 @@ def youtube_search(query):
|
|||||||
error_traceback = traceback.format_exc().split("During")[0]
|
error_traceback = traceback.format_exc().split("During")[0]
|
||||||
log.error("util: youtube query failed with error:\n %s" % error_traceback)
|
log.error("util: youtube query failed with error:\n %s" % error_traceback)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class LoggerIOWrapper(io.TextIOWrapper):
|
||||||
|
def __init__(self, logger: logging.Logger, logging_level, fallback_io_buffer):
|
||||||
|
super().__init__(fallback_io_buffer, write_through=True)
|
||||||
|
self.logger = logger
|
||||||
|
self.logging_level = logging_level
|
||||||
|
|
||||||
|
def write(self, text):
|
||||||
|
if isinstance(text, bytes):
|
||||||
|
self.logger.log(self.logging_level, text.decode('utf-8').rstrip())
|
||||||
|
else:
|
||||||
|
self.logger.log(self.logging_level, text.rstrip())
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user