Python开发之日志记录模块:logging
1 引言
2 日志等级
日志等级(level)
|
描述
|
DEBUG
|
最详细的日志信息,典型应用场景是 问题诊断
|
INFO
|
信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
|
WARNING
|
当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
|
ERROR
|
由于一个更严重的问题导致某些功能不能正常运行时记录的信息
|
CRITICAL
|
当发生严重错误,导致应用程序不能继续运行时记录的信息
|
3 记录日志
3.1 记录日志之logging模块级函数
函数
|
说明
|
logging.debug(msg, *args, **kwargs)
|
创建一条严重级别为DEBUG的日志记录
|
logging.info(msg, *args, **kwargs)
|
创建一条严重级别为INFO的日志记录
|
logging.warning(msg, *args, **kwargs)
|
创建一条严重级别为WARNING的日志记录
|
logging.error(msg, *args, **kwargs)
|
创建一条严重级别为ERROR的日志记录
|
logging.critical(msg, *args, **kwargs)
|
创建一条严重级别为CRITICAL的日志记录
|
函数
|
说明
|
logging.log(level, *args, **kwargs)
|
创建一条严重级别为level的日志记录
|
- import logging
- logging.debug('debug')
- logging.info('info')
- logging.warn('warn')
- logging.error('error')
- logging.critical('critical')
- logging.warn('Today is %s',datetime.date.today())
函数
|
说明
|
logging.basicConfig(**kwargs)
|
对root logger进行一次性配置
|
- import logging
- logging.basicConfig(level=logging.DEBUG) # 设置日志等级
- logging.debug('debug')
- logging.info('info')
- logging.warn('warn')
- logging.error('error')
- logging.critical('critical')
- import logging
- logging.basicConfig(level=logging.DEBUG) # 设置日志等级
- logging.basicConfig(level=logging.INFO) # 重新设置日志等级
- logging.debug('debug')
- logging.info('info')
- logging.warn('warn')
- logging.error('error')
- logging.critical('critical')
参数名称
|
描述
|
filename
|
指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了
|
filemode
|
指定日志文件的打开模式,默认为'a'。需要注意的是,该选项要在filename指定时才有效
|
format
|
指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。
|
datefmt
|
指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
|
level
|
指定日志器的日志级别
|
stream
|
指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常
|
style
|
Python 3.2中新添加的配置项。指定format格式字符串的风格,可取值为'%'、'{'和'$',默认为'%'
|
handlers
|
Python 3.3中新添加的配置项。该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。
|
字段/属性名称
|
使用格式
|
描述
|
asctime
|
%(asctime)s
|
将日志的时间构造成可读的形式,默认情况下是‘2019-03-28 00:00:00,000’的形式,精确到毫秒
|
name
|
%(name)s
|
所使用的日志器名称,默认是'root',因为默认使用的是 rootLogger
|
filename
|
%(filename)s
|
调用日志输出函数的模块的文件名; pathname的文件名部分,包含文件后缀
|
funcName
|
%(funcName)s
|
由哪个function发出的log, 调用日志输出函数的函数名
|
levelname
|
%(levelname)s
|
日志的最终等级(被filter修改后的)
|
message
|
%(message)s
|
日志信息, 日志记录的文本内容
|
lineno
|
%(lineno)d
|
当前日志的行号, 调用日志输出函数的语句所在的代码行
|
levelno
|
%(levelno)s
|
该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
|
pathname
|
%(pathname)s
|
完整路径 ,调用日志输出函数的模块的完整路径名,可能没有
|
process
|
%(process)s
|
当前进程, 进程ID。可能没有
|
processName
|
%(processName)s
|
进程名称,Python 3.1新增
|
thread
|
%(thread)s
|
当前线程, 线程ID。可能没有
|
threadName
|
%(thread)s
|
线程名称
|
module
|
%(module)s
|
调用日志输出函数的模块名, filename的名称部分,不包含后缀即不包含文件后缀的文件名
|
created
|
%(created)f
|
当前时间,用UNIX标准的表示时间的浮点数表示; 日志事件发生的时间--时间戳,就是当时调用time.time()函数返回的值
|
relativeCreated
|
%(relativeCreated)d
|
输出日志信息时的,自Logger创建以 来的毫秒数; 日志事件发生的时间相对于logging模块加载时间的相对毫秒数
|
msecs
|
%(msecs)d
|
日志事件发生事件的毫秒部分。logging.basicConfig()中用了参数datefmt,将会去掉asctime中产生的毫秒部分,可以用这个加上
|
- import logging
- fmt = '%(asctime)s , %(levelname)s , %(filename)s %(funcName)s line %(lineno)s , %(message)s'
- datefmt = '%Y-%m-%d %H:%M:%S %a'
- logging.basicConfig(level=logging.DEBUG,
- format=fmt,
- datefmt=datefmt,
- filename=".log")
- logging.debug('debug')
- logging.info('info')
- logging.warn('warn')
- logging.error('error')
- logging.critical('critical')
3.2 记录日志之logging四大组件

组件名称
|
对应类名
|
功能描述
|
日志器
|
Logger
|
用于提供日志接口,常用于配置和发送日志消息
|
处理器
|
Handler
|
用于写入日志并输出到指定位置,例如控制台、文件或网络位置等
|
过滤器
|
Filter
|
对日志记录进行进一步过滤,输出符合条件的日志记录
|
格式器
|
Formatter
|
配置日志记录的最终输出格式
|
- logger.setLevel() :设置日志器处理日志信息的最低级别
- logger.addHandler():为该logger对象添加一个handler对象
- logger.removeHandler():为该logger对象添加移除一个handler对象
- logger.addFilter():为该logger对象添加一个filter对象
- logger.removeFilter():为该logger对象移除一个filter对象
- logger.debug(),logger.info(),logger.warning(),logger.error(),logger.critical():创建一个对应等级的日志记录
- handler.setLevel():设置handler处理的日志信息最低级别
- handler.setFormatter():为handler设置一个格式器对象
- handler.addFilter():为handler添加一个过滤器对象
- handler.removeFilter():为handler删除一个过滤器对象
Handler
|
描述
|
logging.StreamHandler
|
将日志消息发送到输出到Stream,如std.out, std.err或任何file-like对象。
|
logging.FileHandler
|
将日志消息发送到磁盘文件,默认情况下文件大小会无限增长
|
logging.handlers.RotatingFileHandler
|
将日志消息发送到磁盘文件,并支持日志文件按大小切割
|
logging.hanlders.TimedRotatingFileHandler
|
将日志消息发送到磁盘文件,并支持日志文件按时间切割
|
logging.handlers.HTTPHandler
|
将日志消息以GET或POST的方式发送给一个HTTP服务器
|
logging.handlers.SMTPHandler
|
将日志消息发送给一个指定的email地址
|
logging.NullHandler
|
该Handler实例会忽略error messages,通常被想使用logging的library开发者使用来避免'No handlers could be found for logger XXX'信息的出现。
|
- import logging
- logger = logging.getLogger()
- logger.setLevel(logging.DEBUG)
- # 控制台输出
- con_handler = logging.StreamHandler()
- con_handler.setLevel(logging.INFO)
- logger.addHandler(con_handler)
- # 输出到文件a.log
- file_a_handler = logging.FileHandler('./a.log', encoding='UTF-8')
- file_a_handler.setLevel(logging.DEBUG)
- logger.addHandler(file_a_handler)
- # 输出到文件b.log
- file_b_handler = logging.FileHandler('./b.log', encoding='UTF-8')
- file_b_handler.setLevel(logging.WARNING)
- logger.addHandler(file_b_handler)
- if __name__=='__main__':
- logger.debug('debug msg')
- logger.info('info msg')
- logger.warning('warn msg')
- fmt:指定消息格式化字符串,如果不指定该参数则默认使用message的原始值
- datefmt:指定日期格式字符串,如果不指定该参数则默认使用"%Y-%m-%d %H:%M:%S"
- style:指定格式化占位符,可取值为 '%', '{'和 '$',如果不指定该参数则默认使用'%'
- import logging
- logger = logging.getLogger(__name__)
- handler = logging.StreamHandler()
- logger.setLevel(logging.DEBUG)
- # 定义格式器,添加到处理器中
- fmt = '%(asctime)s , %(levelname)s , %(filename)s %(funcName)s line %(lineno)s , %(message)s'
- datefmt = '%Y-%m-%d %H:%M:%S %a'
- log_fmt = logging.Formatter(fmt=fmt, datefmt=datefmt)
- handler.setFormatter(log_fmt)
- logger.addHandler(handler)
- logger.debug('debug msg')
- logger.info('info msg')
- import logging
- class CountryFilter(logging.Filter):
- def filter(self,record):
- return "America" not in record.getMessage()
- logger = logging.getLogger()
- handler = logging.StreamHandler()
- logger.addHandler(handler)
- logger.setLevel(logging.DEBUG)
- logger.addFilter(CountryFilter())
- logger.critical('I love America')
- logger.debug('I love China')
4 logging奇淫巧技
4.1 记录异常信息:捕获traceback
- import logging
- logger = logging.getLogger(__name__)
- handler = logging.FileHandler('./.log',encoding='utf-8')
- logger.setLevel(logging.DEBUG)
- # 定义格式器,添加到处理器中
- fmt = '%(asctime)s , %(levelname)s , %(filename)s %(funcName)s line %(lineno)s , %(message)s'
- datefmt = '%Y-%m-%d %H:%M:%S %a'
- log_fmt = logging.Formatter(fmt=fmt, datefmt=datefmt)
- handler.setFormatter(log_fmt)
- logger.addHandler(handler)
- try:
- logger.info('Running …')
- 1/0
- except Exception as e:
- logger.error('Exception occurs!',exc_info = True)
- # logger.exception(e) # 与上面这行效果一样
4.2 多模块共享日志
- import logging
- import log_child
- logger = logging.getLogger('main')
- logger.setLevel(logging.DEBUG)
- fmt = '%(name)s , %(asctime)s , %(levelname)s , %(filename)s %(funcName)s line %(lineno)s , %(message)s'
- datefmt = '%Y-%m-%d %H:%M:%S %a'
- log_fmt = logging.Formatter(fmt=fmt, datefmt=datefmt)
- handler = logging.FileHandler('./.log',encoding='utf-8')
- handler.setFormatter(log_fmt)
- logger.addHandler(handler)
- if __name__=='__main__':
- logger.debug('Running …')
- log_child.fun_child()
- import logging
- logger = logging.getLogger('main.child')
- logger.setLevel(logging.DEBUG)
- def fun_child():
- try:
- logger.info('Running …')
- 1 / 0
- except Exception as e:
- logger.exception(e)
4.3 使用配置文件配置logger
- [loggers] #固定写法,定义logger的模块
- keys=root,log_1,log_2 #创建三个logger,root是父类,必需存在的,其他两个logger的name分别为
- [logger_root] # 定制上面的logger,严格要求格式为"logger_loggername",必须通过loggername与上面的logger一一对应
- level=DEBUG # 设置日志级别
- qualname=root # 对于root,其实这里可以不填,默认就是root
- handlers=debugs #设置指定处理器,如果有多个处理器,中间以逗号分隔,这个名字待会儿 我们会以固定格式"handler_(value)"创建
- [logger_log_1]
- level=INFO
- qualname=log_1 #除了root以外,必须要设置这个属性,用于定义打印输出时候的logger名
- handlers=infos
- propagate=0 # 是否将消息想父日志传递,0表示不传递,1表示传递。如果向上传递,父日志器接收到消息后会以父日志器的配置再次处理该消息,所以可能所有多次输出
- [logger_log_2]
- level=WARNING
- qualname=log_2
- handlers=warns
- [handlers] #固定格式, 开始定义处理器
- keys=debugs,infos,warns#定义过滤器名称,与上面出现的handlers的值一一对应,下面定义以handler_handlername格式定义
- [handler_debugs]
- class=StreamHandler # 指定处理器的类名
- level=DEBUG # 设置级别
- formatter=form01 #定义格式器,名称为form01,下面会创建formatters,格式也是严格要求为formatter_formattername
- args=(sys.stdout,) # 控制台输出
- [handler_infos]
- class=FileHandler
- level=INFO
- formatter=form02
- args=('b.log','a')
- [handler_warns]
- class=FileHandler
- level=WARNING
- formatter=form02
- args=('a.log','a')# 写入到文件,写入方式
- [formatters] #固定格式
- keys=form01,form02 #定义名称,下面会引用格式,与上面出现的formatter的值对应
- [formatter_form01]
- format=%(asctime)s %(message)s # 定义消息输出格式,内容
- datefmt=%Y-%m-%d %H:%M:%S #日期输出格式
- [formatter_form02]
- format=%(asctime)s %(filename)s %(levelname)s %(message)s
- datefmt=%Y-%m-%d %H:%M:%S
- # _*_coding:utf-8_*_
- import logging
- from logging.config import fileConfig
- fileConfig('log.conf')
- root= logging.getLogger(name="root")
- log_1= logging.getLogger(name="log_1")
- log_2= logging.getLogger(name="log_2")
- root.debug('root_debug')
- root.info('root_info')
- root.warning('root_warning')
- log_1.debug('log_1_debug')
- log_1.info('log_1_info')
- log_1.warning('log_1_warning')
- log_2.debug('log_2_debug')
- log_2.info('log_2_info')
- log_2.warning('log_2_warning')
4.3 日志回滚
- # -*- coding:utf-8 -*-
- import logging
- from logging.handlers import RotatingFileHandler
- logger = logging.getLogger('main')
- logger.setLevel(level = logging.INFO)
- # 定义一个RotatingFileHandler,最多备份三个日志文件, 每个日志文件最大1k
- file_handler = RotatingFileHandler(".log",maxBytes = 1*1024,backupCount = 3)
- file_handler.setLevel(logging.INFO)
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- file_handler.setFormatter(formatter)
- cons_handler = logging.StreamHandler()
- cons_handler.setLevel(logging.DEBUG)
- cons_handler.setFormatter(formatter)
- logger.addHandler(file_handler)
- logger.addHandler(cons_handler)
- if __name__=='__main__':
- while True:
- logger.debug("debug")
- logger.info("info")
- logger.warning("warning")
- logger.critical("critical")
- import time
- import logging
- import logging.handlers
- # logging初始化工作
- logging.basicConfig()
- # logger的初始化工作
- logger = logging.getLogger('main')
- logger.setLevel(logging.INFO)
- # 添加TimedRotatingFileHandler
- # 定义一个1秒换一次log文件的handler
- # 保留3个旧log文件
- timefilehandler = logging.handlers.TimedRotatingFileHandler(".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)
- logger.addHandler(timefilehandler)
- while True:
- time.sleep(0.1)
- logger.debug("debug")
- logger.info("info")
- logger.warning("warning")
- logger.critical("critical")
5 总结
Python开发之日志记录模块:logging的更多相关文章
- [ Python入门教程 ] Python中日志记录模块logging使用实例
python中的logging模块用于记录日志.用户可以根据程序实现需要自定义日志输出位置.日志级别以及日志格式. 将日志内容输出到屏幕 一个最简单的logging模块使用样例,直接打印显示日志内容到 ...
- 日志记录模块logging
在python中,日志记录显示有两种方式,一种是保存在文件和打印屏幕上,一种保存在文件中. 第一种,直接保存在文件中. import logging #日志模块,方便记录日志 # 下面是配置日志记录格 ...
- Python中的日志记录方案-logging模块&loguru模块
原文链接 原创: 崔庆才 在 Python 中,一般情况下我们可能直接用自带的 logging 模块来记录日志,包括我之前的时候也是一样.在使用时我们需要配置一些 Handler.Formatter ...
- python爬虫学习之日志记录模块
这次的代码就是一个日志记录模块,代码很容易懂,注释很详细,也不需要安装什么库.提供的功能是日志可以显示在屏幕上并且保存在日志文件中.调用的方式也很简单,测试代码里面有. 源代码: #encoding= ...
- c++日志记录模块
C++ 日志记录模块 该模块从实际项目中产生,通过extern声明的方式,可在代码不同模块中生成日志,日志文件名称为随机码加用户指定名称,采用随机码是为了避免日志文件可能被覆盖的问题. 愿意的话你也能 ...
- 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块
Log4a 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块 github地址 : https://github.com/EalenXie/log4a 在API每次被请求时 ...
- python基础语法13 内置模块 subprocess,re模块,logging日志记录模块,防止导入模块时自动执行测试功能,包的理论
subprocess模块: - 可以通过python代码给操作系统终端发送命令, 并且可以返回结果. sub: 子 process: 进程 import subprocess while Tru ...
- python3 logging 日志记录模块
#coding:utf-8 import logginglogging.basicConfig(filename='log1.log', format='%(asctime)s -%(name)s-% ...
- python学习笔记9--日志模块logging
我们在写程序的时候经常会打一些日志来帮助我们查找问题,这次学习一下logging模块,在python里面如何操作日志.介绍一下logging模块,logging模块就是python里面用来操作日志的模 ...
随机推荐
- 使用sqlmap中tamper脚本绕过waf
使用sqlmap中tamper脚本绕过waf 刘海哥 · 2015/02/02 11:26 0x00 背景 sqlmap中的tamper脚本来对目标进行更高效的攻击. 由于乌云知识库少了sqlmap- ...
- 操作系统笔记(六)页面置换算法 FIFO法 LRU最近最久未使用法 CLOCK法 二次机会法
前篇在此: 操作系统笔记(五) 虚拟内存,覆盖和交换技术 操作系统 笔记(三)计算机体系结构,地址空间.连续内存分配(四)非连续内存分配:分段,分页 内容不多,就不做index了. 功能:当缺页中断发 ...
- ubuntu 系统关键指令
1. 查看系统版本号 cat /etc/issue uname -a cat /proc/version 2. linux 32/64 bit? getconf LONG_BIT 3. dpkg 的命 ...
- kafka系列二、kafka manager的安装和使用
1. Yahoo kafka manager介绍 项目地址:https://github.com/yahoo/kafka-manager Requirements: Kafka 0.8.1.1 or ...
- jython获取was5.1的jvm监控参数
perfName = AdminControl.completeObjectName ('type=Perf,process=server1,node=TSC,cell=TSC,*') perfONa ...
- WebSphere的jython编码的一个坑
was5.1版本,用"name=" in line这类判断字符串包含的方式时,系统会提示报错 TypeError: string member test needs char le ...
- 红黑树与AVL树
概述:本文从排序二叉树作为引子,讲解了红黑树,最后把红黑树和AVL树做了一个比较全面的对比. 1 排序二叉树 排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索. 排序二叉树 ...
- 018_nginx_proxy死循环问题
今天线上遇到一个请求一次,触发多次的请求,而且直接把nginx机器压垮了.经排查,经过如下: 一. server{ server www.jyall.com; location /latestrele ...
- apache服务器的常用功能及设置
安装httpd yum -y install httpd 服务脚本:/etc/rc.d/init.d/httpd 脚本配置文件:/etc/sysconfig/httpd ...
- 转载:分布式文件系统 - FastDFS 在 CentOS 下配置安装部署(1)
原文:http://blog.mayongfa.cn/192.html 一.安装 libfastcommon 和 FastDFS 1.下载安装 libfastcommon ,这里是通过wget下载(我 ...