深入理解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"  #生产环境换成warning
  log_extension: ".log"
  test:
    url: "http://119.3.246.198:64644"

配置文件调用代码更新

import os
from utils.YamlUtil import YamlReader

current = 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_path


def get_config_file():
    return _config_file

def 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 ConfigYaml

log_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_file
        self.log_name = log_name
        self.log_level = log_level
        self.fh_file_log_level = fh_file_log_level

        self.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_code
        try:
            body = r.json()
        except Exception as e:
            body = r.text
        res = dict()
        res["code"] = code
        res["body"] = body
        return res
    def 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.mfbz.cn/a/267000.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

冒泡排序之C++实现

描述 冒泡排序算法是一种简单的排序算法,它通过将相邻的元素进行比较并交换位置来实现排序。冒泡排序的基本思想是,每一轮将未排序部分的最大元素逐个向右移动到已排序部分的最右边,直到所有元素都按照从小到大的顺序排列。 冒泡排序的算法…

前端工程注入版本号

文章目录 一、前言二、webpack三、vite四、最后 一、前言 容器化时代,当页面出现问题时,如果你的新版本有可能已经修复了,那样你再排查它就没有意义了。为什么不一定是最新版本呢?一是可能是缓存作祟,二是可能运维成员…

每日一题——LeetCode860

个人方法: 用change数组保存我们拥有的零钱的数量,change数组只有change[5]、change[10]、change[20]是有效的,其值代表了不同面值的零钱拥有多少张 顾客付了多少钱,先把钱存入零钱数组,然后计算需要找零的金额&…

HarmonyOS - 鸿蒙开发入门

文章目录 HarmonyOS核心资源特性:全场景终端HarmonyOS 版本 HarmonyOS 和 OpenHarmony教程资源开发环境开发工具 - DevEco开发语言 - ArkTS核心框架 - ArkUI 考证 HarmonyOS 开发交流秋秋群:23458659,V : ez-code,期待交流和合作 …

vue 实验报告8 基于Nuxt.js开发一个Vue程序,实现登录和注册切换

一、步骤: 保证node.js版本在14以上 1. 全局安装create-nuxt-app: npm install -g create-nuxt-app2.9.x 2. 创建项目: create-nuxt-app my-nuxt-demo 选项这么选: 然后输入: cd my-nuxt-demo 3. 创建登录和注册页面: 在/pages目录下创建logi…

Docker知识总结

Docker 学习目标: 掌握Docker基础知识,能够理解Docker镜像与容器的概念 完成Docker安装与启动 掌握Docker镜像与容器相关命令 掌握Tomcat Nginx 等软件的常用应用的安装 掌握docker迁移与备份相关命令 能够运用Dockerfile编写创建容器的脚本 能够…

【小沐学写作】Docsify制作在线电子书、技术文档(Docsify + Markdown + node)

文章目录 1、简介2、安装2.1 node2.2 docsify-cli 3、配置3.1 初始化3.2 预览效果3.3 加载对话框3.4 更多页面3.5 侧 栏3.6 自定义导航栏 结语 1、简介 https://docsify.js.org/#/?iddocsify 一个神奇的文档网站生成器。 简单轻巧没有静态构建的 html 文件多个主题 Docsify…

跨平台Markdown编辑软件Typora mac功能介绍

Typora mac是一款跨平台的Markdown编辑器,支持Windows、MacOS和Linux操作系统。它具有实时预览功能,能够自动将Markdown文本转换为漂亮的排版效果,让用户专注于写作内容而不必关心格式调整。Typora Mac版除了支持常见的Markdown语法外&#x…

【测试开发】测试用例讲解

文章目录 目录 文章目录 前言 一、测试用例的基本要素 二、测试用例的设计方法 1.基于需求的设计方法 对日历根据web界面的功能布局分析出的功能框图如下: 继续举一个例子百度云盘非功能测试的案例: 2.等价类 3.边界值 5.正交表 6.场景设计法 7…

leetcode 268. 丢失的数字(优质解法)

链接&#xff1a;268. 丢失的数字 代码: class Solution {public int missingNumber(int[] nums) {int result0;for(int i0;i<nums.length;i){result^i;}for(int i0;i<nums.length;i){result^nums[i];}return result;} } 题解&#xff1a; 本题是比较简单的题&#xff…

c语言:递归法求n的阶乘|练习题

一、题目 输入一个数n&#xff0c;用递归法求n的阶乘 二、思路分析 1、因为n!(n-1)!*n,所以&#xff0c;可以选择用递归法 三、代码截图【带注释】 四、源代码【带注释】 #include <stdio.h> //思路&#xff1a; //因为n!(n-1)!*n,所以&#xff0c;可以选择用递归法 int…

数据资源工具断点续传及下载重试功能

我们可以利用数据资源工具下载各类卫星及矢量数据&#xff0c;具体方法见&#xff1a;Sentinel-2 下载&#xff08;其它数据操作方式类似&#xff09;&#xff0c;但在使用资源工具下载数据时可能会出现由于网络不稳定&#xff0c;网站关闭连接而造成下载的错误或中断。尤其是下…

微信小程序图片压缩原来这么easy!

前言 在日常业务中我们可能会涉及到图片上传功能&#xff0c;现代影像设备大多数的照片都是几MB&#xff0c;甚至几十MB大小&#xff0c;大文件的上传会导致上传进度缓慢、占用云存储空间。所以&#xff0c;我们会根据需求来做图片压缩&#xff0c;将过大的图片文件压缩到指定…

线性回归简介

线性回归简介 1、情景描述2、线性回归 1、情景描述 假设&#xff0c;我们现在有这么一张图&#xff1a; 其中&#xff0c;横坐标x表示房子的面积&#xff0c;纵坐标y表示房价。我们猜想x与y之间存在线性关系&#xff1a; y k x b ykxb ykxb 现在&#xff0c;思考一个问题&…

期末加油站-图像处理期末知识点汇总

第三章&#xff1a;图像增强 一、概念 1.图像增强是通过某种技术有选择地突出对某一具体应用有用的信息&#xff0c;削弱或抑制一些无用的信息。 2. 图像增强处理不是无损处理&#xff0c;不能增加原图像的信息。 3. 图像增强按所处理的对象不同可分为&#xff1a; 灰度图像增…

腾讯面试:SaaS多租户,如何设计?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业网易、美团、字节、如阿里、滴滴、极兔、有赞、希音、百度、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 多租户设计&#xff0c;如何 技术选型&#xff…

Vue+ElementUI+nodejs学生宿舍报修管理系统68ozj

本站是一个B/S模式系统&#xff0c;采用vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得学生宿舍信息管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中…

爬虫字典生成工具,CeWL使用教程

爬虫字典生成工具,CeWL使用教程 1.工具概述2.参数解析3.使用实例1.工具概述 CeWL 是一个 ruby 应用程序,它将给定的 URL 爬到指定的深度,可以选择跟随外部链接,并返回一个单词列表,然后可用于密码破解者 Cewl 是黑客武器库中的强大工具,因为它允许创建有针对性的单词列…

Python学习路线 - Python语言基础入门 - Python基础综合案例 - 数据可视化 - 地图可视化

Python学习路线 - Python语言基础入门 - Python基础综合案例 - 数据可视化 - 地图可视化 基础地图使用基础地图演示基础地图演示 - 视觉映射器 疫情地图-国内疫情地图案例效果数据整理 疫情地图-省级疫情地图省疫情地图 基础地图使用 基础地图演示 代码示例&#xff1a; &quo…