本文翻译自:logger configuration to log to file and print to stdout
I'm using Python's logging module to log some debug strings to a file which works pretty well. 我正在使用Python的日志记录模块将一些调试字符串记录到一个非常好的文件中。 Now in addition, I'd like to use this module to also print the strings out to stdout. 现在另外,我想使用这个模块也将字符串打印到stdout。 How do I do this? 我该怎么做呢? In order to log my strings to a file I use following code: 为了将我的字符串记录到文件,我使用以下代码:
import logging
import logging.handlers
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(
LOGFILE, maxBytes=(1048576*5), backupCount=7
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
and then call a logger function like 然后调用一个记录器函数
logger.debug("I am written to the file")
Thank you for some help here! 谢谢你的帮助!
#1楼
参考:https://stackoom.com/question/vciu/记录器配置以记录到文件并打印到stdout
#2楼
在设置任何其他处理程序或记录任何消息之前,使用stream=sys.stdout
作为参数运行basicConfig
,或者手动添加将消息发送到stdout到根记录器的StreamHandler
(或者任何其他所需的记录器) 。
#3楼
Just get a handle to the root logger and add the StreamHandler
. 只需获取根记录器的句柄并添加StreamHandler
。 The StreamHandler
writes to stderr. StreamHandler
写入stderr。 Not sure if you really need stdout over stderr, but this is what I use when I setup the Python logger and I also add the FileHandler
as well. 不确定你是否真的需要stdout而不是stderr,但这是我在设置Python记录器时使用的,我也添加了FileHandler
。 Then all my logs go to both places (which is what it sounds like you want). 然后我的所有日志都会转到这两个地方(这听起来像你想要的)。
import logging
logging.getLogger().addHandler(logging.StreamHandler())
If you want to output to stdout
instead of stderr
, you just need to specify it to the StreamHandler
constructor. 如果要输出到stdout
而不是stderr
,只需将其指定给StreamHandler
构造函数即可。
import sys
# ...
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
You could also add a Formatter
to it so all your log lines have a common header. 您还可以向其添加Formatter
,以便所有日志行都有一个公共标题。
ie: 即:
import logging
logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
rootLogger = logging.getLogger()
fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName))
fileHandler.setFormatter(logFormatter)
rootLogger.addHandler(fileHandler)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logFormatter)
rootLogger.addHandler(consoleHandler)
Prints to the format of: 打印到以下格式:
2012-12-05 16:58:26,618 [MainThread ] [INFO ] my message
#4楼
Adding a StreamHandler without arguments goes to stderr instead of stdout. 添加不带参数的StreamHandler会转到stderr而不是stdout。 If some other process has a dependency on the stdout dump (ie when writing an NRPE plugin), then make sure to specify stdout explicitly or you might run into some unexpected troubles. 如果某个其他进程依赖于stdout转储(即编写NRPE插件时),那么请确保明确指定stdout,否则可能会遇到一些意外问题。
Here's a quick example reusing the assumed values and LOGFILE from the question: 这是一个重用假设值和问题LOGFILE的快速示例:
import logging
from logging.handlers import RotatingFileHandler
from logging import handlers
import sys
log = logging.getLogger('')
log.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(format)
log.addHandler(ch)
fh = handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)
fh.setFormatter(format)
log.addHandler(fh)
#5楼
对于2.7,请尝试以下操作:
fh = logging.handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)
#6楼
logging.basicConfig()
can take a keyword argument handlers
since Python 3.3, which simplifies logging setup a lot, especially when setting up multiple handlers with the same formatter: logging.basicConfig()
可以从Python 3.3开始使用关键字参数handlers
,这简化了日志记录设置,特别是在使用相同的格式化程序设置多个处理程序时:
handlers
– If specified, this should be an iterable of already created handlers to add to the root logger.handlers
- 如果指定,这应该是已经创建的处理程序的可迭代,以添加到根记录程序。 Any handlers which don't already have a formatter set will be assigned the default formatter created in this function. 任何没有格式化程序集的处理程序都将被分配在此函数中创建的默认格式化程序。
The fairly long and verbose example code from the accepted answer therefore becomes just this: 因此,接受的答案中相当长且冗长的示例代码就变成了这样:
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s",
handlers=[
logging.FileHandler("{0}/{1}.log".format(logPath, fileName)),
logging.StreamHandler()
])
(Or with import sys
+ StreamHandler(sys.stdout)
per original question's requirements.) (或者根据原始问题的要求使用import sys
+ StreamHandler(sys.stdout)
。)
To get the logger, use 要获取记录器,请使用
logger = logging.getLogger()
Later in your script, use logger.info()
to output useful logging messages. 稍后在脚本中,使用logger.info()
输出有用的日志消息。