Python+logging输出到屏幕将log日志写入文件


Posted in Python onNovember 11, 2020

日志

日志是跟踪软件运行时所发生的事件的一种方法。软件开发者在代码中调用日志函数,表明发生了特定的事件。事件由描述性消息描述,该描述性消息可以可选地包含可变数据(即,对于事件的每次出现都潜在地不同的数据)。事件还具有开发者归因于事件的重要性;重要性也可以称为级别或严重性。

logging提供了一组便利的函数,用来做简单的日志。它们是 debug()、 info()、 warning()、 error() 和 critical()。

logging函数根据它们用来跟踪的事件的级别或严重程度来命名。标准级别及其适用性描述如下(以严重程度递增排序):

级别 何时使用
DEBUG 详细信息,一般只在调试问题时使用。
INFO 证明事情按预期工作。
WARNING 某些没有预料到的事件的提示,或者在将来可能会出现的问题提示。例如:磁盘空间不足。但是软件还是会照常运行。
ERROR 由于更严重的问题,软件已不能执行一些功能了。
CRITICAL 严重错误,表明软件已不能继续运行了。

级别 数字值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

默认等级是WARNING,这意味着仅仅这个等级及以上的才会反馈信息,除非logging模块被用来做其它事情。

被跟踪的事件能以不同的方式被处理。最简单的处理方法就是把它们在控制台上打印出来。另一种常见的方法就是写入磁盘文件。

一、打印到控制台

import logging
logging.debug('debug 信息')
logging.warning('只有这个会输出。。。')
logging.info('info 信息')

由于默认设置的等级是warning,所有只有warning的信息会输出到控制台。

WARNING:root:只有这个会输出。。。 

利用logging.basicConfig()打印信息到控制台

import logging
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
   level=logging.DEBUG)
logging.debug('debug 信息')
logging.info('info 信息')
logging.warning('warning 信息')
logging.error('error 信息')
logging.critical('critial 信息')

由于在logging.basicConfig()中的level 的值设置为logging.DEBUG, 所有debug, info, warning, error, critical 的log都会打印到控制台。

日志级别: debug < info < warning < error < critical
logging.debug('debug级别,最低级别,一般开发人员用来打印一些调试信息')
logging.info('info级别,正常输出信息,一般用来打印一些正常的操作')
logging.warning('waring级别,一般用来打印警信息')
logging.error('error级别,一般用来打印一些错误信息')
logging.critical('critical 级别,一般用来打印一些致命的错误信息,等级最高')

所以如果设置level = logging.info()的话,debug 的信息则不会输出到控制台。

二、利用logging.basicConfig()保存log到文件

logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
   filename='new.log',
   filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
   #a是追加模式,默认如果不写的话,就是追加模式
   format=
   '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
   #日志格式
   )

如果在logging.basicConfig()设置filename 和filemode,则只会保存log到文件,不会输出到控制台。

三、既往屏幕输入,也往文件写入log

logging库采取了模块化的设计,提供了许多组件:记录器、处理器、过滤器和格式化器。

  • Logger 暴露了应用程序代码能直接使用的接口。
  • Handler将(记录器产生的)日志记录发送至合适的目的地。
  • Filter提供了更好的粒度控制,它可以决定输出哪些日志记录。
  • Formatter 指明了最终输出中日志记录的布局。

Loggers:

Logger 对象要做三件事情。首先,它们向应用代码暴露了许多方法,这样应用可以在运行时记录消息。其次,记录器对象通过严重程度(默认的过滤设施)或者过滤器对象来决定哪些日志消息需要记录下来。第三,记录器对象将相关的日志消息传递给所有感兴趣的日志处理器。

常用的记录器对象的方法分为两类:配置和发送消息。

这些是最常用的配置方法:

Logger.setLevel()指定logger将会处理的最低的安全等级日志信息, debug是最低的内置安全等级,critical是最高的内建安全等级。例如,如果严重程度为INFO,记录器将只处理INFO,WARNING,ERROR和CRITICAL消息,DEBUG消息被忽略。
Logger.addHandler()和Logger.removeHandler()从记录器对象中添加和删除处理程序对象。处理器详见Handlers。
Logger.addFilter()和Logger.removeFilter()从记录器对象添加和删除过滤器对象。

Handlers

处理程序对象负责将适当的日志消息(基于日志消息的严重性)分派到处理程序的指定目标。Logger 对象可以通过addHandler()方法增加零个或多个handler对象。举个例子,一个应用可以将所有的日志消息发送至日志文件,所有的错误级别(error)及以上的日志消息发送至标准输出,所有的严重级别(critical)日志消息发送至某个电子邮箱。在这个例子中需要三个独立的处理器,每一个负责将特定级别的消息发送至特定的位置。

常用的有4种:

1)    logging.StreamHandler -> 控制台输出

使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。

它的构造函数是:

StreamHandler([strm])

其中strm参数是一个文件对象。默认是sys.stderr

2)   logging.FileHandler  -> 文件输出

和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
FileHandler(filename[,mode])

filename是文件名,必须指定一个文件名。

mode是文件的打开方式。默认是'a',即添加到文件末尾。

3)   logging.handlers.RotatingFileHandler -> 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件

这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:

RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])

其中filename和mode两个参数和FileHandler一样。

maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。

backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

4)   logging.handlers.TimedRotatingFileHandler  -> 按照时间自动分割日志文件

这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:

TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])

其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。

interval是时间间隔。

when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:

S 秒

M 分

H 小时

D 天

W 每星期(interval==0时代表星期一)

midnight 每天凌晨

配置方法:

  • setLevel()方法和日志对象的一样,指明了将会分发日志的最低级别。为什么会有两个setLevel()方法?记录器的级别决定了消息是否要传递给处理器。每个处理器的级别决定了消息是否要分发。
  • setFormatter()为该处理器选择一个格式化器。
  • addFilter()和removeFilter()分别配置和取消配置处理程序上的过滤器对象。

Formatters

Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S,下面是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 用户输出的消息

需求:

输出log到控制台以及将日志写入log文件。

保存2种类型的log, all.log 保存debug, info, warning, critical 信息, error.log则只保存error信息,同时按照时间自动分割日志文件。

import logging
from logging import handlers

class Logger(object):
 level_relations = {
 'debug':logging.DEBUG,
 'info':logging.INFO,
 'warning':logging.WARNING,
 'error':logging.ERROR,
 'crit':logging.CRITICAL
 }#日志级别关系映射

 def __init__(self,filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
 self.logger = logging.getLogger(filename)
 format_str = logging.Formatter(fmt)#设置日志格式
 self.logger.setLevel(self.level_relations.get(level))#设置日志级别
 sh = logging.StreamHandler()#往屏幕上输出
 sh.setFormatter(format_str) #设置屏幕上显示的格式
 th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器
 #实例化TimedRotatingFileHandler
 #interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
 # S 秒
 # M 分
 # H 小时、
 # D 天、
 # W 每星期(interval==0时代表星期一)
 # midnight 每天凌晨
 th.setFormatter(format_str)#设置文件里写入的格式
 self.logger.addHandler(sh) #把对象加到logger里
 self.logger.addHandler(th)
if __name__ == '__main__':
 log = Logger('all.log',level='debug')
 log.logger.debug('debug')
 log.logger.info('info')
 log.logger.warning('警告')
 log.logger.error('报错')
 log.logger.critical('严重')
 Logger('error.log', level='error').logger.error('error')

屏幕上的结果如下:

2018-03-13 21:06:46,092 - D:/write_to_log.py[line:25] - DEBUG: debug
2018-03-13 21:06:46,092 - D:/write_to_log.py[line:26] - INFO: info
2018-03-13 21:06:46,092 - D:/write_to_log.py[line:27] - WARNING: 警告
2018-03-13 21:06:46,099 - D:/write_to_log.py[line:28] - ERROR: 报错
2018-03-13 21:06:46,099 - D:/write_to_log.py[line:29] - CRITICAL: 严重
2018-03-13 21:06:46,100 - D:/write_to_log.py[line:30] - ERROR: error

由于when=D,新生成的文件名上会带上时间,如下所示。

Python+logging输出到屏幕将log日志写入文件

总结

到此这篇关于Python+logging输出到屏幕将log日志写入文件的文章就介绍到这了,更多相关Python+logging输出屏幕内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python根据文件大小打log日志
Oct 09 Python
Python中断言Assertion的一些改进方案
Oct 27 Python
Python+matplotlib实现华丽的文本框演示代码
Jan 22 Python
Python pymongo模块用法示例
Mar 31 Python
提升Python程序性能的7个习惯
Apr 14 Python
django项目中使用手机号登录的实例代码
Aug 15 Python
解决Django中修改js css文件但浏览器无法及时与之改变的问题
Aug 31 Python
python异常处理和日志处理方式
Dec 24 Python
基于python实现模拟数据结构模型
Jun 12 Python
Python headers请求头如何实现快速添加
Nov 03 Python
用python对oracle进行简单性能测试
Dec 05 Python
Python必备技巧之字符数据操作详解
Mar 23 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
Nov 11 #Python
Django自定义YamlField实现过程解析
Nov 11 #Python
Python监听剪切板实现方法代码实例
Nov 11 #Python
如何通过python计算圆周率PI
Nov 11 #Python
python中turtle库的简单使用教程
Nov 11 #Python
python 怎样进行内存管理
Nov 10 #Python
python tqdm实现进度条的示例代码
Nov 10 #Python
You might like
php对图像的各种处理函数代码小结
2013/07/08 PHP
JavaScript 事件属性绑定带参数的函数
2009/03/13 Javascript
JavaScript 判断日期格式是否正确的实现代码
2011/07/04 Javascript
js网页中的(运行代码)功能实现思路
2013/02/04 Javascript
原生js实现淘宝首页点击按钮缓慢回到顶部效果
2014/04/06 Javascript
window resize和scroll事件的基本优化思路
2014/04/29 Javascript
jQuery文件上传插件Uploadify使用指南
2014/06/05 Javascript
jQuery中before()方法用法实例
2014/12/25 Javascript
纯JavaScript实现的分页插件实例
2015/07/14 Javascript
JavaScript驾驭网页-CSS与DOM
2016/03/24 Javascript
jQuery轻松实现无缝轮播效果
2017/03/22 jQuery
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
js实现图片轮播效果学习笔记
2017/07/26 Javascript
解决vue项目报错webpackJsonp is not defined问题
2018/03/14 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
Vue项目中最新用到的一些实用小技巧
2018/11/06 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
js对象数组和对象的使用实例详解
2019/08/27 Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
2020/03/06 Javascript
vue实现下拉菜单树
2020/10/22 Javascript
[45:16]完美世界DOTA2联赛循环赛 IO vs FTD BO2第二场 11.05
2020/11/06 DOTA
Python判断直线和矩形是否相交的方法
2015/07/14 Python
python爬虫的工作原理
2017/03/05 Python
解决python3 urllib中urlopen报错的问题
2017/03/25 Python
深入解析python中的实例方法、类方法和静态方法
2019/03/11 Python
python英语单词测试小程序代码实例
2019/09/09 Python
python实现简单坦克大战
2020/03/27 Python
蒂芙尼澳大利亚官方网站:Tiffany&Co. Australia
2017/08/27 全球购物
乌克兰最大的家用电器和电子产品连锁店:Eldorado
2019/10/02 全球购物
区三好学生主要事迹
2014/01/30 职场文书
光盘行动倡议书
2014/02/02 职场文书
《圆明园的毁灭》教学反思
2014/02/28 职场文书
支部书记四风对照材料
2014/08/28 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
Python基础数据类型tuple元组的概念与用法
2021/08/02 Python