Python日志记录不输出任何内容

mur*_*d99 65 python logging

在我写的python脚本中,我正在尝试使用日志记录模块记录事件.我有以下代码来配置我的记录器:

ERROR_FORMAT = "%(levelname)s at %(asctime)s in %(funcName)s in %(filename) at line %(lineno)d: %(message)s"
DEBUG_FORMAT = "%(lineno)d in %(filename)s at %(asctime)s: %(message)s"
LOG_CONFIG = {'version':1,
              'formatters':{'error':{'format':ERROR_FORMAT},
                            'debug':{'format':DEBUG_FORMAT}},
              'handlers':{'console':{'class':'logging.StreamHandler',
                                     'formatter':'debug',
                                     'level':logging.DEBUG},
                          'file':{'class':'logging.FileHandler',
                                  'filename':'/usr/local/logs/DatabaseUpdate.log',
                                  'formatter':'error',
                                  'level':logging.ERROR}},
              'root':{'handlers':('console', 'file')}}
logging.config.dictConfig(LOG_CONFIG)
Run Code Online (Sandbox Code Playgroud)

当我尝试运行时logging.debug("Some string"),我没有输出到控制台,即使文档中的这个页面logging.debug应该让根记录器输出消息.为什么我的程序没有输出任何内容,我该如何解决?

Omr*_*rel 81

默认日志记录级别为警告.由于您没有更改级别,因此根记录器的级别仍然是警告.这意味着它将忽略任何低于警告级别的日志记录,包括调试日志记录.

这在教程中解释:

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything
Run Code Online (Sandbox Code Playgroud)

'info'行不打印任何内容,因为级别高于info.

要更改级别,只需在根记录器中设置它:

'root':{'handlers':('console', 'file'), 'level':'DEBUG'}
Run Code Online (Sandbox Code Playgroud)

换句话说,这是不够的定义与水平= DEBUG处理程序,实际的日志记录级别也必须DEBUG为了得到它的输出任何东西.

  • 请记住,导入“logging”后,您需要至少调用一次“logging.basicConfig()”。否则,您可能会对子记录器不会打印任何内容感到非常惊讶。根记录器上的记录函数会延迟调用它。 (13认同)
  • 在根记录器 `'root':{'handlers':('console', 'file'), 'level':'DEBUG'}` 中设置它是什么意思? (7认同)
  • 这不是文档(**不是教程!**)所说的!文档说只使用例如“logging.basicConfig(level=logging.DEBUG)”。然后应该打印 `logging.debug(...)` (它们还显示打印的内容)。嗯,我的情况也不是这样!至于 `'root':{'handlers':('console', 'file'), 'level':'DEBUG'}` ...这是如何以及在哪里使用的???如果没有它的应用示例,你就不能抛出这样的东西!我真的很想知道这样一个糟糕且无用的答案是如何得到这么多赞成票的!它应该被否决!(我没有,因为我不喜欢那样。) (4认同)
  • @Ben 根据文档,记录器被遍历以查找第一个具有 `level != NOTSET` 的父级或根(如果没有找到)。默认情况下,根目录具有“警告”级别。这是写在您链接到的部分(`Logger.setLevel`)中。 (3认同)
  • 文档说它的默认级别是NOTSET,它是一个0级,它应该输出所有内容......为什么这不是真的? (2认同)

eri*_*ric 60

对于这里想要一个超级简单答案的任何人:只需设置您想要显示的级别。在我所有脚本的顶部,我只放了:

import logging
logging.basicConfig(level = logging.INFO)
Run Code Online (Sandbox Code Playgroud)

然后显示该级别或更高级别的任何内容:

logging.info("Hi you just set your fleeb to level plumbus")
Run Code Online (Sandbox Code Playgroud)

它是五个级别的分层集,以便日志将显示在您设置的级别或更高的级别。因此,如果您想显示错误,可以使用logging.error("The plumbus is broken").

水平,在日益严重的依次是DEBUGINFOWARNINGERROR,和CRITICAL。默认设置是WARNING

这是一篇包含此信息的好文章,比我的答案表达得更好:https :
//www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3

  • 使用 `logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s: %(message)s')` 添加执行时间 (2认同)

Mos*_*sab 45

This problem wasted me so much time, so I'll just invest some more to write an answer and save yours

Problem

Cannot set logging level for custom loggers. (e.g: to DEBUG level)

What DOESN'T work

Setting logging level to the handler.

import logging

# Get logger
logger = logging.getLogger("my logger")

# Create a handler and set logging level for the handler
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.DEBUG) # <- Here things went wrong

# link handler to logger
logger.addHandler(c_handler)

# test
logger.debug('This is a debug message') # WILL NOT WORK
Run Code Online (Sandbox Code Playgroud)

SOLUTION

Set the logging level via the logger object (instead of the handler) Customlogger.setLevel(logging.DEBUG)

import logging

# Get logger
logger = logging.getLogger("my logger")

# Create a handler
c_handler = logging.StreamHandler()

# link handler to logger
logger.addHandler(c_handler)

# Set logging level to the logger
logger.setLevel(logging.DEBUG) # <-- THIS!

# test
logger.debug('This is a debug message') # WILL WORK
Run Code Online (Sandbox Code Playgroud)

  • 嗯...实际上为处理程序设置不同的日志级别怎么样?我希望控制台日志为 INFO,文件日志为 DEBUG (2认同)

Hub*_*iak 19

许多年后,Python记录器似乎仍然存在可用性问题。以下是一些示例说明:

import logging
# This sets the root logger to write to stdout (your console)
logging.basicConfig()

# By default the root logger is set to WARNING and all loggers you define
# inherit that value. Here we set the root logger to NOTSET. This logging
# level is automatically inherited by all existing and new sub-loggers
# that do not set a less verbose level.
logging.root.setLevel(logging.NOTSET)

# The following line sets the root logger level as well.
# It's equivalent to both previous statements combined:
logging.basicConfig(level=logging.NOTSET)


# You can either share the `logger` object between all your files or the
# name handle (here `my-app`) and call `logging.getLogger` with it.
# The result is the same.
handle = "my-app"
logger1 = logging.getLogger(handle)
logger2 = logging.getLogger(handle)
# logger1 and logger2 point to the same object:
# (logger1 is logger2) == True


# Convenient methods in order of verbosity from highest to lowest
logger.debug("this will get printed")
logger.info("this will get printed")
logger.warning("this will get printed")
logger.error("this will get printed")
logger.critical("this will get printed")


# In large applications where you would like more control over the logging,
# create sub-loggers from your main application logger.
component_logger = logger.getChild("component-a")
component_logger.info("this will get printed with the prefix `my-app.component-a`")

# If you wish to control the logging levels, you can set the level anywhere 
# in the hierarchy:
#
# - root
#   - my-app
#     - component-a
#

# Example for development:
logger.setLevel(logging.DEBUG)

# If that prints too much, enable debug printing only for your component:
component_logger.setLevel(logging.DEBUG)


# For production you rather want:
logger.setLevel(logging.WARNING)
Run Code Online (Sandbox Code Playgroud)

混乱的一个常见根源是初始化错误的根记录器。考虑一下:

import logging
log = logging.getLogger("myapp")
log.warning("woot")
logging.basicConfig()
log.warning("woot")
Run Code Online (Sandbox Code Playgroud)

输出:

woot
WARNING:myapp:woot
Run Code Online (Sandbox Code Playgroud)

根据您的运行时环境和日志记录级别,第一条日志行(在基本配置之前)可能不会在任何地方显示

  • 请注意,如果您使用 Matplotlib 并在日志记录导入之后但在其余代码(遵循 pep8)之前运行“import matplotlib.pyplot as plt”,则 Matplotlib 导入会中断日志记录配置,并且不会显示任何日志消息。 (2认同)

小智 8

也许试试这个?在我的情况下,删除所有处理程序后,似乎问题已解决。

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(filename='output.log', level=logging.INFO)
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一对我有用的东西。 (4认同)
  • 为什么这是必要的?什么处理程序带有 python 记录器,为什么他们从那里开始?或者也许问题是,为什么 basicConfig 不覆盖/替换它们? (3认同)

Cjo*_*Cjo 7

import logging
log = logging.getLogger()
log.setLevel(logging.DEBUG)

此代码会将默认日志记录级别设置为 DEBUG。

  • 不,不会的。 (5认同)
  • 我不确定为什么这个答案被标记下来,因为它有效。事实上,这是 AWS 记录 Lambda 中“logging”使用情况的方式 - https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html#python-logging-lib (2认同)