python脚本攻略之log日志
1 logging模块简介
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
- 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
- print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出
- 日志等级:
log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
ALL 最低等级的,用于打开所有日志记录。
TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。
DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。
ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
OFF 最高等级的,用于关闭所有日志记录。
如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
log4j默认的优先级为ERROR或者WARN(实际上是ERROR)
2 logging模块使用
2.1 基本使用
1.配置logging基本的设置,然后在控制台输出日志。
import logging
#初始化
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#生成日志句柄
logger = logging.getLogger("wqbin") logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
2016-10-09 19:11:19,434 - wqbin - INFO - Start print log
2016-10-09 19:11:19,434 - wqbin - WARNING - Something maybe fail.
2016-10-09 19:11:19,434 - wqbin - INFO - Finish
2.
2.1设置等级和格式有很多处。但是有优先等级。
2.2logger中添加StreamHandler,可以将日志输出到屏幕上
2.3logger中添加FileHandler,可以将日志输出到文件里
import logging
import time
import logging.handlers
#初始化设置
logging.basicConfig(level = logging.INFO,format='%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
#创建
logger = logging.getLogger("wqbin")
logger.setLevel(logging.INFO) #创建handler
handler1=logging.FileHandler("base-log.log")
handler1.setLevel(logging.INFO)
formatter=logging.Formatter('%(asctime)s|%(name)-12s+ %(levelname)-8s++%(message)s')
handler1.setFormatter(formatter) handler2=logging.StreamHandler()
handler2.setLevel(logging.ERROR) logger.addHandler(handler1)
logger.addHandler(handler2) logger.info("info")
logger.warning("warning")
logger.error("error")
print('finish')
console:
2019-03-12 21:41:22,215|wqbin : INFO info
finish
2019-03-12 21:41:22,215|wqbin : WARNING warning
error
2019-03-12 21:41:22,215|wqbin : ERROR error
日志等级 初始化设置等级最高
格式 谁离得近谁最高
3.logging.basicConfig参数讲解
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
filename Specifies that a FileHandler be created, using the specified
filename, rather than a StreamHandler.
filemode Specifies the mode to open the file, if filename is specified
(if filemode is unspecified, it defaults to 'a').
format Use the specified format string for the handler.
datefmt Use the specified date/time format.
style If a format string is specified, use this to specify the
type of format string (possible values '%', '{', '$', for
%-formatting, :meth:`str.format` and :class:`string.Template`
- defaults to '%').
level Set the root logger level to the specified level.
stream Use the specified stream to initialize the StreamHandler. Note
that this argument is incompatible with 'filename' - if both
are present, 'stream' is ignored.
handlers If specified, this should be an iterable of already created
handlers, which will be added to the root handler. Any handler
in the list which does not have a formatter assigned will be
assigned the formatter created in this function.
4.fomat参数讲解
%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息
3 logging模块高级用法
3.1日志回滚
什么是日志回滚:
将日志信息输出到一个单一的文件中,随着应用程序的持续使用,该日志文件会越来越庞大,进而影响系统的性能。因此,有必要对日志文件按某种条件进行切分,要切分日志文件。
分割日志的触发条件:大小、日期,或者大小加上日期。
说是切分,实际上是,当一个日志文件达到触发条件后,对日志文件进行重命名,之后再新建原来名称的日志文件(此时就是空文件了),新产生的日志就写入新的日志文件。
为啥叫回滚呢?当分割的日志文件达到指定数目的上限个数时,最老的日志文件就会被删除。
logging库提供了两个可以用于日志滚动的class
1)RotatingFileHandler,它主要是根据日志文件的大小进行滚动,
2)TimeRotatingFileHandler,它主要是根据时间进行滚动。在实际应用中,我们通常根据时间进行滚动。
3.1.1按照天切分日志
import time
import logging
import logging.handlers
import os # 如果日志文件夹不存在,则创建
log_dir = "log-day" # 日志存放文件夹名称
log_path = os.getcwd() + os.sep + log_dir
if not os.path.isdir(log_path):
os.makedirs(log_path) # logging初始化工作
logging.basicConfig() # myapp的初始化工作
myapp = logging.getLogger('myapp')
myapp.setLevel(logging.INFO) # 添加TimedRotatingFileHandler
# 定义一个1天换一次log文件的handler
# 保留3个旧log文件
timefilehandler = logging.handlers.TimedRotatingFileHandler(
log_dir + os.sep + "sec.log",
when='M',
interval=1,
backupCount=3
)
# 设置后缀名称,跟strftime的格式一样
timefilehandler.suffix = "%Y-%m-%d_%H-%M-%S.log"
# timefilehandler.suffix = "%Y-%m-%d.log" formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
timefilehandler.setFormatter(formatter)
myapp.addHandler(timefilehandler) while True:
time.sleep(6)
myapp.info("test")
3.1.2按照时间日志回滚
import os
import time
import logging
import logging.handlers log_dir = "log-day" # 日志存放文件夹名称
log_path = os.getcwd() + os.sep + log_dir
if not os.path.isdir(log_path):
os.makedirs(log_path) # logging初始化工作
logging.basicConfig() # myapp的初始化工作
myapp = logging.getLogger('myapp')
myapp.setLevel(logging.INFO) # 添加TimedRotatingFileHandler
# 定义一个1秒换一次log文件的handler
# 保留3个旧log文件
timefilehandler = logging.handlers.TimedRotatingFileHandler("log-day/myapp.log", when='S', interval=1, backupCount=3)
# 设置后缀名称,跟strftime的格式一样
timefilehandler.suffix = "%Y-%m-%d_%H-%M-%S.log" formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
timefilehandler.setFormatter(formatter)
myapp.addHandler(timefilehandler) while True:
time.sleep(0.1)
myapp.info("test")
注意:filehanlder.suffix的格式必须这么写,才能自动删除旧文件,如果设定是天,就必须写成“%Y-%m-%d.log”,写成其他格式会导致删除旧文件不生效。这个配置在源码里能看出来,但是在官方文档并没有说明这一点!!!!!!!!!!
TimedRotatingFileHandler的构造函数定义如下:
TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]])
filename 是输出日志文件名的前缀,比如log/myapp.log
when 是一个字符串的定义如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
interval 是指等待多少个单位when的时间后,Logger会自动重建文件,当然,这个文件的创建
取决于filename+suffix,若这个文件跟之前的文件有重名,则会自动覆盖掉以前的文件,所以
有些情况suffix要定义的不能因为when而重复。
backupCount 是保留日志个数。默认的0是不会自动删除掉日志。若设3,则在文件的创建过程中
库会判断是否有超过这个3,若超过,则会从最先创建的开始删除。
3.1.3 按照大小日志回滚
RotatingFileHandler基于文件大小切分
这个配置是可以生效的,符合预期
import os
import time
import logging
import logging.handlers log_dir = "log-day" # 日志存放文件夹名称
log_path = os.getcwd() + os.sep + log_dir
if not os.path.isdir(log_path):
os.makedirs(log_path)
# logging初始化工作
logging.basicConfig() # myapp的初始化工作
myapp = logging.getLogger('myDemo')
myapp.setLevel(logging.INFO) # 写入文件,如果文件超过100个Bytes,仅保留5个文件。
handler = logging.handlers.RotatingFileHandler(
'log-day/myDemo.log', maxBytes=500, backupCount=5) formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
# 设置后缀名称,跟strftime的格式一样
myapp.addHandler(handler) while True:
time.sleep(0.1)
myapp.info("file test")
3.2traceback
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log-day/log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter) console = logging.StreamHandler()
console.setLevel(logging.INFO) logger.addHandler(handler)
logger.addHandler(console) logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
try:
open("log-day/sklearn.txt","rb")
except (SystemExit,KeyboardInterrupt):
raise
except Exception:
logger.error("Faild to open sklearn.txt from logger.error",exc_info = True) logger.info("Finish")
也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info = True,_args),
将logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)==>>
logger.exception("Failed to open sklearn.txt from logger.exception")
python脚本攻略之log日志的更多相关文章
- Linux Shell脚本攻略 读书笔记
Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...
- LINUX SHELL脚本攻略笔记[速查]
Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgrep shell数学运算 命令状态 文件描述 ...
- 老李分享:《Linux Shell脚本攻略》 要点(七)
老李分享:<Linux Shell脚本攻略> 要点(七) 1.显示给定文件夹下的文件的磁盘适用情况 [root@localhost program_test]# du -a -h ./ ...
- linux shell脚本攻略笔记
前一阵子系统学习了下<linux shell脚本攻略>这本书.在此记录下自己的学习笔记 1. 输出颜色字符 echo -e "\e[1:41m" 1表示背景色 2 ...
- Linux shell 脚本攻略之统计文件的行数、单词数和字符数
摘自:<Linux shell 脚本攻略>
- Linux shell 脚本攻略之创建不可修改文件
摘自:<Linux shell 脚本攻略>
- Linux shell 脚本攻略之生成任意大小的文件
摘自:<Linux shell 脚本攻略>
- Linux shell 脚本攻略之批量重命名
摘自:<Linux shell 脚本攻略>
- Linux shell 脚本攻略之文件查找与文件列表
摘自:<Linux shell 脚本攻略>
随机推荐
- SpringBoot配置文件可存放位置和加载顺序
使用IDEA创建一个spring初始化项目后.默认的配置文件在resources文件夹下. SpringBoot启动时,会扫描application.properties或application.ym ...
- 21.根据hive绑定数据统计计算保存到hive表中
创建upflow表 create external table mydb2.upflow (ip string,sum string) row format delimited fields term ...
- Java的四层结构dto、dao、service、controller
首先,最底层的就是dto层,dto层就是所谓的model,dto中定义的是实体类,也就是.class文件,该文件中包含实体类的属性和对应属性的get.set方法:<bean> 其次,是da ...
- Golang 无法下载依赖 golang.org (GoLand解决方法)
如下图所示将Proxy设置为:https://goproxy.io/
- STL map 常见用法详解
<算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...
- 小白学习django第一站-环境配置
Django简单来说就是用Python开发的一个免费开源的Web框架 使用Django,使你能够以最小的代价构建和维护高质量的Web应用. 开搞!!! 工具准备: linux(ubuntu) + py ...
- Katu Puzzle POJ - 3678 (2 - sat)
有N个变量X1X1~XNXN,每个变量的可能取值为0或1. 给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三 ...
- OnMouseWheel的通常处理
BOOL CMainWindow::OnMouseWheel(UINT nFlags, short zDelta, CPoint point) { BOOL bUp = TRUE; int nDelt ...
- nignx简单介绍
Nginx的产生 没有听过Nginx?那么一定听过它的"同行"Apache吧!Nginx同Apache一样都是一种WEB服务器.基于REST架构风格,以统一资源描述符(Unifor ...
- Java函数式接口
函数式接口定义且只定义了一个抽象方法.函数式接口的抽象方法的签名称为函数描述符.Java 8的java.util.function包中引入了几个新的函数式接口. 1.Predicate java.ut ...