我有各种模块,其中我大量使用Python日志记录。当我像在Python文档中一样将它们导入主模块并尝试运行它时,我没有从日志记录中获得任何输出。有谁知道发生了什么事?
在下面导入的public
模块导入的模块中调用日志记录(这段代码太大,无法在此处显示)。下面的代码段是运行整个程序并初始化日志记录的地方:
import logging
from bottle import run, debug
import public
logging.basicConfig(level=logging.DEBUG)
if __name__ == '__main__':
logging.info('Started')
debug(mode=True)
run(host='localhost', port = 8080, reloader=True)
logging.info('Finished')
答案 0 :(得分:7)
您的问题可能是由import public
语句调用logging.debug(...)
或类似内容引起的。然后发生的是:
import public
。作为副作用,这称为例如logging.debug
或类似的,会自动调用basicConfig
,这会向根记录器添加StreamHandler
,但不会更改级别。basicConfig
,但由于根记录器已经有一个处理程序,它什么都不做(如文档所述)。WARNING
,因此您的info
和debug
调用不会产生任何输出。您确实应该避免导入的副作用:例如,您对basicConfig
的调用应该在if __name__ == '__main__'
子句中。使用此public.py
:
import logging
def main():
logging.debug('Hello from public')
和main.py
:
import logging
from bottle import run, debug
import public
def main():
logging.basicConfig(level=logging.DEBUG)
logging.info('Started')
debug(mode=True)
public.main()
run(host='localhost', port = 8080, reloader=True)
logging.info('Finished')
if __name__ == '__main__':
main()
您将获得以下输出:
$ python main.py
INFO:root:Started
DEBUG:root:Hello from public
INFO:root:Started
DEBUG:root:Hello from public
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
^CINFO:root:Finished
$ Shutdown...
INFO:root:Finished
你会从中看到,Bottle实际上是在一个单独的进程中重新运行脚本,这可以解释消息的加倍。您可以使用显示进程ID的格式字符串来说明这一点:如果您使用
logging.basicConfig(level=logging.DEBUG,
format='%(process)s %(levelname)s %(message)s')
然后你得到像
这样的输出$ python main.py
13839 INFO Started
13839 DEBUG Hello from public
13840 INFO Started
13840 DEBUG Hello from public
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
^C13839 INFO Finished
$ Shutdown...
13840 INFO Finished
请注意,如果您向public.py
添加副作用生成语句,请执行以下操作:
logging.debug('Side-effect from public')
在模块级别,然后根本没有记录输出:
$ python main.py
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
^C$ Shutdown...
似乎证实了上述分析。
答案 1 :(得分:0)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.handlers
from logging.config import dictConfig
logger = logging.getLogger(__name__)
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
}
def configure_logging(logfile_path):
"""
Initialize logging defaults for Project.
:param logfile_path: logfile used to the logfile
:type logfile_path: string
This function does:
- Assign INFO and DEBUG level to logger file handler and console handler
"""
dictConfig(DEFAULT_LOGGING)
default_formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s():%(lineno)s] [PID:%(process)d TID:%(thread)d] %(message)s",
"%d/%m/%Y %H:%M:%S")
file_handler = logging.handlers.RotatingFileHandler(logfile_path, maxBytes=10485760,backupCount=300, encoding='utf-8')
file_handler.setLevel(logging.INFO)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(default_formatter)
console_handler.setFormatter(default_formatter)
logging.root.setLevel(logging.DEBUG)
logging.root.addHandler(file_handler)
logging.root.addHandler(console_handler)
[31/10/2015 22:00:33] [DEBUG] [yourmodulename] [yourfunction_name():9] [PID:61314 TID:140735248744448] this is logger infomation from hello module
我在我的项目中尝试了这段代码。在main中运行configure_loggint(logpath)。
你可以使用
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
logger = logging.getLogger(__name__)
def hello():
logger.debug("this is logger infomation from hello module")
答案 2 :(得分:-1)
编辑1:
以下是基于对OP代码的误解(来自评论)以及我的错误假设。因此,它无效。
您提供的代码至少有一个错误。 debug(mode=True)
错误有两个原因:
mode=True
是一项作业,而不是对平等的考验以下内容,剥离了任何辅助模块和代码,为我运行和记录:
import logging
mode = False
logging.basicConfig(level=logging.DEBUG)
logging.info('Started')
logging.debug(mode is True)
# ... other code ...
logging.info('Finished')
从命令行运行:
$ python my_logger.py
INFO:root:Started
DEBUG:root:False
INFO:root:Finished