Source code for crazyhusk.logs
"""Logging utilities for crazyhusk Unreal Engine object wrappers."""
# Standard Library
import calendar
import logging
import re
from datetime import datetime
from typing import Any
try:
# Standard Library
from typing import Literal # type:ignore
except ImportError:
# Third Party
from typing_extensions import Literal # type:ignore
# Regular expression for capturing data from UE4 logs
RE_UE4_LOG_LINE = re.compile(
r"\[(?P<timestamp>[\d.:\-]+)\]\[.+\](?P<module>\w+): ?((?P<level>(Display)|(Info)|(Warning)|(Error)): ?)?(?P<message>.+)$"
)
RE_UBT_LOG_LINE = re.compile(
r"^(?P<filename>.+?)\((?P<linenumber>\d+),?(?P<colnumber>\d+?)?\)\s?\:\s?(((?P<level>error|warning) \w+)|note)\:\s(?P<message>.+?)$"
)
UE4_LOG_MAP = {
"Info": logging.INFO,
"Display": logging.INFO,
"Warning": logging.WARNING,
"Error": logging.ERROR,
}
UBT_LOG_MAP = {"warning": logging.WARNING, "error": logging.ERROR}
[docs]class FilterEngineRun(logging.Filter):
"""Filter to enhance log records when using UnrealEngine.run()."""
def __init__(self, executable: str, *args: str) -> None:
"""Initialize the filter base args."""
logging.Filter.__init__(self)
self.executable: str = executable
self.cmd_args = args
[docs] def filter(self, record: Any) -> Literal[True]:
"""Enhance a loggable record's attributes."""
record.executable = self.executable
record.cmd_args = self.cmd_args
return True
[docs]class FilterUBTWarnings(logging.Filter):
"""Filter to enhance log records generated by UnrealBuildTool."""
[docs] def filter(self, record: Any) -> Literal[True]:
"""Filter LogRecords emitted from UnrealBuildTool which are warnings/errors/notes."""
captured = RE_UBT_LOG_LINE.match(record.msg)
if captured is not None:
record.levelno = UBT_LOG_MAP.get(captured.group("level"), logging.WARN)
record.levelname = logging.getLevelName(record.levelno)
record.filename = captured.group("filename")
record.linenumber = captured.group("linenumber")
record.colnumber = captured.group("colnumber")
record.sub_msg = captured.group("message")
return True
[docs]class FilterUE4Logs(logging.Filter):
"""Filter to enhance log records generated by UE4Editor/UE4Game."""
[docs] def filter(self, record: Any) -> Literal[True]:
"""Filter LogRecords emitted from UE4Editor/UE4Game."""
captured = RE_UE4_LOG_LINE.match(record.msg)
if captured is not None:
record.levelno = UE4_LOG_MAP.get(captured.group("level"), logging.INFO)
record.levelname = logging.getLevelName(record.levelno)
record.created = calendar.timegm(
datetime.strptime(
captured.group("timestamp"), "%Y.%m.%d-%H.%M.%S:%f"
).timetuple()
)
record.module = captured.group("module")
record.sub_msg = captured.group("message")
return True