Files
OpenCore-Legacy-Patcher/resources/logging_handler.py
2023-02-05 09:58:00 -07:00

98 lines
3.0 KiB
Python

import logging
import sys
import threading
from pathlib import Path
class InitializeLoggingSupport:
def __init__(self) -> None:
self.log_filename: str = f"OpenCore-Patcher.log"
self.log_filepath: Path = None
self.max_file_size: int = 1024 * 1024 * 10
self.file_size_redline: int = 1024 * 1024 * 9 # When to start cleaning log file
self._initialize_logging_path()
self._clean_log_file()
self._initialize_logging_configuration()
self._implement_custom_traceback_handler()
def _initialize_logging_path(self):
"""
Initialize logging framework storage path
"""
self.log_filepath = Path(f"~/Library/Logs/{self.log_filename}").expanduser()
if self.log_filepath.parent.exists():
return
# Likely in an installer environment, store in /Users/Shared
self.log_filepath = Path("/Users/Shared") / self.log_filename
def _clean_log_file(self):
"""
Determine if log file should be cleaned
We check if we're near the max file size, and if so, we clean the log file
"""
if not self.log_filepath.exists():
return
if self.log_filepath.stat().st_size < self.file_size_redline:
return
# Check if backup log file exists
backup_log_filepath = self.log_filepath.with_suffix(".old.log")
if backup_log_filepath.exists():
backup_log_filepath.unlink()
# Rename current log file to backup log file
self.log_filepath.rename(backup_log_filepath)
def _initialize_logging_configuration(self):
"""
Initialize logging framework configuration
StreamHandler's format is used to mimic the default behavior of print()
While FileHandler's format is for more in-depth logging
"""
logging.basicConfig(
level=logging.NOTSET,
format="%(asctime)s - %(filename)s (%(lineno)d): %(message)s",
handlers=[
logging.StreamHandler(),
logging.FileHandler(self.log_filepath),
],
)
logging.getLogger().setLevel(logging.INFO)
logging.getLogger().handlers[0].setFormatter(logging.Formatter("%(message)s"))
logging.getLogger().handlers[1].maxBytes = self.max_file_size
def _implement_custom_traceback_handler(self):
"""
Reroute traceback to logging module
"""
def custom_excepthook(type, value, tb):
"""
Reroute traceback in main thread to logging module
"""
logging.error("Uncaught exception in main thread", exc_info=(type, value, tb))
def custom_thread_excepthook(args):
"""
Reroute traceback in spawned thread to logging module
"""
logging.error("Uncaught exception in spawned thread", exc_info=(args))
sys.excepthook = custom_excepthook
threading.excepthook = custom_thread_excepthook