使用python logging的配置
简介
在python中使用logging模块,对log进行配置时,可以使用配置文件,而不用再python源码中进行配置。
这样方便更改logging的配置。
使用basicConfig进行配置
使用logging.basicConfig
来加载配置文件。
import logging
LOG_FILENAME="myapp.log"
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
logging.debug("this is a debugmsg!")
logging.info("this is a infomsg!")
logging.warn("this is a warn msg!")
logging.error("this is a error msg!")
logging.critical("this is a critical msg!")
使用config.fileConfig进行配置
使用logging.config.fileConfig
来加载配置文件。
import logging
import logging.config
# 加载配置文件
logging.config.fileConfig("logging2.conf")
#create logger
logger = logging.getLogger("simpleExample")
## getLogger中的参数如果在配置文件中找不到,则缺省使用root配置。
## log
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
可以看看fileConfig的具体定义:
def fileConfig(fname, defaults=None, disable_existing_loggers=True):
"""
Read the logging configuration from a ConfigParser-format file.
This can be called several times from an application, allowing an end user
the ability to select from various pre-canned configurations (if the
developer provides a mechanism to present the choices and load the chosen
configuration).
"""
import ConfigParser
cp = ConfigParser.ConfigParser(defaults)
if hasattr(fname, 'readline'):
cp.readfp(fname)
else:
cp.read(fname)
formatters = _create_formatters(cp)
# critical section
logging._acquireLock()
try:
logging._handlers.clear()
del logging._handlerList[:]
# Handlers add themselves to logging._handlers
handlers = _install_handlers(cp, formatters)
_install_loggers(cp, handlers, disable_existing_loggers)
finally:
logging._releaseLock()
配置文件
这里是示例的配置文件
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=fileHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=WARNING
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('testbyconfig.log','a+')
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
配置说明[loggers]
在loggers
中使用keys
定义几个logger,在code中使用。
[loggers]
keys=root,simpleExample
实践中需要注意的是,一般root强制定义。在code中getLogger(“loggerName”)如果不匹配loggerName时,会使用root。
具体的logger项目配置section,使用的section名以logger_
连接上具体的名称。如logger_root, logger_simpleExample。
这里是logging中的实现代码
#---------------------------------------------------------------------------
# Utility functions at module level.
# Basically delegate everything to the root logger.
#---------------------------------------------------------------------------
def getLogger(name=None):
"""
Return a logger with the specified name, creating it if necessary.
If no name is specified, return the root logger.
"""
if name:
return Logger.manager.getLogger(name)
else:
return root
# ... ...
class Manager(object):
"""
There is [under normal circumstances] just one Manager instance, which
holds the hierarchy of loggers.
"""
def __init__(self, rootnode):
"""
Initialize the manager with the root node of the logger hierarchy.
"""
self.root = rootnode
self.disable = 0
self.emittedNoHandlerWarning = 0
self.loggerDict = {}
self.loggerClass = None
def getLogger(self, name):
"""
Get a logger with the specified name (channel name), creating it
if it doesn't yet exist. This name is a dot-separated hierarchical
name, such as "a", "a.b", "a.b.c" or similar.
If a PlaceHolder existed for the specified name [i.e. the logger
didn't exist but a child of it did], replace it with the created
logger and fix up the parent/child references which pointed to the
placeholder to now point to the logger.
"""
rv = None
if not isinstance(name, basestring):
raise TypeError('A logger name must be string or Unicode')
if isinstance(name, unicode):
name = name.encode('utf-8')
_acquireLock()
try:
if name in self.loggerDict:
rv = self.loggerDict[name]
if isinstance(rv, PlaceHolder):
ph = rv
rv = (self.loggerClass or _loggerClass)(name)
rv.manager = self
self.loggerDict[name] = rv
self._fixupChildren(ph, rv)
self._fixupParents(rv)
else:
rv = (self.loggerClass or _loggerClass)(name)
rv.manager = self
self.loggerDict[name] = rv
self._fixupParents(rv)
finally:
_releaseLock()
return rv
#... ...
配置说明[logger_name]
在这里配置要使用的logger-handlers: 可以使用consoleHandler,fileHandler……。
配置说明[handler_handlerName]
在这里配置要使用logger的handlers的对应的配置.
如class、format、level及对应的args;args是传入class函数的参数。
如consoleHandler对应了
class=StreamHandler
level=WARNING
formatter=simpleFormatter
args=(sys.stdout,)
而 handler_fileHandler 对应的配置
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('testbyconfig.log','a+')
配置说明[formatter_simpleFormatter]
这里配置日志的formatter,如:
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s