logging
许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪。在
python
中,我们不需要第三方的日志组件,python
为我们提供了简单易用、且功能强大的日志模块:logging
。
logging
模块支持将日志信息保存到不同的日志域中,如:保存到日志文件中;以邮件的形式发送日志信息;以http
get
或post
的方式提交日志到web
服务器;以windows
事件的形式记录等等。
logging官网 参考blog
简单的例子:
# 导入 logging 包
import logging
#为生成的日志做一些基本的配置
#比如下面配置了日志文件的绝对路径和日志等级
logging.basicConfig(filename=os.path.join(os.getcwd(),'test.log'),level=loggin.DEBUG)
logging.debug('this is a message!')
# 导入 logging 包
import logging
#为生成的日志做一些基本的配置
#比如下面配置了日志文件的绝对路径和日志等级
logging.basicConfig(filename=os.path.join(os.getcwd(),'test.log'),level=loggin.DEBUG)
logging.debug('this is a message!')
运行上面例子的代码,将会在程序的根目录下创建一个test.log
的文件,打开该文件,里面有一条日志记录:"DEBUG:root:this is a message"
4个主要的组件
- logger:日志类,应用程序往往通过调用它提供的
api
来记录日志。 - handler:对日志信息处理,可以将日志发送(保存)到不同的目标域中;
- filter:对日志信息进行过滤
- formatter:日志的格式化
日志级别
在记录日志是,日志信息都会关联一个级别("级别"本质上是一个非负整数)。系统默认提供了6个级别,它们分别是
:
级别 | 对应的值 |
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
可以给日志对象(logger instance)设置日志级别,低于该级别的日志信息将会被忽略;也可以给Hanlder
设置日志级别,对于低于该级别的日志信息,Handler
也会忽略
logging 模块中常用函数
logging.basicConfig([**kwargs]):
为日志模块配置基本信息。kwargs
支持如下几个关键字参数:
- filename:日志文件的保存路径。如果配置了这个参数,将自动创建一个文件句柄作为
handler
- filemode:日志文件的打开模式。默认值为'a',表示日志信息以追加的形式添加到日志文件中。如果设为'w',那么每次程序启动的时候都会创建一个新的日志文件;
- format:设置日志输出格式
- datefmt:定义日期格式
- level:设置日志的级别,对低于该级别的日志信息将会被忽略
- stream:设置特定的流用于初始化
StreamHandler
下面是一个简单的例子:
#!/usr/bin/env python
#coding:utf8
import logging
logging.basicConfig(filename=os.path.join(os.getcws(),'test.log'),level=logging.WARN,filemode='w',format='%(asctime)s - %(levelname)s: %(message)s')
logging.debug('debug') #被忽略
logging.info('info') #被忽略
logging.warning('warn') #记录
logging.error('error') #记录
#——————————————结果————————————————
#2017-11-10 23:23:14,661 - WARNING: warn
#2017-11-10 23:23:14,663 - ERROR: error
#!/usr/bin/env python
#coding:utf8
import logging
logging.basicConfig(filename=os.path.join(os.getcws(),'test.log'),level=logging.WARN,filemode='w',format='%(asctime)s - %(levelname)s: %(message)s')
logging.debug('debug') #被忽略
logging.info('info') #被忽略
logging.warning('warn') #记录
logging.error('error') #记录
#——————————————结果————————————————
#2017-11-10 23:23:14,661 - WARNING: warn
#2017-11-10 23:23:14,663 - ERROR: error
format 的格式
变量 | 解释 |
%(name)s | Logger的名字 |
%(levelno)s | 数字形式的日志级别 |
%(levelname)s | 文本形式的日志级别 |
%(pathname)s | 调用日志输出函数的模块的完整路径名,可能没有 |
%(filename)s | 调用日志输出函数的模块的文件名 |
%(module)s | 调用日志输出函数的模块名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 调用日志输出函数的语句所在的代码行 |
%(created)f | 当前时间,用UNIX标准的表示时间的浮点数表示 |
%(relativeCreated)d | 输出日志信息时的,自Logger创建以来的毫秒数 |
%(asctime)s | 字符串形式的当前时间。默认格式是“2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d | 线程ID。可能没有 |
%(threadName)s | 线程名。可能没有 |
%(process)d | 进程ID。可能没有 |
%(message)s | 用户输出的消息 |
logging.getLogger([name])
创建一个Logger
对象。日志记录的工作主要由Logger
对象来完成。在调用getLogger
时要提供Logger
的名称,logger
实例之间有层次关系,这些关系通过Logger
名称来实现。
#!/usr/bin/env python
#coding:utf8
import logging
logging.basicConfig(filename=os.path.join(os.getcwd(),'test1.log'),level=logging.WARN,filemode='w',format='%(asctime)s %(name)s %(levelname)s: %(message)s')
a1 = logging.getLogger("alpha")
b1 = logging.getLogger("beta")
c1 = logging.getLogger("gamma")
a1.warning("this is a test from a1!")
b1.warning("this is a test from b1!")
c1.warning("this is a test from c1!")
#!/usr/bin/env python
#coding:utf8
import logging
logging.basicConfig(filename=os.path.join(os.getcwd(),'test1.log'),level=logging.WARN,filemode='w',format='%(asctime)s %(name)s %(levelname)s: %(message)s')
a1 = logging.getLogger("alpha")
b1 = logging.getLogger("beta")
c1 = logging.getLogger("gamma")
a1.warning("this is a test from a1!")
b1.warning("this is a test from b1!")
c1.warning("this is a test from c1!")
输出结果:
2017-11-10 23:53:02,448 alpha WARNING: this is a test from a1!
2017-11-10 23:53:02,448 beta WARNING: this is a test from b1!
2017-11-10 23:53:02,448 gamma WARNING: this is a test from c1!
2017-11-10 23:53:02,448 alpha WARNING: this is a test from a1!
2017-11-10 23:53:02,448 beta WARNING: this is a test from b1!
2017-11-10 23:53:02,448 gamma WARNING: this is a test from c1!