深入理解Python的logging模块:从基础到高级

在Python编程中,日志记录是一种重要的调试和错误追踪工具。Python的logging模块提供了一种灵活的框架,用于发出日志消息,这些消息可以被发送到各种输出源,如控制台、文件、HTTP GET/POST位置等。本文将深入探讨Python的logging模块,包括其基本用法、高级特性以及如何将其应用到实际项目中。

首先,我们来看一下logging模块的基本用法。logging模块的主要功能是提供一种灵活的框架,用于发出日志消息。这些消息可以被发送到各种输出源,如控制台、文件、HTTP GET/POST位置等。logging模块的核心是Logger类,它提供了应用程序可直接使用的接口。Logger实例化后,可以设置其日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL),并可以通过其方法来发出日志消息。

例如,以下是一个简单的logging模块的使用示例:

import logging# 创建一个logger
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)# 给logger添加handler
logger.addHandler(fh)# 记录一条日志
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')

在这个示例中,我们首先创建了一个名为’my_logger’的logger,并设置了其日志级别为DEBUG。然后,我们创建了一个handler,用于将日志消息写入到’test.log’文件中。我们还定义了handler的输出格式,包括时间戳、logger的名字、日志级别和日志消息。最后,我们将这个handler添加到logger中,并发出了几条不同级别的日志消息。

除了基本的用法,logging模块还提供了许多高级特性,如过滤器、格式化器、处理器等。过滤器可以根据日志消息的内容或级别来决定是否应该处理这条消息。格式化器可以定义日志消息的输出格式。处理器则负责将日志消息发送到指定的输出源。

例如,以下是如何使用过滤器和格式化器的示例:

import logging# 创建一个logger
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)# 创建一个过滤器,只处理INFO级别及以上的日志消息
class MyFilter(logging.Filter):def filter(self, record):return record.levelno >= logging.INFO
filter = MyFilter()
fh.addFilter(filter)# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)# 给logger添加handler
logger.addHandler(fh)# 记录一条INFO级别的日志消息和一条DEBUG级别的日志消息
logger.info('This is an info message')
logger.debug('This is a debug message')  # 这条消息不会被处理,因为它的级别低于INFO

在这个示例中,我们首先创建了一个名为’my_logger’的logger,并设置了其日志级别为DEBUG。然后,我们创建了一个handler,用于将日志消息写入到’test.log’文件中。我们还创建了一个过滤器,只处理INFO级别及以上的日志消息。最后,我们将这个handler添加到logger中,并发出了两条不同级别的日志消息。由于我们的过滤器只处理INFO级别及以上的日志消息,所以DEBUG级别的日志消息不会被处理。

本专栏封装日志工具类供外部使用:

配置文件

BASE:log_level: "debug"fh_file_log_level: "debug"  #生产环境换成warninglog_extension: ".log"test:url: "http://119.3.246.198:64644"

配置文件调用代码更新

import os
from utils.YamlUtil import YamlReadercurrent = os.path.abspath(__file__)BASE_DIR = os.path.dirname(os.path.dirname(current))_config_path = BASE_DIR + os.sep + "config"
_config_file = _config_path + os.sep + 'conf.yml'_log_path = BASE_DIR + os.sep + "logs"
def get_config_path():return _config_pathdef get_config_file():return _config_filedef get_log_path():return _log_path
class ConfigYaml:def __init__(self):self.config = YamlReader(get_config_file()).data()def get_conf_url(self):return self.config['BASE']['test']['url']def get_conf_log_level(self):#获取日志级别return self.config['BASE']['log_level']def get_conf_fh_file_log_level(self):#获取日志文件级别return self.config['BASE']['fh_file_log_level']def get_conf_log_extension(self):#获取日志文件扩展名return self.config['BASE']['log_extension']

日志工具类封装

import logging
import datetime,os
from config import Conf
from config.Conf import ConfigYamllog_levels = {"info": logging.INFO,"debug": logging.DEBUG,"warning": logging.WARNING,"error": logging.ERROR,
}class Logger:def __init__(self, log_file, log_name, log_level, fh_file_log_level):self.log_file = log_fileself.log_name = log_nameself.log_level = log_levelself.fh_file_log_level = fh_file_log_levelself.logger = logging.getLogger(self.log_name)self.logger.setLevel(log_levels[self.log_level])if not self.logger.handlers:fh_stream = logging.StreamHandler()fh_stream.setLevel(log_levels[self.log_level])formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')fh_stream.setFormatter(formatter)fh_file = logging.FileHandler(self.log_file,encoding='utf-8')  #注意,此处不写encoding='utf-8',会出现导出日志中的中文乱码。fh_file.setLevel(log_levels[self.fh_file_log_level])fh_file.setFormatter(formatter)self.logger.addHandler(fh_stream)self.logger.addHandler(fh_file)log_path = Conf.get_log_path()
current_time = datetime.datetime.now().strftime("%Y-%m-%d")
conf_read = ConfigYaml()
log_extention = conf_read.get_conf_log_extension()
log_file =os.path.join(log_path,current_time+log_extention)
log_level = conf_read.get_conf_log_level()
fh_file_log_level = conf_read.get_conf_fh_file_log_level()def tester_log(log_name = __file__):return Logger(log_file=log_file, log_name=log_name, log_level=log_level, fh_file_log_level=fh_file_log_level).logger

这段代码是一个Python日志记录模块的实现。它使用了logging库来创建和管理日志记录器,并提供了自定义的日志级别和格式。

首先,导入了必要的模块:

  • logging:用于创建和管理日志记录器。
  • datetimeos:用于获取当前时间和构建文件路径。
  • ConfConfigYaml:从配置文件中读取配置信息。

然后,定义了一个名为Logger的类,用于创建和管理日志记录器。该类接受以下参数:

  • log_file:日志文件的路径。
  • log_name:日志记录器的名称。
  • log_level:日志记录器的级别。
  • fh_file_log_level:文件处理器的日志级别。

在类的构造函数中,首先根据传入的参数创建一个日志记录器对象,并设置其级别。然后,如果日志记录器没有处理程序(handler),则创建一个流处理器(StreamHandler)和一个文件处理器(FileHandler)。流处理器将日志输出到控制台,而文件处理器将日志写入指定的文件中。

接下来,定义了一些变量和常量:

  • log_path:日志文件所在的目录路径。
  • current_time:当前时间的字符串表示形式,格式为"YYYY-MM-DD"。
  • conf_read:一个ConfigYaml对象,用于读取配置文件中的配置信息。
  • log_extention:日志文件的扩展名。
  • log_file:完整的日志文件路径。
  • log_level:日志记录器的级别。
  • fh_file_log_level:文件处理器的日志级别。

最后,定义了一个名为tester_log的函数,用于创建并返回一个日志记录器对象。该函数接受一个可选参数log_name,默认值为当前文件的名称。

使用这个模块,你可以创建一个日志记录器对象,并通过调用其方法来记录不同级别的日志消息。例如,可以使用logger.info()logger.debug()logger.warning()logger.error()来记录不同级别的日志消息。

工具类应用

在requests封装类中对requests添加日志

import requests
from utils.LogUtil import tester_log
class Request:def __init__(self):self.log = tester_log()def requests_api(self, url, data=None, json=None, headers=None, cookies=None, method="get"):if method == "get":self.log.debug("发送get请求")r = requests.get(url, data=data, json=json, headers=headers, cookies=cookies)elif method == "post":self.log.debug("发送post请求")r = requests.post(url, data=data, json=json, headers=headers, cookies=cookies)code = r.status_codetry:body = r.json()except Exception as e:body = r.textres = dict()res["code"] = coderes["body"] = bodyreturn resdef get(self, url, **kwargs):return self.requests_api(url, method="get", **kwargs)def post(self, url, **kwargs):return self.requests_api(url, method="post", **kwargs)

调用效果

def login():conf_y = ConfigYaml()r = Request()url_path = conf_y.get_conf_url()url = url_path+'/prod-api/login'data = {"username":"test","password":"49e881218a48a363c35c5215fdc80d3f48d6a17ba0a1f9242c66aebc7ea29c626b26d7ef3bdae00ee9fde85bbf837dcce9f9e4e8f4371d74ff6eaf98ab53d7715996761ef56bff06461e74eb4b3f582949fb3b5281a89fc997a1de35f86a9aad35b87980dcf94e43191293"}res=r.requests_api(url,json=data,method="post")# r = requests.post(url,json=data)print(res)if __name__ == '__main__':login()

在这里插入图片描述在这里插入图片描述

总的来说,Python的logging模块提供了一种灵活的框架,用于发出日志消息。通过使用logging模块,我们可以方便地记录和管理程序的运行情况,从而更好地进行调试和错误追踪。虽然logging模块的基本用法相对简单,但其高级特性却非常强大,可以帮助我们更有效地使用日志记录。因此,对于任何使用Python进行开发的程序员来说,理解和掌握logging模块都是非常必要的。

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

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

相关文章

http请求连接

1、在Info.plist中添加NSAppTransportSecurity类型Dictionary。2、在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES转载于:https://www.cnblogs.com/liuting-1204/p/5919233.html

数据库不完全恢复 以及恢复到测试环境:

sample 1: 1.清空归档日志 RMAN> crosscheck archivelog all; RMAN> delete achivelog all; 2.清空数据文件。 select name from v$datafile; rm v$datafile 3.恢复数据 ##check file date: ##把db数据恢复到:2017-02-05 00:00:00 ls -lt /ngenprdblog/ ls…

centos7安装java6_CentOS7.6安装jdk1.8

2、登录Linux服务器,通过rz命令将jdk导入服务器如果没有rz命令 需要先安装lrzszyum install lrzsz -y3、将jdk压缩包解压到指定路径 -C 指定路径4、配置环境变量编辑/etc/profile文件 在末尾加上以下内容 wq保存退出source /etc/profile文件 使配置文件生效export J…

ubuntu安装wkhtmltopdf

下载安装wkhtmltox系统环境 http://wkhtmltopdf.org/downloads.html wget https://bitbucket.org/wkhtmltopdf/wkhtmltopdf/downloads/wkhtmltox-0.13.0-alpha-7b36694_linux-precise-amd64.deb dpkg -i 安装包名字 当我把它生成pdf的时候我想让每个块都是一页,经过…

人生苦短,我用python——当我在玩python的时候我玩些什么 -

程序的基本思路 用一个txt文件记录电脑的一天内累计使用时间累计使用时间超过若干小时就会自动关机程序开机自动运行 为什么我最后选择了python 想着怎么写、搜资料的时候就发现Java并不适合,虽然不是不能实现,但有好几个问题解决起来都有点麻烦。对我这…

IO流的练习5 —— 读取文件中的字符串,排序后写入另一文件中

需求:已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”     请编写程序读取数据内容,把数据排序后写入ss.txt中。分析:   A:读取文件中的数据   B:把数据存在一个字符串中   C…

java解析未知key json_Gson解析JSON中动态未知字段key的方法

前面一篇文章我介绍了Gson的解析的基本方法。但我们在享受Gson解析的高度封装带来的便利时,有时可能会遇到一些特殊情况,比如json数据中的字段key是动态可变的时候,由于Gson是使用静态注解的方式来设置实体对象的,因此我们很难直接…

Twisted入门教程(5)

2019独角兽企业重金招聘Python工程师标准>>> 第五部分:由Twited支持的诗歌下载服务客户端 你可以从这里从头开始阅读这个系列 抽象地构建客户端 在第四部分中,我们构建了第一个使用Twisted的客户端。它确实能很好地工作,但仍有提高…

Jquery 学习之基础一

1.添加一个CSS类 $("button").click(function(){ $("#div1").addClass("important blue");}); 2.移除一个类 $("button").click(function(){ $("h1,h2,p").removeClass("blue");}); 3.切换类 $("button&…

**print('人生苦短 我爱Python')**

print(‘人生苦短 我爱Python’) 一、变量 **""" 1.代码自上而下执行 2_运算符和表达式.一行一句,不要把多个语句写到一行上,可读性不好 3中文只能出现在引号里,其他地方不能出现中文 4不能随意缩进 """**pr…

java线程提高速度_如何在JAVA中减慢线程速度

我有这个类,我在其中运行10次for循环.该类实现了Runnable接口.现在在main()中我创建了2个线程.现在两个都将循环运行到10.但我想检查每个线程的循环计数.如果t1超过7,则让它休眠1秒,以便让t2完成.但是如何实现这一目标呢?请参阅代码.我尝试但看起来完全愚蠢.只是如何…

(转ORCLE导入导出命令)

oracle数据库导入导出命令!Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份。 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失)。 Oracle有个好处&…

笔记本(华硕UL80VT)软件超频setFSB

Warning !!!If you are a beginner, do not use this software. This software is for power users only. Use "SetFSB.exe" at your own risk.试了setfsb各种版本,基本不能打开。还有官网的免费版,居然不能用,真是很奇怪。 官网&a…

Day01-python编程基础

1. 程序 为了完成某种特定功能,以某种程序设计语言编写的有序指令的集合。程序是指挥cpu工作的“工作手册”。计算机只能执行二进制代码,程序设计语言一般类似英文,想要让计算机理解你写的程序,必须把程序代码“翻译”成计算机能…

pro c 访问 MySQL_Pro*C  OCI  OCCI  及OCI介绍

Pro*C OCIOCCI 这三种都是C/C访问数据库的手段。Pro*C:内嵌SQL,预编译后把内嵌SQL处理为ORACLE标准运行库的调用,然后再象编译一般的C程序一样进行编译、连接、运行。1.proc XXX.pc2.gcc/g XXX.c –lclntsh(PRO*C的预编译,也可直接MAKEFILE…

细说Cookie

http://www.cnblogs.com/fish-li/archive/2011/07/03/2096903.html转载于:https://www.cnblogs.com/benpaodexiaopangzi/p/5933230.html

Node.js~在linux上的部署

我们以centOS为例来说说如何部署node.js环境 一 打开centos,然后开始下载node.js包 curl --silent --location https://rpm.nodesource.com/setup_6.x | bash - yum -y install nodejs 二 安装gcc环境 yum install gcc-c make 安装完成! 三 安装nodejs的npm,这是一个包程序工具…

Django中的class Meta知识点

今天来回顾一下Django中model的class Meta class Main(models.Model):img models.CharField(max_length200) # 图片name models.CharField(max_length100) # 名称trackid models.CharField(max_length16) # 通用idclass Meta:abstract True #抽象类class MainWheel(…

python wheel使用_Python wheel.Wheel方法代碼示例

# 需要導入模塊: from pip import wheel [as 別名]# 或者: from pip.wheel import Wheel [as 別名]def from_line(cls, name, comes_fromNone, prereleasesNone):"""Creates an InstallRequirement from a name, which might be arequirement, directory contai…

英语学习Day1

今天要开始学英语了,我这个人没什么长性,语言这种东西对我来说又是很不擅长的一种技能,那为什么要学英语呢?我要做翻译,也是呵呵了,主要是我想赚钱,这个力量能够支撑我吧,我想。 网上…