mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-20 02:36:19 +08:00
* Fixes #388 * Bump docker/setup-buildx-action from 2 to 3 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump docker/login-action from 2 to 3 Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump gitpython from 3.1.35 to 3.1.36 Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.35 to 3.1.36. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.35...3.1.36) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.11.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.11.0) - [github.com/asottile/pyupgrade: v3.10.1 → v3.11.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.11.0) - [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1) * Error handling when BHD API doesn't respond * add BHD specific announce related issues * handle JSONDecodeError * Special mapping to leave torrents uncategorized on cat-update (#398) Special mapping to leave torrents uncategorized on cat-update (closes #395) * Bump gitpython from 3.1.36 to 3.1.37 Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.36 to 3.1.37. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.36...3.1.37) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump ruamel-yaml from 0.17.32 to 0.17.33 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.32 to 0.17.33. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * last_active flag for share_limits (#397) Added a last_active flag for share_limits to resume torrents and avoid cleanup if there was activity in the last X minutes. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#405) updates: - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.11.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.11.0) - [github.com/asottile/pyupgrade: v3.10.1 → v3.13.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.13.0) - [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * Bump schedule from 1.2.0 to 1.2.1 Bumps [schedule](https://github.com/dbader/schedule) from 1.2.0 to 1.2.1. - [Changelog](https://github.com/dbader/schedule/blob/master/HISTORY.rst) - [Commits](https://github.com/dbader/schedule/compare/1.2.0...1.2.1) --- updated-dependencies: - dependency-name: schedule dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump ruamel-yaml from 0.17.33 to 0.17.34 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.33 to 0.17.34. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix exit codes when program fails (#411) Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * Bump ruamel-yaml from 0.17.34 to 0.17.35 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.34 to 0.17.35. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * [pre-commit.ci] pre-commit autoupdate (#409) updates: - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.12.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.12.0) - [github.com/asottile/pyupgrade: v3.10.1 → v3.14.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.14.0) - [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * New option cat in trackers (#400) * New option cat in trackers * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * update config.sample for #200 * add additional script to edit trackers * clarify remote_dir usage (#417) * Bump gitpython from 3.1.35 to 3.1.37 (#414) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.35 to 3.1.37. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.35...3.1.37) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#413) updates: - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.12.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.12.0) - [github.com/asottile/pyupgrade: v3.10.1 → v3.15.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.15.0) - [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> * 4.0.5 * Fixes #419 * Bump pre-commit from 3.4.0 to 3.5.0 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump gitpython from 3.1.37 to 3.1.38 Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.37 to 3.1.38. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.37...3.1.38) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Remove duplicates from when processing cleanup_dirs (#422) remove duplicates from cleanup_dirs * Bump gitpython from 3.1.38 to 3.1.40 Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.38 to 3.1.40. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.38...3.1.40) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump ruamel-yaml from 0.17.35 to 0.17.39 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.35 to 0.17.39. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fixes #426 * Bump qbittorrent-api from 2023.9.53 to 2023.10.54 Bumps [qbittorrent-api](https://github.com/rmartin16/qbittorrent-api) from 2023.9.53 to 2023.10.54. - [Release notes](https://github.com/rmartin16/qbittorrent-api/releases) - [Changelog](https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md) - [Commits](https://github.com/rmartin16/qbittorrent-api/compare/v2023.9.53...v2023.10.54) --- updated-dependencies: - dependency-name: qbittorrent-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump ruamel-yaml from 0.17.39 to 0.17.40 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.39 to 0.17.40. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump ruamel-yaml from 0.17.40 to 0.18.0 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.17.40 to 0.18.0. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Fixes #429 * Fixes bug in edit_tracker * Bump ruamel-yaml from 0.18.0 to 0.18.2 Bumps [ruamel-yaml](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree) from 0.18.0 to 0.18.2. --- updated-dependencies: - dependency-name: ruamel-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * 4.0.6 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Esteban Thilliez <77675611+estebanthi@users.noreply.github.com> Co-authored-by: Fabricio Silva <hi@fabricio.dev> Co-authored-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com> Co-authored-by: garypiner <36236331+garypiner@users.noreply.github.com>
300 lines
11 KiB
Python
Executable file
300 lines
11 KiB
Python
Executable file
"""Logging module"""
|
|
import io
|
|
import logging
|
|
import os
|
|
import re
|
|
import sys
|
|
import traceback
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
LOG_DIR = "logs"
|
|
|
|
CRITICAL = 50
|
|
FATAL = CRITICAL
|
|
ERROR = 40
|
|
WARNING = 30
|
|
WARN = WARNING
|
|
DRYRUN = 25
|
|
INFO = 20
|
|
DEBUG = 10
|
|
TRACE = 1
|
|
|
|
|
|
def fmt_filter(record):
|
|
"""Filter log message"""
|
|
record.levelname = f"[{record.levelname}]"
|
|
record.filename = f"[{record.filename}:{record.lineno}]"
|
|
return True
|
|
|
|
|
|
_srcfile = os.path.normcase(fmt_filter.__code__.co_filename)
|
|
|
|
|
|
class MyLogger:
|
|
"""Logger class"""
|
|
|
|
def __init__(self, logger_name, log_file, log_level, default_dir, screen_width, separating_character, ignore_ghost):
|
|
"""Initialize logger"""
|
|
self.logger_name = logger_name
|
|
self.default_dir = default_dir
|
|
self.screen_width = screen_width
|
|
self.separating_character = separating_character
|
|
self.ignore_ghost = ignore_ghost
|
|
self.log_dir = os.path.join(default_dir, LOG_DIR)
|
|
self.main_log = log_file if os.path.exists(os.path.dirname(log_file)) else os.path.join(self.log_dir, log_file)
|
|
self.main_handler = None
|
|
self.save_errors = False
|
|
self.saved_errors = []
|
|
self.config_handlers = {}
|
|
self.secrets = set()
|
|
self.spacing = 0
|
|
os.makedirs(self.log_dir, exist_ok=True)
|
|
self._logger = logging.getLogger(self.logger_name)
|
|
logging.DRYRUN = DRYRUN
|
|
logging.addLevelName(DRYRUN, "DRYRUN")
|
|
setattr(self._logger, "dryrun", lambda dryrun, *args: self._logger._log(DRYRUN, dryrun, args))
|
|
logging.TRACE = TRACE
|
|
logging.addLevelName(TRACE, "TRACE")
|
|
setattr(self._logger, "trace", lambda trace, *args: self._logger._log(TRACE, trace, args))
|
|
self._log_level = getattr(logging, log_level.upper())
|
|
self._logger.setLevel(self._log_level)
|
|
|
|
cmd_handler = logging.StreamHandler()
|
|
cmd_handler.setLevel(self._log_level)
|
|
|
|
self._logger.addHandler(cmd_handler)
|
|
|
|
def clear_errors(self):
|
|
"""Clear saved errors"""
|
|
self.saved_errors = []
|
|
|
|
def _get_handler(self, log_file, count=5):
|
|
"""Get handler for log file"""
|
|
max_bytes = 1024 * 1024 * 10
|
|
_handler = RotatingFileHandler(log_file, delay=True, mode="w", maxBytes=max_bytes, backupCount=count, encoding="utf-8")
|
|
self._formatter(handler=_handler)
|
|
# if os.path.isfile(log_file):
|
|
# _handler.doRollover()
|
|
return _handler
|
|
|
|
def _formatter(self, handler=None, border=True, log_only=False, space=False):
|
|
"""Format log message"""
|
|
console = f"| %(message)-{self.screen_width - 2}s |" if border else f"%(message)-{self.screen_width - 2}s"
|
|
file = f"{' '*65}" if space else "[%(asctime)s] %(filename)-27s %(levelname)-10s "
|
|
handlers = [handler] if handler else self._logger.handlers
|
|
for h in handlers:
|
|
if not log_only or isinstance(h, RotatingFileHandler):
|
|
h.setFormatter(logging.Formatter(f"{file if isinstance(h, RotatingFileHandler) else ''}{console}"))
|
|
|
|
def add_main_handler(self):
|
|
"""Add main handler to logger"""
|
|
self.main_handler = self._get_handler(self.main_log, count=19)
|
|
self.main_handler.addFilter(fmt_filter)
|
|
self._logger.addHandler(self.main_handler)
|
|
|
|
def remove_main_handler(self):
|
|
"""Remove main handler from logger"""
|
|
self._logger.removeHandler(self.main_handler)
|
|
|
|
def add_config_handler(self, config_key):
|
|
"""Add config handler to logger"""
|
|
if config_key in self.config_handlers:
|
|
self._logger.addHandler(self.config_handlers[config_key])
|
|
else:
|
|
self.config_handlers[config_key] = self._get_handler(os.path.join(self.log_dir, config_key + ".log"))
|
|
self._logger.addHandler(self.config_handlers[config_key])
|
|
|
|
def remove_config_handler(self, config_key):
|
|
"""Remove config handler from logger"""
|
|
if config_key in self.config_handlers:
|
|
self._logger.removeHandler(self.config_handlers[config_key])
|
|
|
|
def _centered(self, text, sep=" ", side_space=True, left=False):
|
|
"""Center text"""
|
|
if len(text) > self.screen_width - 2:
|
|
return text
|
|
space = self.screen_width - len(text) - 2
|
|
text = f"{' ' if side_space else sep}{text}{' ' if side_space else sep}"
|
|
if space % 2 == 1:
|
|
text += sep
|
|
space -= 1
|
|
side = int(space / 2) - 1
|
|
final_text = f"{text}{sep * side}{sep * side}" if left else f"{sep * side}{text}{sep * side}"
|
|
return final_text
|
|
|
|
def separator(self, text=None, space=True, border=True, side_space=True, left=False, loglevel="INFO"):
|
|
"""Print separator"""
|
|
sep = " " if space else self.separating_character
|
|
for handler in self._logger.handlers:
|
|
self._formatter(handler, border=False)
|
|
border_text = f"|{self.separating_character * self.screen_width}|"
|
|
if border:
|
|
self.print_line(border_text, loglevel)
|
|
if text:
|
|
text_list = text.split("\n")
|
|
for txt in text_list:
|
|
self.print_line(f"|{sep}{self._centered(txt, sep=sep, side_space=side_space, left=left)}{sep}|", loglevel)
|
|
if border:
|
|
self.print_line(border_text, loglevel)
|
|
for handler in self._logger.handlers:
|
|
self._formatter(handler)
|
|
return [text]
|
|
|
|
def print_line(self, msg, loglevel="INFO", *args, **kwargs):
|
|
"""Print line"""
|
|
loglvl = getattr(logging, loglevel.upper())
|
|
if self._logger.isEnabledFor(loglvl):
|
|
self._log(loglvl, str(msg), args, **kwargs)
|
|
return [str(msg)]
|
|
|
|
def trace(self, msg, *args, **kwargs):
|
|
"""Print trace"""
|
|
if self._logger.isEnabledFor(TRACE):
|
|
self._log(TRACE, str(msg), args, **kwargs)
|
|
|
|
def debug(self, msg, *args, **kwargs):
|
|
"""Print debug"""
|
|
if self._logger.isEnabledFor(DEBUG):
|
|
self._log(DEBUG, str(msg), args, **kwargs)
|
|
|
|
def info_center(self, msg, *args, **kwargs):
|
|
"""Print info centered"""
|
|
self.info(self._centered(str(msg)), *args, **kwargs)
|
|
|
|
def info(self, msg, *args, **kwargs):
|
|
"""Print info"""
|
|
if self._logger.isEnabledFor(INFO):
|
|
self._log(INFO, str(msg), args, **kwargs)
|
|
|
|
def dryrun(self, msg, *args, **kwargs):
|
|
"""Print dryrun"""
|
|
if self._logger.isEnabledFor(DRYRUN):
|
|
self._log(DRYRUN, str(msg), args, **kwargs)
|
|
|
|
def warning(self, msg, *args, **kwargs):
|
|
"""Print warning"""
|
|
if self._logger.isEnabledFor(WARNING):
|
|
self._log(WARNING, str(msg), args, **kwargs)
|
|
|
|
def error(self, msg, *args, **kwargs):
|
|
"""Print error"""
|
|
if self.save_errors:
|
|
self.saved_errors.append(msg)
|
|
if self._logger.isEnabledFor(ERROR):
|
|
self._log(ERROR, str(msg), args, **kwargs)
|
|
|
|
def critical(self, msg, *args, **kwargs):
|
|
"""Print critical"""
|
|
if self.save_errors:
|
|
self.saved_errors.append(msg)
|
|
if self._logger.isEnabledFor(CRITICAL):
|
|
self._log(CRITICAL, str(msg), args, **kwargs)
|
|
|
|
def stacktrace(self):
|
|
"""Print stacktrace"""
|
|
self.debug(traceback.format_exc())
|
|
|
|
def _space(self, display_title):
|
|
"""Add spaces to display title"""
|
|
display_title = str(display_title)
|
|
space_length = self.spacing - len(display_title)
|
|
if space_length > 0:
|
|
display_title += " " * space_length
|
|
return display_title
|
|
|
|
def ghost(self, text):
|
|
"""Print ghost"""
|
|
if not self.ignore_ghost:
|
|
try:
|
|
final_text = f"| {text}"
|
|
except UnicodeEncodeError:
|
|
text = text.encode("utf-8")
|
|
final_text = f"| {text}"
|
|
print(self._space(final_text), end="\r")
|
|
self.spacing = len(text) + 2
|
|
|
|
def exorcise(self):
|
|
"""Exorcise ghost"""
|
|
if not self.ignore_ghost:
|
|
print(self._space(" "), end="\r")
|
|
self.spacing = 0
|
|
|
|
def secret(self, text):
|
|
"""Add secret"""
|
|
if str(text) not in self.secrets and str(text):
|
|
self.secrets.add(str(text))
|
|
|
|
def insert_space(self, display_title, space_length=0):
|
|
"""Insert space"""
|
|
display_title = str(display_title)
|
|
if space_length == 0:
|
|
space_length = self.spacing - len(display_title)
|
|
if space_length > 0:
|
|
display_title = " " * space_length + display_title
|
|
return display_title
|
|
|
|
def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1):
|
|
"""Log"""
|
|
log_only = False
|
|
if self.spacing > 0:
|
|
self.exorcise()
|
|
if "\n" in msg:
|
|
for i, line in enumerate(msg.split("\n")):
|
|
self._log(level, line, args, exc_info=exc_info, extra=extra, stack_info=stack_info, stacklevel=stacklevel)
|
|
if i == 0:
|
|
self._formatter(log_only=True, space=True)
|
|
log_only = True
|
|
else:
|
|
for secret in sorted(self.secrets, reverse=True):
|
|
if secret in msg:
|
|
msg = msg.replace(secret, "(redacted)")
|
|
if "HTTPConnectionPool" in msg:
|
|
msg = re.sub("HTTPConnectionPool\\((.*?)\\)", "HTTPConnectionPool(redacted)", msg)
|
|
if "HTTPSConnectionPool" in msg:
|
|
msg = re.sub("HTTPSConnectionPool\\((.*?)\\)", "HTTPSConnectionPool(redacted)", msg)
|
|
try:
|
|
if not _srcfile:
|
|
raise ValueError
|
|
func, lno, func, sinfo = self.find_caller(stack_info, stacklevel)
|
|
except ValueError:
|
|
func, lno, func, sinfo = "(unknown file)", 0, "(unknown function)", None
|
|
if exc_info:
|
|
if isinstance(exc_info, BaseException):
|
|
exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
|
|
elif not isinstance(exc_info, tuple):
|
|
exc_info = sys.exc_info()
|
|
record = self._logger.makeRecord(self._logger.name, level, func, lno, msg, args, exc_info, func, extra, sinfo)
|
|
self._logger.handle(record)
|
|
if log_only:
|
|
self._formatter()
|
|
|
|
def find_caller(self, stack_info=False, stacklevel=1):
|
|
"""Find caller"""
|
|
frm = logging.currentframe()
|
|
if frm is not None:
|
|
frm = frm.f_back
|
|
orig_f = frm
|
|
while frm and stacklevel > 1:
|
|
frm = frm.f_back
|
|
stacklevel -= 1
|
|
if not frm:
|
|
frm = orig_f
|
|
rvf = "(unknown file)", 0, "(unknown function)", None
|
|
while hasattr(frm, "f_code"):
|
|
code = frm.f_code
|
|
filename = os.path.normcase(code.co_filename)
|
|
if filename == _srcfile:
|
|
frm = frm.f_back
|
|
continue
|
|
sinfo = None
|
|
if stack_info:
|
|
sio = io.StringIO()
|
|
sio.write("Stack (most recent call last):\n")
|
|
traceback.print_stack(frm, file=sio)
|
|
sinfo = sio.getvalue()
|
|
if sinfo[-1] == "\n":
|
|
sinfo = sinfo[:-1]
|
|
sio.close()
|
|
rvf = (code.co_filename, frm.f_lineno, code.co_name, sinfo)
|
|
break
|
|
return rvf
|