python模块分析之logging日志(四)
前言
python的logging模块是用来设置日志的,是python的标准模块。
系列文章
日志记录的级别
DEBUG:优先级10,记录调试的详细信息,只在调试时开启;
INFO:优先级20,记录普通的消息,包括错误和警告等等;
WARNING:优先级30,记录相关的警告信息;
ERROR:优先级40,记录错误信息,程序崩溃;
CRITICAL:优先级50,记录错误信息;
如果不设置级别的话,默认为warning,系统记录设置的日志级别优先级以上的日志信息。
logging模块的主要结构
查看logging的源码,可知主要有四个类实现功能;
Loggers:提供应用程序直接使用的接口,如相关的配置设置;
Handlers:将Loggers产生的日志传到指定位置,设置日志保存的位置;
Filters:对输出日志进行过滤操作;
Formatters:控制日志的输出格式;
Formatters
Formatter对象定义了日志的输出格式,有多种可选参数。
%(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 用户输出的消息
# 定义一个输出格式的对象
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S', style='%')
# Formatter参数:
fmt:定义输出的日志信息的格式;
datefmt:定义时间信息的格式,默认为'%Y-%m-%d %H:%M:%S';
style:定义格式化输出的占位符,默认是%(name)格式,可选{}或$格式
Handlers日志处理器
日志处理器用来处理日志的具体流向,是输出到文件中还是到标准输出等,它通过设置Formatter控制输出格式,添加filters过滤日志;
- 常见的处理器有两种:
StreamHandler:用于向控制台打印日志;
FileHandler:用于向日志文件打印日志;
- 其它的处理器
RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚
TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件
SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP sockets
DatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP sockets
SMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址
SysLogHandler:logging.handlers.SysLogHandler;日志输出到syslog
NTEventLogHandler:logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志
MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定buffer
HTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器
from logging import Handler
handler = Handler() # 所有上述处理器的父类
print(handler.level) # 处理日志的等级
print(handler.name) # 处理日志的名字
print(handler.filters) # 处理器的日志过滤器
print(handler.formatter) # 日志的格式
handler.get_name()
handler.set_name('')
handler.createLock() # 创建线程锁
handler.acquire() # 获取线程锁
handler.release() # 释放线程锁
handler.setLevel('info') # 设置日志处理器的记录级别
handler.setFormatter(fmt='') # 设置日志的输出格式
handler.addFilter('') # 往处理器中添加过滤器
handler.removeFilter('') # 往处理器中移除过滤器
handler.emit('') # 日志记录的处理逻辑,由子类实现
Logger日志对象
Logger管理着所有记录日志的方法。
logger = getLogger(__name__) # 返回一个Logger实例
# logger = getLogger('root') # 以'root'为名字的日志对象在Logger对象中只有一个实例
# 如果是想调用以'root'为名字的日志对象输出日志,可以直接导入
from logging import error, debug, warning, info, fatal, critical
print(logger.root) # 获取根日志对象
print(logger.manager) # 获取manager
print(logger.name) # 日志对象的名字
print(logger.level) # 日志记录水平
print(logger.filters) # 日志过滤器列表
print(logger.handlers) # 日志处理器列表
print(logger.disabled)
logger.setLevel('info') # 设置日志记录水平
logger.info('this is %s', 'info', exc_info=1) # 输出日志信息,格式化输出
logger.warning('') # 记录warning信息
logger.error('') # 记录error信息
logger.exception('') # 等价于logger.error('', exc_info=1)
logger.debug('') # 记录debug信息
logger.critical('') # 记录critical信息
logger.log('info','') # 直接指定级别
logger.addHandler('') # 添加处理器
logger.removeHandler('') # 移除处理器
logger.hasHandlers() # 判断是否有处理器
logger的基本使用
import logging
import sys
def get_logger(appname):
# 获取logger实例,如果参数为空则返回root logger
logger = logging.getLogger(appname)
# 创建日志输出格式
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
# 设置文件处理器,加载处理格式
file_handler = logging.FileHandler("test.log") # 指定输出的文件路径
file_handler.setFormatter(formatter)
# 控制台日志
console_handler = logging.StreamHandler(sys.stdout)
console_handler.formatter = formatter
# 为logger添加的日志处理器
logger.addHandler(file_handler)
logger.addHandler(console_handler)
# 指定日志的最低输出级别,默认为WARN级别
logger.setLevel(logging.INFO)
if __name__ == "__main__":
logger = get_logger('test')
logger.debug('this is debug info')
logger.info('this is information')
logger.warn('this is warning message')
logger.error('this is error message')
logger.fatal('this is fatal message, it is same as logger.critical')
logger.critical('this is critical message')
logger日志记录的逻辑调用过程
记录日志通过调用logger.debug等方法;
首先判断本条记录的日志级别是否大于设置的级别,如果不是,直接pass,不再执行;
将日志信息当做参数创建一个LogRecord日志记录对象;
将LogRecord对象经过logger过滤器过滤,如果被过滤掉则pass;
日志记录对象被Handler处理器的过滤器过滤;
判断本条记录的日志级别是否大于Handler处理器设置的级别,如果不是,直接pass,不再执行,最后调用处理器的emit方法处理日志记录;
配置logger
- 通过代码进行完整配置,主要是通过getLogger方法实现,但不好修改;
- 通过basicConfig方法实现,这种方式快速但不够层次分明;
- 通过logging.config.fileConfig(filepath),文件配置。
- 通过dictConfig的字典方式配置,这是py3.2版本引入的新的配置方法;
使用文件方式配置
# logging.conf
[loggers] # 定义日志的对象名称是什么,注意必须定义root,否则报错。
keys=root,main
[handlers] # 定义处理器的名称是什么,可以有多个,用逗号隔开
keys=consoleHandler
[formatters] # 定义输出格式对象的名称,可以有多个,用逗号隔开
keys=simpleFormatter
[logger_root] # 配置root对象的日志记录级别和使用的处理器
level=INFO
handlers=consoleHandler
[logger_main] # 配置main对象的日志记录级别和使用的处理器,qualname值得就是日志对象的名字
level=INFO
handlers=consoleHandler
qualname=main
propagate=0 # logger对象把日志记录传递给所有相关的handler的时候,会(逐级向上)寻找这个logger和它所有的父logger的全部handler,propagate=1表示会继续向上搜寻;propagate=0表示停止搜寻,这个参数涉及重复打印的坑。
[handler_consoleHandler] # 配置处理器consoleHandler
class=StreamHandler
level=WARNING
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter] # 配置输出格式过滤器simpleFormatter
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
- 注意:可以看到logger和Handler都可以设置日志级别,日志输出是取最高级别。
使用字典形式配置
字典形式配置功能更加强大,也更加灵活。通过dictConfig函数,我们可以将其他格式的配置文件先转化成字典,如json、YAML等。
import yaml
from logging.config import dictConfig
import os
filename = os.path.dirname(os.path.abspath(__file__))
with open(filename + '\logging.yml', 'r') as f:
log = yaml.load(f.read())
dictConfig(log)
# logging.yaml
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
console_err:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stderr
loggers:
simpleExample:
level: DEBUG
handlers: [console]
propagate: no
root:
level: DEBUG
handlers: [console_err]
一些细节
- logger的继承
logging.getLogger(appname),同一个appname获取到的logger对象是同一个,同时appname.name命名的logger继承了appname的所有的属性,可以不用重新配置logger。
- 输出错误信息的方法
try:
raise
except:
logger.error('this is error message',exc_info = True)
# 或
logger.exception("Failed to open sklearn.txt from logger.exception")
# 设置exc_info为True后,会自动将错误的信息也发送到日志中;
# 直接使用exception实现一样的功能。
监听logger配置更改
- logging.config.listen(port)函数可以让应用程序在一个socket上监听新的配置信息,达到在运行时改变配置,而不用重启应用程序的目的。
import logging.config
import logging
import time
logging.config.fileConfig("logging.conf")
logger = logging.getLogger("test.listen")
t = logging.config.listen(9999)
t.setDaemon(True)
t.start() # 启动监听服务器
参考
python模块分析之logging日志(四)的更多相关文章
- 【转】python模块分析之logging日志(四)
[转]python模块分析之logging日志(四) python的logging模块是用来写日志的,是python的标准模块. 系列文章 python模块分析之random(一) python模块分 ...
- Python模块04/包/logging日志
Python模块04/包/logging日志 目录 Python模块04/包/logging日志 内容大纲 1.包 2.logging日志 3.今日总结 内容大纲 1.包 2.logging日志 1. ...
- Python模块学习:logging 日志记录
原文出处: DarkBull 许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪.在.NET平台中,有非常著名的第三方开源日志组件log4net ...
- 【转】python模块分析之collections(六)
[转]python模块分析之collections(六) collections是Python内建的一个集合模块,提供了许多有用的集合类. 系列文章 python模块分析之random(一) pyth ...
- 【转】python模块分析之unittest测试(五)
[转]python模块分析之unittest测试(五) 系列文章 python模块分析之random(一) python模块分析之hashlib加密(二) python模块分析之typing(三) p ...
- 【转】python模块分析之typing(三)
[转]python模块分析之typing(三) 前言:很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度 ...
- python模块分析之typing(三)
前言:很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,加上Python本身就是一门弱类型的语言,这种 ...
- 【转】python模块分析之hashlib加密(二)
[转]python模块分析之hashlib加密(二) hashlib模块是用来对字符串进行hash加密的模块,明文与密文是一一对应不变的关系:用于注册.登录时用户名.密码等加密使用.一.函数分析:1. ...
- python 自动化之路 logging日志模块
logging 日志模块 http://python.usyiyi.cn/python_278/library/logging.html 中文官方http://blog.csdn.net/zyz511 ...
随机推荐
- MT【52】空间法向量理解直线条数
[从最简单的做起.]--波利亚 评:线面角转化成线与线的角,这道题还有类似的这类题是学生的难点.
- 自学Linux Shell3.5-目录处理命令mkdir rmdir
点击返回 自学Linux命令行与Shell脚本之路 3.5-目录处理命令mkdir rmdir 1. mkdir命令 创建一个或多个新的目录. mkdir 命令创建由 Directory 参数指定的一 ...
- 自学Aruba1.4-Aruba体系结构-产品线
点击返回:自学Aruba之路 1. Aruba产品线 IP switches: 1500.2500.3500 Controllers:7200 .70x0 Series.7005 Meridian:基 ...
- idea tomcat上传图片,无法显示的问题解决
真是浪费时间啊,之前eclipse下的tomcat 去webapps下找就行了,这倒好,idea下根本没有. 我上传的目录建在项目中的static中了,upload文件夹,上传到这里肯定是找不到了的: ...
- 警告: No data sources are configured to run this SQL and provide advanced code assistance. Disable this inspection via problem menu (Alt+Enter). more... (Ctrl+F1) SQL dialect is not configured. Postgr
python3出现问题: 警告: No data sources are configured to run this SQL and provide advanced code assistance ...
- (大数)Computer Transformation hdu1041
Computer Transformation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
- ADO.NET连接字符串大全
说明ADO.NET连接字符串:SQL Server,SQL Server 2005,ACCESS,Oracle,MySQL,Interbase,IBM DB2,Sybase,Informix,Ingr ...
- InfluxDB1.2.4部署(centos6.8)
InfluxDB介绍 官网:https://www.influxdata.com/ 文档:https://docs.influxdata.com/influxdb/v1.2/introduction/ ...
- mysql 缓存机制
了解mysql缓存吗(顺丰) mysql缓存机制就是缓存sql 文本及缓存结果,用KV形式保存再服务器内存中,如果运行相同的sql,服务器直接从缓存中去获取结果,不需要在再去解析.优化.执行sql. ...
- NTT模板
NTT(快速数论变换)用到的各种素数及原根: https://blog.csdn.net/hnust_xx/article/details/76572828 NTT多项式乘法模板 #include&l ...