diff --git a/bazarr/logger.py b/bazarr/logger.py index 5dae44d55..44812a90f 100644 --- a/bazarr/logger.py +++ b/bazarr/logger.py @@ -14,18 +14,33 @@ from config import settings logger = logging.getLogger() -class OneLineExceptionFormatter(logging.Formatter): +class FileHandlerFormatter(logging.Formatter): + """Formatter that removes apikey from logs.""" + APIKEY_RE = re.compile(r'apikey(?:=|%3D)([a-zA-Z0-9]+)') + IPv4_RE = re.compile(r'\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]' + r'[0-9]|[1-9]?[0-9])\b') + def formatException(self, exc_info): """ Format an exception so that it prints on a single line. """ - result = super(OneLineExceptionFormatter, self).formatException(exc_info) + result = super(FileHandlerFormatter, self).formatException(exc_info) return repr(result) # or format into one line however you want to - + + def formatApikey(self, s): + return re.sub(self.APIKEY_RE, 'apikey=(removed)', s) + + def formatIPv4(self, s): + return re.sub(self.IPv4_RE, '***.***.***.***', s) + def format(self, record): - s = super(OneLineExceptionFormatter, self).format(record) + s = super(FileHandlerFormatter, self).format(record) if record.exc_text: s = s.replace('\n', '') + '|' + + s = self.formatApikey(s) + s = self.formatIPv4(s) + return s @@ -57,18 +72,15 @@ def configure_logging(debug=False): ch.setFormatter(cf) ch.setLevel(log_level) - # ch.addFilter(MyFilter()) logger.addHandler(ch) # File Logging global fh fh = TimedRotatingFileHandler(os.path.join(args.config_dir, 'log/bazarr.log'), when="midnight", interval=1, backupCount=7, delay=True, encoding='utf-8') - f = OneLineExceptionFormatter('%(asctime)s|%(levelname)-8s|%(name)-32s|%(message)s|', - '%d/%m/%Y %H:%M:%S') + f = FileHandlerFormatter('%(asctime)s|%(levelname)-8s|%(name)-32s|%(message)s|', + '%d/%m/%Y %H:%M:%S') fh.setFormatter(f) - fh.addFilter(BlacklistFilter()) - fh.addFilter(PublicIPFilter()) fh.setLevel(log_level) logger.addHandler(fh) @@ -116,85 +128,6 @@ def configure_logging(debug=False): logging.getLogger("stevedore.extension").setLevel(logging.CRITICAL) -class MyFilter(logging.Filter): - def __init__(self): - super(MyFilter, self).__init__() - - def filter(self, record): - if record.name != 'root': - return 0 - return 1 - - -class ArgsFilteringFilter(logging.Filter): - def filter_args(self, record, func): - if isinstance(record.args, (list, tuple)): - final_args = [] - for arg in record.args: - if not isinstance(arg, str): - final_args.append(arg) - continue - - final_args.append(func(arg)) - record.args = type(record.args)(final_args) - elif isinstance(record.args, dict): - for key, arg in record.args.items(): - if not isinstance(arg, str): - continue - - record.args[key] = func(arg) - - -class BlacklistFilter(ArgsFilteringFilter): - """ - Log filter for blacklisted tokens and passwords - """ - APIKEY_RE = re.compile(r'apikey(?:=|%3D)([a-zA-Z0-9]+)') - - def __init__(self): - super(BlacklistFilter, self).__init__() - - def filter(self, record): - def mask_apikeys(s): - apikeys = self.APIKEY_RE.findall(s) - for apikey in apikeys: - s = s.replace(apikey, 8 * '*' + apikey[-2:]) - return s - - try: - record.msg = mask_apikeys(record.msg) - self.filter_args(record, mask_apikeys) - except: - pass - return 1 - - -class PublicIPFilter(ArgsFilteringFilter): - """ - Log filter for public IP addresses - """ - IPV4_RE = re.compile(r'[0-9]+(?:\.[0-9]+){3}(?!\d*-[a-z0-9]{6})') - - def __init__(self): - super(PublicIPFilter, self).__init__() - - def filter(self, record): - def mask_ipv4(s): - ipv4 = self.IPV4_RE.findall(s) - for ip in ipv4: - s = s.replace(ip, ip.partition('.')[0] + '.***.***.***') - return s - - try: - # Currently only checking for ipv4 addresses - record.msg = mask_ipv4(record.msg) - self.filter_args(record, mask_ipv4) - except: - pass - - return 1 - - def empty_log(): fh.doRollover() logging.info('BAZARR Log file emptied')