Newer
Older
pydwiki / log_manager / trace_log.py
import functools
import inspect
import logging
import threading

thread_local = threading.local()


def initialize_thread_local():
    """スレッドローカルの初期化をします。"""
    if not hasattr(thread_local, "depth"):
        thread_local.depth = 1


def trace_log(func):
    """トレースログを出力します。

    Arguments:
        func: 関数
    """

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        initialize_thread_local()

        logger = logging.getLogger(func.__module__)
        f_pathname = inspect.getfile(func)
        f_lineno = inspect.getsourcelines(func)[1]

        # 関数呼出し前ログ出力
        actual_args = args[1:] if args and hasattr(args[0], func.__name__) else args
        ext_depth = ">" * thread_local.depth
        logger.debug(
            f"{func.__name__}: args={actual_args}, {kwargs=}",
            extra={
                "ext_depth": ext_depth,
                "ext_levelname": "TRACE",
                "ext_pathname": f_pathname,
                "ext_lineno": f_lineno,
            },
        )

        thread_local.depth += 1
        try:
            # 関数実行
            result = func(*args, **kwargs)

            # 関数呼出し後ログ出力
            thread_local.depth -= 1
            ext_depth = "<" * thread_local.depth
            logger.debug(
                f"{func.__name__}: return={result}",
                extra={
                    "ext_depth": ext_depth,
                    "ext_levelname": "TRACE",
                    "ext_pathname": f_pathname,
                    "ext_lineno": f_lineno,
                },
            )
            return result
        except Exception as e:

            # エラー発生時ログ出力
            thread_local.depth -= 1
            ext_depth = "#" * thread_local.depth
            logger.error(
                f"{func.__name__}: {e=}",
                extra={
                    "ext_depth": ext_depth,
                    "ext_pathname": f_pathname,
                    "ext_lineno": f_lineno,
                },
            )
            raise

    return wrapper