97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
import sys
|
|
import logging
|
|
import asyncio
|
|
from discord import AllowedMentions
|
|
|
|
from cmdClient.logger import cmd_log_handler
|
|
|
|
from utils.lib import mail, split_text
|
|
|
|
from .client import client
|
|
from .config import conf
|
|
|
|
|
|
# Setup the logger
|
|
logger = logging.getLogger()
|
|
log_fmt = logging.Formatter(fmt='[{asctime}][{levelname:^8}] {message}', datefmt='%d/%m | %H:%M:%S', style='{')
|
|
# term_handler = logging.StreamHandler(sys.stdout)
|
|
# term_handler.setFormatter(log_fmt)
|
|
# logger.addHandler(term_handler)
|
|
# logger.setLevel(logging.INFO)
|
|
|
|
|
|
class LessThanFilter(logging.Filter):
|
|
def __init__(self, exclusive_maximum, name=""):
|
|
super(LessThanFilter, self).__init__(name)
|
|
self.max_level = exclusive_maximum
|
|
|
|
def filter(self, record):
|
|
# non-zero return means we log this message
|
|
return 1 if record.levelno < self.max_level else 0
|
|
|
|
|
|
logger.setLevel(logging.NOTSET)
|
|
|
|
logging_handler_out = logging.StreamHandler(sys.stdout)
|
|
logging_handler_out.setLevel(logging.DEBUG)
|
|
logging_handler_out.setFormatter(log_fmt)
|
|
logging_handler_out.addFilter(LessThanFilter(logging.WARNING))
|
|
logger.addHandler(logging_handler_out)
|
|
|
|
logging_handler_err = logging.StreamHandler(sys.stderr)
|
|
logging_handler_err.setLevel(logging.WARNING)
|
|
logging_handler_err.setFormatter(log_fmt)
|
|
logger.addHandler(logging_handler_err)
|
|
|
|
|
|
# Define the context log format and attach it to the command logger as well
|
|
@cmd_log_handler
|
|
def log(message, context="GLOBAL", level=logging.INFO, post=True):
|
|
# Add prefixes to lines for better parsing capability
|
|
lines = message.splitlines()
|
|
if len(lines) > 1:
|
|
lines = [
|
|
'┌ ' * (i == 0) + '│ ' * (0 < i < len(lines) - 1) + '└ ' * (i == len(lines) - 1) + line
|
|
for i, line in enumerate(lines)
|
|
]
|
|
else:
|
|
lines = ['─ ' + message]
|
|
|
|
for line in lines:
|
|
logger.log(level, '\b[{}] {}'.format(
|
|
str(context).center(22, '='),
|
|
line
|
|
))
|
|
|
|
# Fire and forget to the channel logger, if it is set up
|
|
if post and client.is_ready():
|
|
asyncio.ensure_future(live_log(message, context, level))
|
|
|
|
|
|
# Live logger that posts to the logging channels
|
|
async def live_log(message, context, level):
|
|
if level >= logging.INFO:
|
|
log_chid = conf.bot.getint('log_channel')
|
|
|
|
# Generate the log messages
|
|
header = "[{}][{}]".format(logging.getLevelName(level), str(context))
|
|
if len(message) > 1900:
|
|
blocks = split_text(message, blocksize=1900, code=False)
|
|
else:
|
|
blocks = [message]
|
|
|
|
if len(blocks) > 1:
|
|
blocks = [
|
|
"```md\n{}[{}/{}]\n{}\n```".format(header, i+1, len(blocks), block) for i, block in enumerate(blocks)
|
|
]
|
|
else:
|
|
blocks = ["```md\n{}\n{}\n```".format(header, blocks[0])]
|
|
|
|
# Post the log messages
|
|
if log_chid:
|
|
[await mail(client, log_chid, content=block, allowed_mentions=AllowedMentions.none()) for block in blocks]
|
|
|
|
|
|
# Attach logger to client, for convenience
|
|
client.log = log
|