python中logging的用法,python logging模块默认日志
本章内容:
一、测井模块介绍
二、日志模块的使用
第三,通过JSON或YMAL文件配置日志模块
=====================================================
一、测井模块介绍
Python的日志模块提供了一个通用的日志系统,可以方便的被第三方模块或者应用使用。该模块提供了不同的日志级别,可以用不同的方式记录日志,如文件、HTTP GET/POST、SMTP、Socket等。甚至可以自己实现特定的日志记录方法。
日志模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的级别、日志保存路径、日志文件回滚等。与印刷品相比,它有以下优点:
通过设置不同的日志级别,在发布版本中只输出重要信息,不显示大量的调试信息;Print将所有信息输出到标准输出,严重影响开发人员从标准输出查看其他数据;日志可以由开发人员决定在哪里以及如何输出信息;
Logger从不直接实例化,通常通过日志记录获得。Getlogger (name),日志记录的模块级函数。如果没有给出名称,则使用root。这个名字是由点划分(a.b.c)命名的。使用相同名称多次调用logging.getLogger()方法将返回相同的Logger对象。在这种命名方法中,后面的日志程序是前面日志程序的子日志程序,它们自动继承父日志程序的日志信息。正因为如此,不需要配置一个应用的所有记录器,只需要配置顶层记录器,然后子记录器根据需要继承。
伐木。记录器对象扮演着三重角色:
1.它向应用程序公开了几个方法,以便应用程序可以在运行时写日志。
2.Logger对象根据日志信息的严重程度或者根据filter对象(默认过滤功能)决定如何处理日志信息。
3.logger还负责将日志信息传输给相关的处理程序。
日志模块和log4j的机制是一样的,只是具体实现细节不同。提供了模块记录器、处理程序、过滤器和格式化程序。
记录器:提供日志接口供代码使用。Logger使用时间最长的操作有两种:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象。如果不指定名称,将返回根对象。使用相同的名称多次调用getLogger方法,以返回相同的Logger对象。处理程序:将日志记录发送到适当的目的地,如文件、套接字等。一个logger对象可以通过addHandler方法给多个处理程序加0,每个处理程序可以定义不同的日志级别,实现日志分级过滤显示。Filter:提供了一种优雅的方式来决定是否将日志记录发送给处理程序。格式:指定日志输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。类似于log4j,日志器、处理程序和日志消息的调用可以有特定的日志级别,只有当日志消息的级别大于日志器和处理程序的级别时。
二、日志模块的使用
2.1基本用途
配置基本日志设置,然后在控制台中输出日志。
导入日志记录
logging . basic config(level=logging。INFO,format= %(asctime)s-%(name)s-%(level name)s-%(message)s )
logger=logging . get logger(_ _ name _ _)
logger.info(“开始打印日志”)
logger.debug(做点什么)
logger.warning(某些东西可能会失败。)
当logger.info(Finish )运行时,控制台输出
1 2016-10-09 19:11:19,434 - __main__ - INFO -开始打印日志
2 2016-10-09 19:11:19,434 - __main__ -警告-某些东西可能会失败。
3 2016-10-09 19: 11: 19,434-_ _ main _ _-INFO-finish日志记录可以选择很多消息级别,比如:调试、信息、警告、错误、关键。通过给予logger或handler不同的级别,开发人员可以只将错误信息输出到特定的日志文件,或者只在调试过程中记录调试信息。
将记录器的级别更改为DEBUG,然后观察输出:
伐木。基本配置(级别=日志记录.DEBUG,format= %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s
从输出结果可以看到,输出了调试的日志记录
1 2016-10-09 19:12:08,289 - __main__ - INFO -开始打印日志
2 2016-10-09 19:12:08,289 - __main__ - DEBUG -做点什么
3 2016-10-09 19:12:08,289 - __main__ -警告-某些东西可能会失败。
4 2016-10-09 19:12:08,289-_ _ main _ _-INFO-finish文件名:指定日志文件名;
文件模式:和文件函数意义相同,指定日志文件的打开模式, w 或者a’;
格式:指定输出的格式和内容,格式可以输出很多有用的信息,
日期:指定时间格式,同时间。strftime();
级别:设置日志级别,默认为伐木。警告;
流:指定将日志的输出流,可以指定输出到系统标准错误,系统标准输出或者文件,默认输出到sys.stderr,当溪流和文件名同时指定时,流被忽略;
格式化程序定义了记录器记录的输出格式,定义了最终原木信息的内容格式,应用可以直接实例化泡沫物质类。信息格式字符串用%(字典关键字)s风格的字符串做替换。
属性名称
格式
说明
名字
%(名称)s
日志的名称
将时间日期以字符串格式表示
%(asctime)s
可读时间,默认格式2003-07-08 16:49:45,896,逗号之后是毫秒
文件名
%(文件名)s
文件名,路径名的一部分
路径名
%(路径名)s
文件的全路径名称
函数名
%(funcName)s
调用日志多对应的方法名
日志的级别
%(级别名)s
日志的等级
日志的级别
%(级别号)s
数字化的日志等级
当前行号
%(行号)d
被记录日志在源码中的行数
组件
%(模块)s
模块名
毫秒值
%(毫秒)d
时间中的毫秒部分
过程
%(流程)d
进程的身份
进程名
%(进程名)s
进程的名称
线
%(线程)d
线程的身份
线程名字
%(线程名)s
线程的名称
相对创造
%(相对创建的)d
日志被创建的相对时间,以毫秒为单位
2.2将日志写入文件
2.2.1将日志写入到文件
设置伐木,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到伐木工,然后将日志写入到指定的文件中。
导入日志记录
logger=日志记录。获取记录器(_ _ name _ _)
logger.setLevel(level=logging .信息)
处理程序=日志记录FileHandler(log.txt )
handler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s )
handler.setFormatter(格式化程序)
logger.addHandler(处理程序)
logger.info("开始打印日志")
logger.debug(做点什么)
logger.warning(某些东西可能会失败。)
logger.info(完成)
log.txt中日志数据为:
2018-01-25 13:02:09905-_ _ main _ _-INFO-开始打印日志
2017-01-25 13:02:09905-_ _ main _ _-警告-某些东西可能会失败。
2017-01-25 13:02:09905-_ _ main _ _-信息-完成
2.2.2将日志同时输出到屏幕和日志文件
记录器中添加StreamHandler,可以将日志输出到屏幕上。
导入日志记录
logger=日志记录。获取记录器(_ _ name _ _)
logger.setLevel(level=logging .信息)
处理程序=日志记录FileHandler(log.txt )
handler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s )
handler.setFormatter(格式化程序)
控制台=日志记录StreamHandler()
console.setLevel(日志记录。信息)
logger.addHandler(处理程序)
logger.addHandler(控制台)
logger.info("开始打印日志")
logger.debug(做点什么)
logger.warning(某些东西可能会失败。)
logger.info(完成)
可以在log.txt文件和控制台中看到:
2018-01-23 15:03:05,075 - __main__ - INFO -开始打印日志
2017-01-23 15:03:05,075 - __main__ -警告-某些东西可能会失败。
2017-01-23 15:03:05075-_ _ main _ _-信息-完成
可以发现,日志记录有一个日志处理的主对象,其他处理方式都是通过定义添加进去,日志记录中包含的处理者主要有如下几种:
处理者名称:位置;作用
StreamHandler:日志记录StreamHandler日志输出到流,可以是系统标准错误,系统标准输出或者文件
文件处理程序:日志记录文件处理程序日志输出到文件
BaseRotatingHandler:日志记录。经手人。BaseRotatingHandler基本的日志回滚方式
旋转处理程序:日志记录。经手人。旋转处理器;日志回滚方式,支持日志文件最大数量和日志文件回滚
timerotationhandler:日志记录。经手人。timerotationhandler日志回滚方式,在一定时间区域内回滚日志文件
套接字处理程序:日志记录。经手人。套接字处理程序;远程输出日志到传输控制协议套接字
数据报处理程序:日志记录。经手人。数据报处理器;远程输出日志到用户数据报协议(User Datagram Protocol)套接字
SMTPHandler:正在记录日志。经手人。SMTPHandler远程输出日志到邮件地址
系统日志处理程序:日志记录。经手人。系统日志处理程序;日志输出到系统记录
NTEventLogHandler:记录日志。经手人。NTEventLogHandler远程输出日志到Windows NT/2000/XP的事件日志
内存处理程序:日志记录。经手人。内存处理器;日志输出到内存中的指定缓冲器
HTTPHandler:日志记录。经手人。HTTPHandler通过得到或者发布远程输出到超文本传送协议服务器
2.2.3日志回滚
使用旋转文件处理器,可以实现日志回滚。
可以在工程目录中看到,备份的日志文件
导入日志记录
从日志记录.处理程序导入旋转文件处理器
logger=日志记录。获取记录器(_ _ name _ _)
logger.setLevel(level=logging .信息)
#定义一个旋转文件处理器,最多备份3个日志文件,每个日志文件最大1K
rHandler=旋转文件处理程序( log。txt ,maxBytes=1*1024,backupCount=3)
rHandler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s )
rHandler.setFormatter(格式化程序)
控制台=日志记录StreamHandler()
console.setLevel(日志记录。信息)
console.setFormatter(格式化程序)
logger.addHandler(rHandler)
logger.addHandler(控制台)
logger.info("开始打印日志")
logger.debug(做点什么)
logger.warning(某些东西可能会失败。)
logger.info(完成)
2.3 设置消息的等级
可以设置不同的日志等级,用于控制日志的输出。
#日志等级:使用范围
#致命:致命错误很少使用
关键:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
错误:发生错误时,如超正析象管(图片Orthicon)操作失败或者连接问题
警告:发生很重要的事件,但是并不是错误时,如用户登录密码错误
信息:处理请求或者状态变化等日常事务
调试:调试过程中使用调试等级,如算法中每个循环的中间状态
设置等级定义处理原木的最低等级,内建的级别为调试信息警告错误关键;
下图是级别对应的数值,当然你也可以调用系统方法,修改值,但是优先级是没法修改的。
2.4捕获追溯
计算机编程语言中的追溯模块被用于跟踪异常返回的信息,可以在记录中记录下追溯
导入日志记录
logger=日志记录。获取记录器(_ _ name _ _)
logger.setLevel(level=logging .信息)
处理程序=日志记录FileHandler(log.txt )
handler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s )
handler.setFormatter(格式化程序)
控制台=日志记录StreamHandler()
console.setLevel(日志记录。信息)
logger.addHandler(处理程序)
logger.addHandler(控制台)
logger.info("开始打印日志")
logger.debug(做点什么)
logger.warning(某些东西可能会失败。)
尝试:
打开( sklearn.txt , rb )
除了(系统退出,键盘中断):
上升
例外情况除外:
logger.error(无法从记录器.错误打开sklearn.txt ,exc_info=True)
logger.info(完成)
控制台和日志文件log.txt中输出
2018-01-23 15:04:24045-_ _ main _ _-INFO-开始打印日志
2018-01-23 15:04:24045-_ _ main _ _-警告-某些东西可能会失败。
2018-01-23 15:04:24046-_ _ main _ _-错误-无法从记录器打开sk学习。txt。错误
回溯(最近一次呼叫):
模块中文件" F:\PYTHON\xxxx\Logging.py "的第71行
打开( sklearn.txt , rb )
io error:[错误号2]没有这样的文件或目录:" sklearn.txt "
2018-01-23 15:04:24049-_ _ main _ _-信息-完成
也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info=True,_args),
将
logger.error(无法从记录器.错误打开sklearn.txt ,exc_info=True)
替换为,
logger.exception(无法从记录器.异常打开sk learn . txt’)
2.5多模块使用记录
主模块主模块。巴拉圭
导入日志记录
导入子模块
logger=日志记录。获取记录器(“主模块”)
logger.setLevel(level=logging .信息)
处理程序=日志记录FileHandler(log.txt )
handler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s )
handler.setFormatter(格式化程序)
控制台=日志记录StreamHandler()
console.setLevel(日志记录。信息)
console.setFormatter(格式化程序)
logger.addHandler(处理程序)
logger.addHandler(控制台)
logger.info(创建子模块的实例)
a=子模块。子模块类()
logger.info(调用子模块。子模块类。做点什么’)
doSomething()
logger.info(用子模块。子模块类。做某事完成)
logger.info(调用子模块。some _ function’)
subModule.som_function()
logger.info(用子模块. some_function完成)
子模块主模块。巴拉圭
导入日志记录
module _ logger=日志记录。获取记录器(主模块。子’)
班级子模块类别(对象):
def __init__(self):
自我。logger=日志记录。获取记录器(主模块。子模块’)
self.logger.info(在子模块类中创建实例)
定义做某事(自己):
self.logger.info(在子模块中执行某些操作)
a=[]
答。追加(1)
自我。伐木工。debug( list a= str(a))
self.logger.info(在子模块类中完成一些事情)
def som_function():
module_logger.info(调用函数some _ function’)
执行之后,在控制和日志文件log.txt中输出
2018-01-23 15:05:07,427 -主模块-信息-创建子模块的实例
2018-01-23 15:05:07,427-主模块。子模块-信息-在子模块类中创建实例
2018-01-23 15:05:07,427 -主模块-信息-调用子模块。子模块类。做某事
2018-01-23 15:05:07,427-主模块。子模块-信息-在子模块中执行操作
2018-01-23 15:05:07,427-主模块。子模块-信息-完成子模块类中的某些内容
2018-01-23 15:05:07,427-主模块-信息-子模块完成。子模块类。做某事
2018-01-23 15:05:07,427 -主模块-信息-调用子模块。一些功能
2018-01-23 15:05:07,427 - mainModule.sub - INFO -调用函数一些功能
2018-01-23 15:05:07,428 -主模块-信息-用子模块. some_function完成说明:
首先在主模块定义了记录器主模块,并对它进行了配置,就可以在解释器进程里面的其他地方通过getLogger(mainModule )得到的对象都是一样的,不需要重新配置,可以直接使用。定义的该记录器的子伐木工,都可以共享父记录器的定义和配置,所谓的父子记录器是通过命名来识别,任意以主模块开头的记录器都是它的子伐木工,例如mainModule.sub。
实际开发一个应用程序,首先可以通过记录配置文件编写好这个应用所对应的配置,可以生成一个根伐木工,如皮索纳普,然后在主函数中通过文件配置加载记录配置,接着在应用的其他地方、不同的模块中,可以使用根记录器的子伐木工,如皮索纳普。核心,皮索纳普。网络来进行日志,而不需要反复的定义和配置各个模块的伐木工。
三、通过数据或者YMAL文件配置记录模块
尽管可以在计算机编程语言代码中配置伐木,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。在Python 2.7及以后的版本中,可以从字典中加载记录配置,也就意味着可以通过数据或者YAML文件加载日志的配置。
3.1通过数据文件配置
数据配置文件
{
版本:1,
disable _ existing _ loggers :false,
格式化程序:{
简单:{
格式:%(asctime)s-%(名称)s-%(级别名称)s-%(消息)s
}
},
处理程序:{
控制台:{
类":"日志记录 StreamHandler ,
级别:调试,
格式化程序:简单,
stream:ext://sys.stdout
},
信息文件处理程序:
类“:”日志记录。经手人。旋转文件处理程序,
级别:信息,
格式化程序:简单,
文件名: info.log ,
maxBytes:10485760 ,
backupCount:20,
编码: utf8
},
错误文件处理程序:
类“:”日志记录。经手人。旋转文件处理程序,
级别:错误,
格式化程序:简单,
文件名:错误。日志,
maxBytes:10485760,
backupCount:20,
编码: utf8
}
},
"记录器":{
我的模块:
级别:错误,
处理程序:[信息文件处理程序],
传播:否
}
},
根:{
级别:信息,
处理程序:[控制台,信息文件处理程序,错误文件处理程序]
}
} 通过数据加载配置文件,然后通过logging.dictConfig配置记录
导入数据
导入日志记录。配置
导入操作系统
def setup _ logging(default _ path= logging。JSON ,default_level=logging .INFO,env_key=LOG_CFG ):
路径=默认路径
value=os.getenv(env_key,None)
如果值:
路径=值
如果os.path.exists(路径):
用打开(路径,“r”)作为女:
config=json.load(f)
伐木。配置。字典配置(配置)
否则:
伐木。基本配置(级别=默认级别)
定义函数():
logging.info("启动函数")
logging.info(执行函数)
伐木。信息("结束函数")
if __name__==__main__ :
setup _ logging(default _ path= logging。JSON’)
func() 3.2通过YMAL文件配置
通过YAML文件进行配置,比数据看起来更加简介明了
版本:1
禁用现有记录器:假
格式化程序:
简单:
格式:" %(asctime)s-%(名称)s-%(级别名称)s-%(消息)s "
经手人:
控制台:
类:日志记录。流处理器
级别:调试
格式化程序:简单
stream: ext://sys.stdout
信息文件处理程序:
类:日志记录。经手人。旋转文件处理程序
级别:信息
格式化程序:简单
文件名:信息.日志
最大字节数:10485760
备份计数:20
编码:utf8
错误文件处理程序:
类:日志记录。经手人。旋转文件处理程序
级别:错误
格式化程序:简单
文件名:错误.日志
最大字节数:10485760
备份计数:20
编码:utf8
记录器:
我的模块:
级别:错误
处理程序:[信息文件处理程序]
传播:否
根:
级别:信息
处理程序:[控制台,信息文件处理程序,错误文件处理程序]
通过YAML加载配置文件,然后通过logging.dictConfig配置记录
导入格式
导入日志记录。配置
导入操作系统
def setup _ logging(default _ path= logging。YAML ,默认级别=日志记录.INFO,env_key=LOG_CFG ):
路径=默认路径
value=os.getenv(env_key,None)
如果值:
路径=值
如果os.path.exists(路径):
用打开(路径,“r”)作为女:
config=yaml.load(f)
伐木。配置。字典配置(配置)
否则:
伐木。基本配置(级别=默认级别)
定义函数():
logging.info("启动函数")
logging.info(执行函数)
伐木。信息("结束函数")
if __name__==__main__ :
setup _ logging(default _ path= logging。YAML’)
函数()
四、参考
http://wjdadi-gmail-com.iteye.com/blog/1984354
http://python.jobbole.com/84092/
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。