可用于日志格式的调用堆栈

发布于 2024-10-22 06:07:12 字数 852 浏览 5 评论 0原文

因此,我有一个返回调用堆栈的简单字符串的方法。


def call_stack():
    if "inspect" not in globals().keys():
        import inspect
    stack = [frame[3] for frame in inspect.stack() if frame[3] not in [inspect.stack()[0][3],"<module>"]]
    s = ""
    for method in stack: 
        if len(s) > 0:
            s += "." 
        s += method
    return s

def modify_logger(logger):
    logger.args["call_stack"] = call_stack()

是否有可能创建这种行为?


import logging
logging.basicConfig(level=logging.DEBUG, format="%(call_stack)s -- %(levelname)s:  %(message)s")

def bar():
    logging.debug("test")

def foo():
    bar()

def monkey():
    foo()

# modify root logger.
modify_logger(logging.getLogger())

# write to the log.
monkey()

这会产生以下条目:


monkey.foo.bar -- DEBUG: test

So, I have a method that returns a simple string of the call-stack.


def call_stack():
    if "inspect" not in globals().keys():
        import inspect
    stack = [frame[3] for frame in inspect.stack() if frame[3] not in [inspect.stack()[0][3],"<module>"]]
    s = ""
    for method in stack: 
        if len(s) > 0:
            s += "." 
        s += method
    return s

def modify_logger(logger):
    logger.args["call_stack"] = call_stack()

Is it possible to create this behavior?


import logging
logging.basicConfig(level=logging.DEBUG, format="%(call_stack)s -- %(levelname)s:  %(message)s")

def bar():
    logging.debug("test")

def foo():
    bar()

def monkey():
    foo()

# modify root logger.
modify_logger(logging.getLogger())

# write to the log.
monkey()

Which results in the following entry:


monkey.foo.bar -- DEBUG: test

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无言温柔 2024-10-29 06:07:12

也许最简单的方法就是定义一个自定义的 debug 函数

import logging

def call_stack():
    if "inspect" not in globals().keys():
        import inspect
    stack = [frame[3] for frame in inspect.stack()
             if frame[3] not in [inspect.stack()[0][3],"<module>"]]
    s='.'.join(reversed(stack))
    return s

def debug(message):
    logging.debug('{s} -- DEBUG: {m}'.format(
        s=call_stack()[:-len('debug.')],m=message))

logging.basicConfig(level=logging.DEBUG, format="%(message)s")

def bar():
    debug("test")

def foo():
    bar()

def monkey():
    foo()

monkey()

monkey.foo.bar -- DEBUG: test

Perhaps the easiest way is just to define a custom debug function:

import logging

def call_stack():
    if "inspect" not in globals().keys():
        import inspect
    stack = [frame[3] for frame in inspect.stack()
             if frame[3] not in [inspect.stack()[0][3],"<module>"]]
    s='.'.join(reversed(stack))
    return s

def debug(message):
    logging.debug('{s} -- DEBUG: {m}'.format(
        s=call_stack()[:-len('debug.')],m=message))

logging.basicConfig(level=logging.DEBUG, format="%(message)s")

def bar():
    debug("test")

def foo():
    bar()

def monkey():
    foo()

monkey()

yields

monkey.foo.bar -- DEBUG: test
心不设防 2024-10-29 06:07:12

昨天对这个模式进行了相当多的研究之后,我意识到我想要的对于 Python 语言来说是不合理的。毕竟,它是一种解释性语言,这意味着总有一个文件存在于已知路径和可以引用的行号上。在 C#、Java、C 或 C++ 等编译语言中,这是有意义的,因为您拥有命名空间、对象和方法,但没有文件/路径和行号的好处。

故事的寓意

当人们告诉您您的要求没有意义时,不要只是忽略他们。在积极寻找在您的特定用例或上下文中可能没有意义的问题的答案之前,请花一些时间仔细检查您最初的请求以及您的观点。

After having researched this pattern quite a bit yesterday, I realized that what I wanted wasn't reasonable for the Python language. Its an interpreted language, after all, which means that there is always a file that exists on a known path and a line number which can be referenced. It would make sense, in a compiled language like C#, Java, C, or C++ because you have namespaces, objects, and methods without the benefit of having a file/path and line number.

Moral of the story

When people tell you that what you're asking for doesn't make sense, don't just write them off. Take a few moments and scrutinize your original request along with your perspective before vigorously pursuing an answer to a question that might not make sense in your specific use-case or context.

梦在深巷 2024-10-29 06:07:12

我尝试将你的解决方案与另一个解决方案混合,它给了我我正在寻找的结果。

    import logging
    DEBUG = True
    TRACE = True

    #-----------------------------------------------------------------------------
    # TRACE BACK
    #-----------------------------------------------------------------------------
    class ContextFilter(logging.Filter):
        def filter(self, record):
            import traceback
            if "inspect" not in globals().keys():
                import inspect
            stack = [frame[3] for frame in inspect.stack()
            if frame[3] not in [inspect.stack()[0][3],"<module>"]]
            record.stack ='.'.join(reversed(stack))
            return True

    #-----------------------------------------------------------------------        ---------
    # LOGGER
    #--------------------------------------------------------------------------------
    logger = logging.getLogger()
    if TRACE:
        logger.addFilter(ContextFilter())

    if DEBUG:
        logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(stack)s\n{%(pathname)s:%(lineno)d} - %(asctime)s - %(levelname)s - %(message)s')

        fh = logging.FileHandler('log_filename.txt')
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(formatter)
        logger.addHandler(fh)

        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(formatter)
        logger.addHandler(ch)

    else:
        logger.setLevel(logging.NOTSET)
        print 'NOT IN DEBUG MODE: Logging.NOTSET'

I tried your solution mixed with another, it gave me the results I was looking for.

    import logging
    DEBUG = True
    TRACE = True

    #-----------------------------------------------------------------------------
    # TRACE BACK
    #-----------------------------------------------------------------------------
    class ContextFilter(logging.Filter):
        def filter(self, record):
            import traceback
            if "inspect" not in globals().keys():
                import inspect
            stack = [frame[3] for frame in inspect.stack()
            if frame[3] not in [inspect.stack()[0][3],"<module>"]]
            record.stack ='.'.join(reversed(stack))
            return True

    #-----------------------------------------------------------------------        ---------
    # LOGGER
    #--------------------------------------------------------------------------------
    logger = logging.getLogger()
    if TRACE:
        logger.addFilter(ContextFilter())

    if DEBUG:
        logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(stack)s\n{%(pathname)s:%(lineno)d} - %(asctime)s - %(levelname)s - %(message)s')

        fh = logging.FileHandler('log_filename.txt')
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(formatter)
        logger.addHandler(fh)

        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(formatter)
        logger.addHandler(ch)

    else:
        logger.setLevel(logging.NOTSET)
        print 'NOT IN DEBUG MODE: Logging.NOTSET'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文