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里面用来操作日志的模 ...
随机推荐
- 数据库运维平台~inception回滚功能
一 简介:inception的另一个激动人心的功能,很强大.二 功能简介: inception会针对已经执行sql语句进行1 记录 2 生成回滚语句三 备份: 1 启用远程备份机制(强烈建议一台单 ...
- Application生命周期
onCreate 在创建应用程序时创建 onTerminate 当终止应用程序对象时调用,不保证一定被调用,当程序是被内核终止以便为其他应用程序释放资源,那么将不会提醒,并且不调用应用程序的对象的on ...
- Service的线程、工作线程、权限及系统Service
Service组件和其他组件一样,都是运行于应用的主线程当中,它们都运行于同一个单一的线程中. 可以把Service简单的理解成一个没有界面显示的Activity(这个比喻其实并不准确,因为Servi ...
- android okhttp的使用
OkHttpClient client = new OkHttpClient(); String url = ""; Request request = new Request.B ...
- ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(1)-EL/ET/ST
1.前言 ARMV8系统级编程模型主要包括异常级别.运行状态.安全状态.同步异常.异步异常.DEBUG 本文主要对系统级编程模型做一个概要介绍 2. 异常级别 2.1 Exception level概 ...
- python的技巧和方法你了解多少?
学了这些你的python代码将会改善与你的技巧将会提高. 1. 路径操作 比起os模块的path方法,python3标准库的pathlib模块的Path处理起路径更加的容易. 获取当前文件路径 前提导 ...
- springboot系列三、springboot 单元测试、配置访问路径、多个配置文件和多环境配置,项目打包发布
一.单元测试 生成的demo里面包含spring-boot-starter-test :测试模块,包括JUnit.Hamcrest.Mockito,没有的手动加上. <dependency> ...
- C++:STL vector:sizeof(vector)
原文地址:http://blog.csdn.net/zcsylj/article/details/7857009 int的大小是4,定义vector<int> vec,vec中有一个元素, ...
- windows系统中搭建Jenkins服务器
1 须知 100.126.36.232等Jenkins服务器是通过设置代理访问外网,管理Jenkins和插件升级站点的,本地安装受黄区网络限制需要特殊配置,且有些插件无法下载. 前提条件: ...
- saltStack运维工具的部署及master迁移实现的过程详解
服务器端:192.168.3.87 客户端:192.168.3.86.192.168.3.108 1.salt服务器端安装 192.168.3.87 rpm -Uvh http://mirrors.y ...