如何在Python中记录源文件名和行号

dig*_*igy 103 python logging

是否可以装饰/扩展python标准日志记录系统,以便在调用日志记录方法时,它还会记录文件和调用它的行号,或者调用它的方法?

Seb*_*Seb 190

当然,检查记录文档中的格式化程序.特别是lineno和pathname变量.

%(pathname)s 发出日志记录调用的源文件完整路径名(如果可用).

%(filename)s 路径名文件名部分.

%(模块)s 模块(文件名的名称部分).

%(funcName)s 包含日志记录调用的函数名称.

%(lineno)d 发出日志记录调用的源行号(如果可用).

看起来像这样:

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')
Run Code Online (Sandbox Code Playgroud)

  • 也被称为“实施得很差的骆驼案”。 (3认同)
  • 而且,是的,需要考虑变量中的**大写/小写混乱**。 (2认同)
  • 我使用 Logger.py 文件在文件之间共享记录器,当我使用此语法时,我获取记录器的文件名和行号,而不是用于调用记录器方法的文件和行。有什么办法解决吗? (2认同)

cod*_*ter 62

除了Seb非常有用的答案之外,这里还有一个方便的代码片段,它以合理的格式演示了记录器的使用情况:

#!/usr/bin/env python
import logging

logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")
Run Code Online (Sandbox Code Playgroud)

生成此输出:

2017-06-06:17:07:02,158 DEBUG    [log.py:11] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred
Run Code Online (Sandbox Code Playgroud)

  • 使用它来获取更多细节:formatter = logging.Formatter('%(asctime)s,%(levelname)-8s [%(filename)s:%(module)s:%(funcName)s:%(lineno)d] %(消息)S') (4认同)
  • @Marie.P。不要在评论中提出不同的问题。答案是日志级别。 (3认同)

ora*_*ips 7

以将调试日志发送到标准输出的方式构建上述内容:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)

logging.debug("I am sent to standard out.")
Run Code Online (Sandbox Code Playgroud)

将上述内容放入名为的文件中debug_logging_example.py会产生输出:

[debug_logging_example.py:14 -             <module>() ] I am sent to standard out.
Run Code Online (Sandbox Code Playgroud)

然后如果你想关闭日志注释掉root.setLevel(logging.DEBUG)

对于单个文件(例如类作业),我发现这是一种比使用print()语句更好的方法。它允许您在提交之前在一个地方关闭调试输出。


cha*_*ars 7

对于使用 PyCharm 或 Eclipse pydev 的开发人员,以下内容将在控制台日志输出中生成指向日志语句源的链接:

import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))


log.debug("hello logging linked to source")
Run Code Online (Sandbox Code Playgroud)

请参阅Eclipse 控制台中的 Pydev 源文件超链接以获取更长的讨论和历史记录。


Hos*_*mes 7

# your imports above ...


logging.basicConfig(
    format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in 
    function %(funcName)s] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)

# your classes and methods below ...
# An naive Sample of usage:
try:
    logger.info('Sample of info log')
    # your code here
except Exception as e:
    logger.error(e)
Run Code Online (Sandbox Code Playgroud)

与其他答案不同,这将记录文件的完整路径和可能发生错误的函数名称。如果您的项目包含多个模块和分布在这些模块中的多个同名文件,这将非常有用。