@(杂庭忆技)[Python, logging]css
018.8.17html
import logging
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
# 输出
>>WARNING:root:warning
>>ERROR:root:error
默认状况下,logging将日志打印到屏幕上,按WARNING级别python
CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET服务器
设置日志等级之后,程序会自动过滤掉低于设置等级的日志信息。如:当等级为WARNING的时候,包括INFO及如下的日志信息会被过滤掉socket
利用logging模块中的basicConfig()
方法对日志作简单设置函数
import logging
# 设置日志的基本信息
logging.basicConfig(
level=logging.DEBUG, # 设置等级
filename = "test.log", # 设置输出文件
datefmt = "%Y/%m/%d %H:%M:%S", # 设置时间格式
format = "【%(asctime)s %(levelname)s】 %(lineno)d: %(message)s") # 设置输出格式
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
运行程序以后,当前目录下会生成一个test.log的文件,内容以下:
spa
可见输出格式是按照参数format指定样子生成的,而asctime,levelname,lineno指定的是须要输出哪些内容,这里依次是:时间,日志等级,出现行号,以及日志内容;若是不看小括号中的内容,其实%s,%d就是格式占位符线程
固然basicConfig()
的用法并无完,完整参数以下
- filename:输出文件路径
- filemode:按什么方式写入,w
表示清空内容以后写入,a
表示追加(默认追加模式)
- datefmt:设置时间格式
- style:当format传入了参数的时候,用style参数来指定占位符,能够是:%,{,$debug
import logging
# 不指定style时,默认%
logging.basicConfig(
level=logging.DEBUG,
datefmt = "%Y/%m/%d",
filename = "test.log",
format = "%(asctime)s %(message)s")
# 指定用符号 {
logging.basicConfig(
level=logging.DEBUG,
style = "{",
datefmt = "%Y/%m/%d",
filename = "test.log",
format = "{asctime} {message}")
# 指定用符号 $
logging.basicConfig(
level=logging.DEBUG,
style = "{",
datefmt = "%Y/%m/%d",
filename = "test.log",
format = "$asctime $message")
logging.debug("debug")
须要区分%、{、$占位时的不一样用法
- level:指定日志输出等级,只有大于等于这个等级的日志才会被输出
- stream:输出流,能够理解为输出到终端,当没有设置filename参数的时候,默认用StreamHandler;若是同时设置了stream和filename参数,stream的效果将被忽略
- handlers:指定日志处理时使用的Handler
- format:指定日志输出格式。经常使用参数以下:
1. asctime
:时间,默认按照2003-07-08 16:49:45,896格式
2. created
:也是时间,但以时间戳形式输出
3. filename
:当前执行文件的名字
4. funcName
:当前执行函数的名字
5. levelname
:日志级别的名称(WARNING、ERROR…)
6. lineno
:当前行号
7. message
:日志内容
8. module
:模块名
9. process
:进程号
10. processName
:进程名字
11. thread
:线程号
12. threadName
:线程名字
13. (更多相关参数可查看官方文档)3d
前面都是利用logging的basicConfig()
方法配置全局信息,咱们也能够经过getLogger()
方法返回一个logging.Logger类型的对象进行动态配置
import logging
# 实例一个logger对象,并对其添加文件名
logger = logging.getLogger(__name__)
# 设置日志级别
logger.setLevel(logging.WARNING)
# 构建日志格式
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
# 构建一个handler对象,并设置日志存放路径
handler = logging.FileHandler("test.log")
# 添加格式
handler.setFormatter(formatter)
# 添加handler
logger.addHandler(handler)
# 输出日志
logger.error("error")
咱们也能够构建多个handler来处理问题,好比将日志输出到文件的同时,也在终端输出
import logging
logger = logging.getLogger(__name__)
formatter = logging.Formatter("【%(asctime)s %(levelname)s】 %(message)s")
# 构建一个StreamHandler,用于输出到终端
strHandler = logging.StreamHandler()
strHandler.setLevel(logging.WARN) # 设置等级高于WARN以及WARN以上的(WARNING的简写)
strHandler.setFormatter(formatter)
logger.addHandler(strHandler)
# 构建一个FileHandler,用于输出到文件
fileHandler = logging.FileHandler("a-simmple.log")
fileHandler.setLevel(logging.INFO)# 设置等级高于INFO以及INFO以上的(WARNING的简写)
fileHandler.setFormatter(formatter)
logger.addHandler(fileHandler)
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
终端输出结果以下:
日志文件内容以下:
须要注意一点,在使用Handler(FileHandler,StreamHandler)对象的setLevel()方法的时候,若是须要设置的日志级别低于WARNING,则必须对logger对象使用setLevel(),根据具体状况选择logging.DEBUG或logging.INFO参数;固然也可使用logging.basicConfig()方法配置全局信息,也能起到一样的效果,以下:
import logging
logging.basicConfig(level = logging.DEBUG)
logger = logging.getLogger(__name__)
formatter = logging.Formatter("【%(asctime)s %(levelname)s】 %(message)s")
# 构建一个StreamHandler,用于输出到终端
...(省略)
除FileHandler,StreamHandler外,logging模块还提供了其余的Handler(如下都包含在logging.handlers模块中)
- BaseRotatingHandler:基本的日志回滚方式
- RotatingHandler:日志回滚方式,支持日志文件最大数量和日志文件回滚
- TimeRotatingHandler:日志回滚方式,在必定时间区域内回滚日志文件
- SocketHandler:远程输出日志到TCP/IP sockets
- DatagramHandler:远程输出日志到UDP sockets
- SMTPHandler:远程输出日志到邮件地址
- SysLogHandler:日志输出到syslog
- NTEventLogHandler:远程输出日志到Windows NT/2000/XP的事件日志
- MemoryHandler:日志输出到内存中的指定buffer
- HTTPHandler:经过GET或POST远程输出到HTTP服务器
利用logging模块,也能够详细记录Traceback,方便咱们查找问题
import logging
logger = logging.getLogger(__name__)
formatter = logging.Formatter(
"【%(asctime)s %(levelname)s】 %(message)s")
handler = logging.FileHandler("traceback.log")
handler.setFormatter(formatter)
logger.addHandler(handler)
try:
print(name)
except:
logger.error("error", exc_info=True)
运行结果以下:
能够经过配置父模块的方法,让子模块也受益
""" 父模块:mainLog.py """
import logging
import dupLog
logger = logging.getLogger("father") # 生成一个logger,并为其命名“father”
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler("my-log.txt")
formatter = logging.Formatter(
"【%(asctime)s %(levelname)s】 %(name)s: %(message)s ")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug("debug")
logger.info("info")
logger.warning("warning")
dupLog.record_log() # 调用子模块的日志记录功能
""" 子模块:dupLog.py """
import logging
logger = logging.getLogger("father.son") # 生成一个logger,并为其命名“father.son”
# 记录日志函数
def record_log():
logger.info("info")
logger.error("error")
输出结果:
"""
日志文件:my-log.txt
"""
【2018-08-18 07:47:21,775 DEBUG】 father: debug
【2018-08-18 07:47:21,776 INFO】 father: info
【2018-08-18 07:47:21,776 WARNING】 father: warning
【2018-08-18 07:47:21,776 INFO】 father.son: info
【2018-08-18 07:47:21,776 ERROR】 father.son: error
这里须要注意的是,子模块的logger名称必须以父模块的logger名称开头,如上所示的父father,子father.son
尽管设置配置信息的时候有logging.basciConfig()
,logging.getLogger().setLevel()
,logging.Formatter().setFormatter()
等方法,但语句始终镶嵌在代码里,不利于修改,也不利于阅读。所以logging模块提供了以加载配置文件的方式对日志功能进行配置
配置文件: log.conf
[loggers]
keys=root,log02
[handlers]
keys=hand01,hand02
[formatters]
keys=form01,form02
#################################################
[logger_root]
level=NOTSET
handlers=hand01
[logger_log02]
level=WARNING
handlers=hand02
propagate=1
qualname=log02
#################################################
[handler_hand01]
class=FileHandler
level=NOTSET
formatter=form01
args=("mine.log", "w")
[handler_hand02]
class=StreamHandler
level=WARNING
formatter=form02
args=(sys.stdout,)
#################################################
[formatter_form01]
format=[%(asctime)s %(levelname)s]-%(name)s-: %(message)s
datefmt=%Y/%m/%d %H:%M:%S
class=logging.Formatter
[formatter_form02]
format=%(asctime)s %(levelname)s: %(message)s
class=logging.Formatter
执行文件:test_log.py
import logging
import logging.config
logging.config.fileConfig("log.conf") # 加载配置文件
loggerRoot = logging.getLogger("root") # 获取root的配置
loggerLog02 = logging.getLogger("log02") # 获取log2的配置
loggerRoot.debug("debug")
loggerRoot.info("info")
loggerRoot.warning("warning")
loggerRoot.error("error")
loggerLog02.warning("warning")
loggerLog02.error("error")
运行结果以下:
- 终端
- mine.log
须要注意如下几点:
- 配置文件中,必须含有[loggers]
[handlers]
[formatters]
字段
- [loggers]
的keys中,必须含有root,并对其配置
- root会执行全部logger应该执行的debug(),info()...
等方法(因此上示mine.log文件中,有log02的日志信息)
- 更多详情可查看官方logging.config信息
文件配置还有另外一种方法,利用logging.config.dictConfig()
方法加载配置信息,配置文件格式以下:
具体使用方法可参看官方文档说明,也能够看崔庆才的一篇关于使用logging的文章