Good logging practice in Python
这篇介绍地不错,由浅入深
http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python
There are different handlers, you can also send records to you mailbox or even a to a remote server. You can also write your own custom logging handler. I’m not going to tell you details, please reference to official documents: Basic Tutorial, Advanced Tutorial and Logging Cookbook.
通过配置设置日志格式
import logging import logging.config logging.config.fileConfig('logging.conf') # create logger logger = logging.getLogger('simpleExample') # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
配置文件:
[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt=
Use _name_ as the logger name
根据调用的模块生成相关日志,日志中记录调用的模块名称
guosongdeMacBook-Air:20150114 guosong$ tree |grep -v pyc . ├── main.py ├── test │ ├── __init__.py │ ├── test.py └── test.test 1 directory, 6 files guosongdeMacBook-Air:20150114 guosong$ ./main.py guosongdeMacBook-Air:20150114 guosong$ ll total 16 -rwxr-xr-x 1 guosong staff 136B 1 14 11:48 main.py drwxr-xr-x 6 guosong staff 204B 1 14 11:51 test -rw-r--r-- 1 guosong staff 336B 1 14 11:53 test.test guosongdeMacBook-Air:20150114 guosong$ more test.test 2015-01-14 11:51:26,373 - test.test - INFO - Hello baby 2015-01-14 11:51:26,374 - test.test - INFO - Hello baby 2015-01-14 11:51:26,374 - test.test - INFO - Hello baby 2015-01-14 11:53:09,950 - test.test - INFO - Hello baby 2015-01-14 11:53:09,951 - test.test - INFO - Hello baby 2015-01-14 11:53:09,951 - test.test - INFO - Hello baby
http://blog.donews.com/limodou/archive/2005/02/16/278699.aspx
1 #!/usr/bin/env python 2 3 import logging 4 5 logfile="./log.file" 6 7 def initlog(): 8 logger=logging.getLogger() 9 hdlr=logging.FileHandler(logfile) 10 11 formatter=logging.Formatter('%(asctime)s %(levelname)s %(message)s') 12 hdlr.setFormatter(formatter) 13 logger.addHandler(hdlr) 14 logger.setLevel(logging.NOTSET) 15 16 return logger 17 18 def main(): 19 logger=initlog() 20 21 message="error" 22 logger.error(message) 23 24 message="info" 25 logger.info(message) 26 27 if __name__ == "__main__": 28 main()
第8行生成一个日志对象,可以带一个名字,可以缺省。
第9行生成一个Handler。logging支持许多Handler,象FileHandler, SocketHandler, SMTPHandler等,我由于要写文件就使用了FileHandler。logfile是一个全局变量,它就是一个文件名,如:’crawl.log’。
第11行生成一个格式器,用于规范日志的输出格式。如果没有这行代码,那么缺省的格式就是:”%(message)s”。也就是写日志时,信息是什么日志中就是什么,没有日期,没有信息级别等信息。logging支持许多种替换值,详细请看Formatter的文档说明。这里有三项:时间,信息级别,日志信息。
第12行将格式器设置到处理器上。
第13行将处理器加到日志对象上。
第14行设置日志信息输出的级别。logging提供多种级别的日志信息,如:NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL等。每个级别都对应一个数值。如果不执行此句,缺省为30(WARNING)。可以执行:logging.getLevelName(logger.getEffectiveLevel())来查看缺省的日志级别。日志对象对于不同的级别信息提供不同的函数进行输出,如:info(), error(), debug()等。当写入日志时,小于指定级别的信息将被忽略。因此为了输出想要的日志级别一定要设置好此参数。这里我设为NOTSET(值为0),也就是想输出所有信息。
getLogger两个方法:
1、getLogger(name=None)
Return a logger with the specified name, creating it if necessary.
If no name is specified, return the root logger.
2、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.
封装的日志:
#!/usr/bin/python26 #-*- coding:utf8 -*- import os import sys import logging import logging.handlers
#解决路径问题 os.chdir(sys.path[0]) class Logger(object): def __init__(self,log_dir,log_level,logger_name): if not os.path.exists(log_dir): os.mkdir(log_dir) self.__log_filename = log_dir + logger_name + ".log" self.__logger = logging.getLogger(logger_name) self.__logger.setLevel(log_level) handler = logging.handlers.RotatingFileHandler(self.__log_filename,maxBytes=10000,backupCount=0) formatter = logging.Formatter("%(asctime)s - [%(levelname)s] [%(name)s/%(filename)s %(lineno)d] - %(message)s") handler.setFormatter(formatter) self.__logger.addHandler(handler) def debug(self,message): self.__logger.debug(message) def error(self,message): self.__logger.error(message) def info(self,message): self.__logger.info(message) def main(): logger = Logger("../log/",logging.DEBUG,"test") logger.debug("Test") if __name__ == '__main__': main()