1 基本使用

转自:https://www.cnblogs.com/wf-linux/archive/2018/08/01/9400354.html
配置logging基本的设置,然后在控制台输出日志,
import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

运行时,控制台输出,

2016-10-09 19:11:19,434 - __main__ - INFO - Start print log
2016-10-09 19:11:19,434 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:11:19,434 - __main__ - INFO - Finish
logging中可以选择很多消息级别,如debug、info、warning、error以及critical。通过赋予logger或者handler不同的级别,开发者就可以只输出错误信息到特定的记录文件,或者在调试时只记录调试信息。
例如,我们将logger的级别改为DEBUG,再观察一下输出结果,
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
控制台输出,可以发现,输出了debug的信息。
2016-10-09 19:12:08,289 - __main__ - INFO - Start print log
2016-10-09 19:12:08,289 - __main__ - DEBUG - Do something
2016-10-09 19:12:08,289 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:12:08,289 - __main__ - INFO - Finish
logging.basicConfig函数各参数:
filename:指定日志文件名;
filemode:和file函数意义相同,指定日志文件的打开模式,'w'或者'a';
format:指定输出的格式和内容,format可以输出很多有用的信息,
参数:作用%(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:打印日志信息
datefmt:指定时间格式,同time.strftime();
level:设置日志级别,默认为logging.WARNNING;
stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略;

2 将日志写入到文件

2.2.1 将日志写入到文件
设置logging,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到logger,然后将日志写入到指定的文件中,
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

log.txt中日志数据为,

2016-10-09 19:01:13,263 - __main__ - INFO - Start print log
2016-10-09 19:01:13,263 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:01:13,263 - __main__ - INFO - Finish
2.2 将日志同时输出到屏幕和日志文件
logger中添加StreamHandler,可以将日志输出到屏幕上,
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("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.")
logger.info("Finish")
可以在log.txt文件和控制台中看到,
2016-10-09 19:20:46,553 - __main__ - INFO - Start print log
2016-10-09 19:20:46,553 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:20:46,553 - __main__ - INFO - Finish
可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,logging中包含的handler主要有如下几种,
handler名称:位置;作用StreamHandler:logging.StreamHandler;日志输出到流,可以是sys.stderr,sys.stdout或者文件
FileHandler:logging.FileHandler;日志输出到文件
BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滚方式
RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚
TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件
SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP sockets
DatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP sockets
SMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址
SysLogHandler:logging.handlers.SysLogHandler;日志输出到syslog
NTEventLogHandler:logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志
MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定buffer
HTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器
2.3 日志回滚
使用RotatingFileHandler,可以实现日志回滚,
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
#定义一个RotatingFileHandler,最多备份3个日志文件,每个日志文件最大1K
rHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3)
rHandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
rHandler.setFormatter(formatter)console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)logger.addHandler(rHandler)
logger.addHandler(console)logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
可以在工程目录中看到,备份的日志文件,
2016/10/09  19:36               732 log.txt
2016/10/09  19:36               967 log.txt.1
2016/10/09  19:36               985 log.txt.2
2016/10/09  19:36               976 log.txt.3

2.3 设置消息的等级

可以设置不同的日志等级,用于控制日志的输出,
日志等级:使用范围FATAL:致命错误
CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
ERROR:发生错误时,如IO操作失败或者连接问题
WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误
INFO:处理请求或者状态变化等日常事务
DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态

2.4 捕获traceback

Python中的traceback模块被用于跟踪异常返回信息,可以在logging中记录下traceback,
代码,
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("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("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")

控制台和日志文件log.txt中输出,

Start print log
Something maybe fail.
Faild to open sklearn.txt from logger.error
Traceback (most recent call last):File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>open("sklearn.txt","rb")
IOError: [Errno 2] No such file or directory: 'sklearn.txt'
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")
控制台和日志文件log.txt中输出,
Start print log
Something maybe fail.
Failed to open sklearn.txt from logger.exception
Traceback (most recent call last):File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>open("sklearn.txt","rb")
IOError: [Errno 2] No such file or directory: 'sklearn.txt'
Finish

2.5 多模块使用logging

主模块mainModule.py,
import logging
import subModule
logger = logging.getLogger("mainModule")
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("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)
console.setFormatter(formatter)logger.addHandler(handler)
logger.addHandler(console)logger.info("creating an instance of subModule.subModuleClass")
a = subModule.SubModuleClass()
logger.info("calling subModule.subModuleClass.doSomething")
a.doSomething()
logger.info("done with  subModule.subModuleClass.doSomething")
logger.info("calling subModule.some_function")
subModule.som_function()
logger.info("done with subModule.some_function")

子模块subModule.py,

import loggingmodule_logger = logging.getLogger("mainModule.sub")
class SubModuleClass(object):def __init__(self):self.logger = logging.getLogger("mainModule.sub.module")self.logger.info("creating an instance in SubModuleClass")def doSomething(self):self.logger.info("do something in SubModule")a = []a.append(1)self.logger.debug("list a = " + str(a))self.logger.info("finish something in SubModuleClass")def som_function():module_logger.info("call function some_function")

执行之后,在控制和日志文件log.txt中输出,

2016-10-09 20:25:42,276 - mainModule - INFO - creating an instance of subModule.subModuleClass
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - creating an instance in SubModuleClass
2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.subModuleClass.doSomething
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - do something in SubModule
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - finish something in SubModuleClass
2016-10-09 20:25:42,279 - mainModule - INFO - done with  subModule.subModuleClass.doSomething
2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.some_function
2016-10-09 20:25:42,279 - mainModule.sub - INFO - call function some_function
2016-10-09 20:25:42,279 - mainModule - INFO - done with subModule.some_function
首先在主模块定义了logger'mainModule',并对它进行了配置,就可以在解释器进程里面的其他地方通过getLogger('mainModule')得到的对象都是一样的,不需要重新配置,可以直接使用。定义的该logger的子logger,都可以共享父logger的定义和配置,所谓的父子logger是通过命名来识别,任意以'mainModule'开头的logger都是它的子logger,例如'mainModule.sub'。
实际开发一个application,首先可以通过logging配置文件编写好这个application所对应的配置,可以生成一个根logger,如'PythonAPP',然后在主函数中通过fileConfig加载logging配置,接着在application的其他地方、不同的模块中,可以使用根logger的子logger,如'PythonAPP.Core','PythonAPP.Web'来进行log,而不需要反复的定义和配置各个模块的logger。

3 通过JSON或者YAML文件配置logging模块

尽管可以在Python代码中配置logging,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。在Python 2.7及以后的版本中,可以从字典中加载logging配置,也就意味着可以通过JSON或者YAML文件加载日志的配置。

3.1 通过JSON文件配置

JSON配置文件,
{"version":1,"disable_existing_loggers":false,"formatters":{"simple":{"format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"}},"handlers":{"console":{"class":"logging.StreamHandler","level":"DEBUG","formatter":"simple","stream":"ext://sys.stdout"},"info_file_handler":{"class":"logging.handlers.RotatingFileHandler","level":"INFO","formatter":"simple","filename":"info.log","maxBytes":"10485760","backupCount":20,"encoding":"utf8"},"error_file_handler":{"class":"logging.handlers.RotatingFileHandler","level":"ERROR","formatter":"simple","filename":"errors.log","maxBytes":10485760,"backupCount":20,"encoding":"utf8"}},"loggers":{"my_module":{"level":"ERROR","handlers":["info_file_handler"],"propagate":"no"}},"root":{"level":"INFO","handlers":["console","info_file_handler","error_file_handler"]}
}
通过JSON加载配置文件,然后通过logging.dictConfig配置logging,
import json
import logging.config
import osdef setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"):path = default_pathvalue = os.getenv(env_key,None)if value:path = valueif os.path.exists(path):with open(path,"r") as f:config = json.load(f)logging.config.dictConfig(config)else:logging.basicConfig(level = default_level)def func():logging.info("start func")logging.info("exec func")logging.info("end func")if __name__ == "__main__":setup_logging(default_path = "logging.json")func()

3.2 通过YAML文件配置

通过YAML文件进行配置,比JSON看起来更加简介明了,
version: 1
disable_existing_loggers: False
formatters:simple:format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:console:class: logging.StreamHandlerlevel: DEBUGformatter: simplestream: ext://sys.stdoutinfo_file_handler:class: logging.handlers.RotatingFileHandlerlevel: INFOformatter: simplefilename: info.logmaxBytes: 10485760backupCount: 20encoding: utf8error_file_handler:class: logging.handlers.RotatingFileHandlerlevel: ERRORformatter: simplefilename: errors.logmaxBytes: 10485760backupCount: 20encoding: utf8
loggers:my_module:level: ERRORhandlers: [info_file_handler]propagate: no
root:level: INFOhandlers: [console,info_file_handler,error_file_handler]
通过YAML加载配置文件,然后通过logging.dictConfig配置logging,
import yaml
import logging.config
import osdef setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"):path = default_pathvalue = os.getenv(env_key,None)if value:path = valueif os.path.exists(path):with open(path,"r") as f:config = yaml.load(f)logging.config.dictConfig(config)else:logging.basicConfig(level = default_level)def func():logging.info("start func")logging.info("exec func")logging.info("end func")if __name__ == "__main__":setup_logging(default_path = "logging.yaml")func()

python 日志 logging模块(详细解析)相关推荐

  1. Python 日志logging模块初探及多线程踩坑(2)

    系列文章: Python 日志logging模块初探及多线程踩坑(1) Python 日志logging模块初探及多线程踩坑(2) 接着上面一篇文章,我们这篇来写一个多进程兼容且无损性能的 Timed ...

  2. python之 logging模块详细使用【转载】

    很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,主要用于输出 ...

  3. python 的日志logging模块学习

    2019独角兽企业重金招聘Python工程师标准>>> python 的日志logging模块学习 分类: python 2011-08-02 23:51 8338人阅读 评论(0) ...

  4. python中日志logging模块和异常捕获traceback模块的使用

    python中日志logging模块和异常捕获traceback模块的使用 参考文章: (1)python中日志logging模块和异常捕获traceback模块的使用 (2)https://www. ...

  5. logging模块详细使用

    啄木鸟社区里的Pythonic八荣八耻有一条: 以打印日志为荣 , 以单步跟踪为耻; 很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误.警告等信息输出,python ...

  6. Python中logging模块的基本用法

    本文首发于:行者AI 在开发项目时,我们不可能将所有的信息都打印在控制台中.我们可以使用Python标准库提供的logging API来处理.相比print,logging模块提供了许多强大而灵活的功 ...

  7. python 之logging 模块

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  8. Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life

    Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life 学习目标 Python日志Logging 小游戏设计game of life 课后作业(2必做) ...

  9. python stdout_详解使用python的logging模块在stdout输出的两种方法

    详解使用python的logging模块在stdout输出 前言: 使用python的logging模块时,除了想将日志记录在文件中外,还希望在前台执行python脚本时,可以将日志直接输出到标准输出 ...

最新文章

  1. 理解CNN卷积层与池化层计算
  2. Java集合查找Map,java:使用hashmap或其他一些java集合创建查找...
  3. SimpleAdapter与listview,gridview的组合用法
  4. mysql重装要删注册表_Mysql重装问题—删除注册表
  5. 结构struct(值类型)在实际应用要注意的二点:
  6. Laravel-admin hasMany表单关联提交报错字段 无详细信息错误说明
  7. MySQL 授权远程登录(Ubuntu 环境)
  8. php文件下载不完整,求帮看下这段PHP下载MP4文件的有关问题,文件下载不完整
  9. 程序员最深情的告白——《致对象》
  10. Unity4.3 2D新特性
  11. Django【跨域】
  12. .Net Framework 总结
  13. 郑大计算机组成原理(专科)试卷 答案,专科《数字电路与逻辑设计》
  14. 让自己的底线一降再降,相当于没有底线
  15. 适合小白的 Asyncio 教程!
  16. Android中百度地图基础实现,定位
  17. 指南-Luat二次开发教程-功能开发教程-SOCKET
  18. 树莓派 交叉编译工具链的安装
  19. 网易云 音乐 url 引入步骤
  20. 为什么进入boot怎么只有计算机这个应用,电脑开机就进入bios的解决方法

热门文章

  1. 运算阶乘的代码_【必修1】2.4可以复用的代码
  2. 邀请函丨云和恩墨邀您一起迈向混合数据库时代!
  3. 活动丨PGConf.Asia大会11月17-20日线上直播!
  4. 请收下这10篇2020上半年最受欢迎的数据库技术文章
  5. 带你探索CPU调度的奥秘
  6. K近邻算法:机器学习萌新必学算法
  7. 【玩转Atlas200DK系列】为Atlas200DK配置wifi外挂模块
  8. Vue深入学习2—虚拟DOM和Diff算法
  9. SpringBoot 之 跳转页面的几种方法
  10. Kotlin学习笔记25 协程part5 协程的同步与异步