1 logging模块简介

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

  1. 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
  2. print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出
  3. 日志等级:

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日志的更多相关文章

  1. Linux Shell脚本攻略 读书笔记

    Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...

  2. LINUX SHELL脚本攻略笔记[速查]

    Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgrep shell数学运算 命令状态 文件描述 ...

  3. 老李分享:《Linux Shell脚本攻略》 要点(七)

    老李分享:<Linux Shell脚本攻略> 要点(七)   1.显示给定文件夹下的文件的磁盘适用情况 [root@localhost program_test]# du -a -h ./ ...

  4. linux shell脚本攻略笔记

    前一阵子系统学习了下<linux shell脚本攻略>这本书.在此记录下自己的学习笔记 1. 输出颜色字符  echo -e "\e[1:41m" 1表示背景色   2 ...

  5. Linux shell 脚本攻略之统计文件的行数、单词数和字符数

    摘自:<Linux shell 脚本攻略>

  6. Linux shell 脚本攻略之创建不可修改文件

    摘自:<Linux shell 脚本攻略>

  7. Linux shell 脚本攻略之生成任意大小的文件

    摘自:<Linux shell 脚本攻略>

  8. Linux shell 脚本攻略之批量重命名

    摘自:<Linux shell 脚本攻略>

  9. Linux shell 脚本攻略之文件查找与文件列表

    摘自:<Linux shell 脚本攻略>

随机推荐

  1. 获得http请求的RequestID

    firefox: F12---network---响应, 请求一个页面:

  2. [计蒜客T2237]魔法_树

    魔法 题目大意: 数据范围: 题解: 这个题挺好玩的 可以用反证法,发现所有叶子必须都得选而且所有叶子都选了合法. 故此我们就是要使得,一次操作之后使得叶子的个数最少. 这怎么弄呢? 我们发现,如果一 ...

  3. [CF544D]Destroying Roads_最短路_bfs

    D. Destroying Roads 题目大意: In some country there are exactly n cities and m bidirectional roads conne ...

  4. 小记--------sparksql和DataFrame的小小案例java、scala版本

    sparksql是spark中的一个模块,主要用于进行结构化数据的处理,他提供的最核心的编程抽象,就是DataFrame.同时,sparksql还可以作为分布式的sql查询引擎. 最最重要的功能就是从 ...

  5. linux 查找大文件

    查看磁盘使用情况:df -h [root@iZwz9gs2zseivevv1k5vnkZ /]# df -h Filesystem Size Used Avail Use% Mounted on /d ...

  6. Python开发之IDE选择

    Python开发之IDE 一.为什么用IDE 到现在为止,谁还不是个写过代码的人啦,但你有没有发现,每次写代码要新建文件.写完保存时还要选择存放地点,执行时还要切换到命令行调用python解释器,好麻 ...

  7. jmeter 工具学习 未完待续

    about Apache JMeter是Apache组织的开源项目,是 一个纯Java桌面应用,用于压力测试和性能测试,它最初被设计用于 web应用测试,后来逐渐的扩展到其他领域 jmeter可以用于 ...

  8. Qt 4.5发布(最大的变动是换用LGPL许可证,移植进了苹果的Cocoa框架。之前的Qt只支持Carbon框架,现在的Qt 4.5两者都支持。单一源代码创建出支持32位或64位字节的Intel或PowerPC Mac二进制文件)

            Nokia的开源Qt开发工具正式发布了4.5版.如前所述,Qt 4.5最大的变动是换用LGPL许可证,目前采用的三个许可证分别为LGPL/GPL和商业许可证.           新版 ...

  9. 一致性算法—Paxos、Raft、ZAB

    一致性算法—Paxos.Raft.ZAB 2019年04月21日 20:35:09 bulingma 阅读数 64更多 分类专栏: 分布式概念   版权声明:本文为博主原创文章,遵循CC 4.0 BY ...

  10. C#面向对象21 接口

    接口的规范: 1.接口是一种规范.只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员. 2.为了多态,接口不能被实例化,接口不new(不能创建对象) 3.接口中的成员不能加“访问修饰符”, ...