python大型项目中的日志模块_Python中日志模块的使用

前言

程序和脚本往往是无人值守运行的,一旦发生问题,就需要我们去追溯当时的情况来定位问题的原因。

这便需要我们在程序和脚本中引入日志的功能。

相比于print信息,使用logging日志有以下优点

可以记录输出日志的时间、文件、函数以及代码行,甚至线程名和线程号

可以分等级记录日志(调试级、信息级、警告级、错误级、严重错误级)

即可以实时输出到屏幕,也可以输出到文件

基本使用

Python中使用自带的logging模块输出日志,logging模块的主要组件为logger日志记录器,如下图。

2ef642dd0f68e09089b781130bf1fcac.png

基本使用如下

import logging

logging.debug('调试级别的日志')

logging.info('信息级别的日志')

logging.warning('警告级别的日志') # 或logging.warn('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

try:

1/0

except Exception as ex:

logging.exception(ex) # 错误级别的日志,显示多行回溯信息

运行结果为

WARNING:root:警告级别的日志

ERROR:root:错误级别的日志

CRITICAL:root:严重错误级别的日志

ERROR:root:division by zero

Traceback (most recent call last):

File "", line 9, in

1/0

ZeroDivisionError: division by zero

发现只显示warning、error、critical的日志,这是因为logging中的默认日志记录器(root logger)的level级别是logging.WARNING,即默认只显示警告级别以上的日志。

修改日志等级

我们可以使用logging.basicConfig来修改root logger的设置。

import logging

logging.basicConfig(level=logging.DEBUG) # 配置全局root logger

logging.debug('调试级别的日志')

logging.info('信息级别的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

再次运行,发现所有的日志都可以输出了。

level日志等级支持

logging.NOTSET: 未设置,输出所有级别的日志

logging.DEBUG: 调试级别,输出所有级别的日志

logging.INFO: 信息级别,输出包含信息级别以上的日志

logging.WARNING: 警告级别,输出包含警告级别的日志

logging.ERROR: 错误级别,输出包含错误级别以上的日志

logging.CRITICAL: 严重错误级别,仅输出严重错误日志

日志等级的关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET

修改日志格式

日志默认的格式为WARNING:root:警告级别的日志,即等级:Logger名称:输出消息。我们也可以在logging.basicConfig中使用format参数来修改其输出格式。

import logging

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s')

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

运行输出如下:

2020-11-04 10:11:49,238 - DEBUG - 调试级别的日志

2020-11-04 10:11:49,238 - INFO - 信息基本的日志

2020-11-04 10:11:49,238 - WARNING - 警告级别的日志

2020-11-04 10:11:49,238 - ERROR - 错误级别的日志

2020-11-04 10:11:49,238 - CRITICAL - 严重错误级别的日志

format中使用%(变量名)s这样的具名占位符,来输出不同的信息,其他的字符则原样显示。

支持的变量如下:

%(levelno)s: 打印日志级别的数值

%(levelname)s: 打印日志级别名称

%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]

%(filename)s: 打印当前执行程序名

%(funcName)s: 打印日志的当前函数

%(lineno)d: 打印日志的当前行号(因为是数字,所以使用%d)

%(asctime)s: 打印日志的时间

%(thread)d: 打印线程ID

%(threadName)s: 打印线程名称

%(process)d: 打印进程ID

%(message)s: 打印日志信息

对于日期,我们可以使用datefmt来修改,比如,将上例中的logging.basicConfig修改为

...

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S')

...

输出形式如下:

2020年11月04日 10:19:04 - DEBUG - 调试级别的日志

2020年11月04日 10:19:04 - INFO - 信息基本的日志

2020年11月04日 10:19:04 - WARNING - 警告级别的日志

2020年11月04日 10:19:04 - ERROR - 错误级别的日志

2020年11月04日 10:19:04 - CRITICAL - 严重错误级别的日志

输出到文件

日志是默认输出的屏幕的,也可以通过logging.basicConfig中的filename将日志输出到文件。

import logging

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S',

filename='run.log',

filemode='a'

)

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

运行后,日志将不会输出到屏幕,转而输出到文件中,filemode支持'w'每次覆盖和'a'追加模式。

自定义handlers

如果想即输出到屏幕又输出到文件,我们可以在logging.basicConfig的handlers参数中添加两个不同的handler来实现,logging.StreamHander()可以用于输出到屏幕,logging.FileHandler()可以用于输出到文件。

import logging

cli_handler = logging.StreamHandler() # 输出到屏幕的日志处理器

file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8') # 输出到文件的日志处理器

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S',

handlers=[cli_handler, file_handler] # 添加两个日志处理器

)

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

这样便可以即输出到屏幕又输出到文件了。

自定义Logger

使用logging.basicConfig是直接配置全局的root logger,会对项目中所有的模块及三方包产生影响。

为了不影响其他模块和三方包的日志输出,我们可以使用自定义Logger,即日志记录器,基本步骤为

使用logging.getLogger()新建一个logger对象,并配置期日志等级(总日志开关)

新建多个日志处理器,分别设置其格式和日志等级

将多个日志处理器添加到logger中

代码如下

# 文件名: mylogger.py

import logging

def get_logger(name):

logger = logging.getLogger(name)

logger.setLevel(logging.DEBUG) # 设置总日志等级

format = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y年%m月%d日 %H:%M:%S') # 日志格式

cli_handler = logging.StreamHandler() # 输出到屏幕的日志处理器

file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8') # 输出到文件的日志处理器

cli_handler.setFormatter(format) # 设置屏幕日志格式

file_handler.setFormatter(format) # 设置文件日志格式

cli_handler.setLevel(logging.INFO) # 设置屏幕日志等级, 可以大于日志记录器设置的总日志等级

# file_hander.setLevel(logging.DEBUG) # 不设置默认使用logger的等级

logger.handlers.clear() # 清空已有处理器, 避免继承了其他logger的已有处理器

logger.addHandler(cli_handler) # 将屏幕日志处理器添加到logger

logger.addHandler(file_handler) # 将文件日志处理器添加到logger

return logger

使用方式为,导入本模块的get_logger方法,使用logger代替logging打印各种信息。

from mylogger import get_logger

logger = get_logger('mylogger')

logger.debug('调试级别的日志')

logger.info('信息基本的日志')

logger.warning('警告级别的日志')

logger.error('错误级别的日志')

logger.critical('严重错误级别的日志')

注意:由于logger具有子模块继承性,在项目中多个地方使用get_logger生成不同的logger对象时,有可能会继承其他logger的处理器。建议项目中使用同一个logger。或者对日志记录器使用单例模式。

在服务端项目中(如web项目),由于进程是长久运行,可以使用滚动日志处理器来分割日志文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSI强调:SSPL并不是开源许可证

喜欢就关注我们吧!日前,开放源代码促进会 OSI(Open Source Initiative)强调,SSPL 并不是一个开源许可证。OSI 表示,SSPL(Server Side Public License) 是一种典型的 “fauxpen”&…

.NET Remoting

轉自:http://www.iiiedu.org.tw/knowledge/knowledge20030430_2.htm.NET Remoting 資策會數位教育研究所講師 董淑惠     概念簡介 微軟以往使用COM/DCOM的技術來處理分散式系統架構,透過Client端的Proxy代理程式來呼叫遠端Server機器上的物件。.NET Framework則…

通过python实现linux切换用户_Python操作远程服务器切换到root用户

在自动化运维过程中,需要远程服务器切换到root用户下执行命令,尝试了一些方法,得到如下好用的方法,供大家使用: import time import paramiko def verification_ssh(host,username,password,port,root_pwd,cmd): spara…

RabbitMQ 入门:1. Message Broker(消息代理)

Message Broker(消息代理)维基百科对 Message Broker 的定义是:Message broker是一种中介程序模块,它把消息从发送方的正式消息传递协议转化为接收方的正式消息传递协议。这个定义略繁琐,下面看看 RabbitMQ 官网对 Mes…

什么时候我们应谈及性能?

【导读】实际项目开发中、有部分童鞋可能无时无刻都在关注性能,那么我们到底应该什么时候关注性能呢?个人以为,性能并非一次性就可完全成全,需结合实际业务有一个大致评估或预期,比如数据量大小,若预期短暂…

python编写正则表达式匹配单词_Python正则表达式匹配整个单词

守候你守候我 我认为,通过给出的答案,OP所期望的行为并没有完全实现。具体来说,布尔值的期望输出没有完成。给出的答案做帮助说明这一概念,我认为他们是优秀的。也许我可以说明我的意思,我认为OP使用了下面的例子。给出…

python中可以表示任意大的整数_Python无法表示99999999999999999999这样大的整数。

被邓为“小平和国一部意义义的具有际意称赞法律历史,无法”的性的一个具有杰作创造“是是(。表示。对于的容性要密封求高器,样整数包括性试验的要求中应进行气密各种。无法喷涂金属及工具有设备。吊装台起用多重机设备时,表示为(吊装用的常采…

[转]简单介绍如何用Reporting Service制作报表

1) 在安装好Reporting Service后,打开Visual studio .net ,选择新建项目,选择建立商业智能项目,选择新建一个报表项目,命名为reportservice1,再选确定,如下图: 2)之后,在…

freertos源码详解与应用开发 pdf_互联网企业面试必问Spring源码?搞定Spring源码,看完这篇就够了...

不用说,Spring已经成为Java后端开发的事实上的行业标准。无数公司选择Spring作为基本开发框架。大多数Java后端程序员在日常工作中也会接触到Spring。因此,如何很好地使用Spring,已成为Java程序员的必修课之一。同时,Spring Boot和…

MS-SQLSERVER--错用了LEN()函数

sqlserver数据导入oracle时发现字符长度不对。。下面是两个函数的区别:DATALENGTH 返回任何表达式所占用的字节数。LEN 返回给定字符串表达式的字符(而不是字节)个数,其中不包含尾随空格转载于:https://www.cnblogs.com/yooplmqj/…

rsa算法c语言实现_数据结构与算法之线性表-顺序表实现(C语言版本)

原文托管在Github: https://github.com/shellhub/blog/issues/52数据结构与算法之线性表-顺序表实现(C语言版本)前言数据结构与算法是一个程序员必备的技能之一,而顺序表更是每个程序员在面试过程中要经常被问到的,如Java语言中的ArrayList类的底层实现就是使用顺序…

hadoop安装详细步骤_推荐一个超详细的Hadoop安装教程,已有32万次阅读

安装Hadoop软件系列,首选Linux系统,比如Ubuntu。如果你的系统是Windows,建议再安装一个Ubuntu,组成双系统,如此可以发挥各自系统的特点。使用U盘制作一个系统,拿出一块分区用作新装的系统,开机启…

后宫佳丽三千,假如古代皇帝也懂负载均衡算法...

古代皇帝,后宫佳丽三千,没法做到雨露均沾,但为了繁衍后代,子嗣繁盛,弱水三千,只取一瓢饮显然是不行的。不同的朝代有不同的宠幸妃子的方法,著名的有羊车望幸、掷筛侍寝、翻牌悬灯等等。如果皇帝…

mac 配置php和mysql_Mac下配置PHP+MySql环境

由于最近需要布置mantis用来进行bug追踪,在此记录其过程。由于PHP apache环境在Mac OS上是自带的,所以不需要另处下安装包,只需要简单配置一下即可。首先打开终端输入命令:sudo vim /etc/apache2/httpd.conf其中有一行是这样的#Lo…

git使用的基本流程_git命令的基本使用

首先下载完git之后打开Git Bash配置你的邮箱和用户名(github或gitee):$ git config --global user.name "注册时账号的名字"$ git config --global user.email "注册时使用的邮箱"获取ssh公钥:ssh-keygen -t …

Code Runner for VS Code 突破 2000 万下载量!支持超过 50 种语言

还记得五年前的夏天,我在巨硬写着世界上最好的语言,有时也需要带着游标卡尺写着另一门语言。然而,我对这两门语言都不熟悉,如果能在 VS Code 中方便快捷地运行各种语言,那岂不是很方便?于是,我就…

mysql group where_[MySQL] 测试where group by order by的索引问题

1. select * from test where axx group by b order by c 如何加索引CREATE TABLE index_test (id int(10) unsigned NOT NULL AUTO_INCREMENT,name varchar(100) NOT NULL DEFAULT ,gid int(11) NOT NULL DEFAULT 0,age int(11) NOT NULL DEFAULT 0,PRIMARY KEY (id)) ENGI…

gpl可以商用吗_一文看懂开源许可证,能不能商用再也不抓瞎

在github中闲逛,宝藏多福利好。不过心里或许总有小忐忑,这么多开源项目,我的产品里能不能用呀!其实想知道项目能不能用看下项目的开源许可证就清楚了(即使是非软件产品比如数据、媒体、资料等也可以通过开源许可证知道它们的可用范…

使用 Tye 辅助开发 k8s 应用竟如此简单(一)

最近正巧在进行 Newbe.Claptrap 新版本的开发,其中使用到了 Tye 来辅助 k8s 应用的开发。该系列我们就来简单了解一下其用法。安装 Tye 首先,确保已经正确安装了 netcore 2.1 或以上版本的 dotnet SDK。Tye 目前还处于开发阶段,因此&#xff…

php上传文件很慢的原因_PHP编码安全:上传文件安全

一次性付费进群,长期免费索取教程,没有付费教程。进微信群回复公众号:微信群;QQ群:460500587教程列表 见微信公众号底部菜单 | 本文底部有推荐书籍 微信公众号:计算机与网络安全ID:Computer-net…