当前位置: 首页 > news >正文

logging.config 日志模块

logging 日志模块

简单应用:

import logging
logging.warning('警告!')  # 输出结果:
WARNING:root:警告!

1. 日志等级

- debug   	调试 10 最详细的日志信息,典型应用场景是 问题诊断
- info    	普通信息 20 信息详细程度仅次于DEBUG,用于确认一切都是按照我们预期的那样进行工作
- warning 	警告信息 30 当某些不期望的事情发生时记录的信息,但是此时应用程序还是正常运行的
- error 	错误信息 40 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
- critical	严重错误信息 50 当发生严重错误,导致应用程序不能继续运行时记录的信息

2. 日志形式

一条日志信息一般包括以下几点:

  • 事件发生的时间
  • 事件发生的位置
  • 事件的严重程度 – 日志级别(DEBUG -> INFO -> WARNING -> ERROR -> CRITICAL)
  • 事件的内容

2.1 logging模块的四大组件

组件说明
Logger日志记录器:提供应用程序代码直接使用的接口
Handler日志处理器:用于将日志记录发送到指定的目的位置
Filter日志过滤器:提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出(其它的日志记录将会被忽略)
Formatter日志格式化:用于控制日志信息的最终输出格式

这些组件之间的关系描述:

  • 不同的处理器(handler)可以将日志输出到不同的位置;
  • 日志器(logger)可以设置多个处理器(handler)将同一条日志记录输出到不同的位置;
  • 每个处理器(handler)都可以设置自己的过滤器(filter)实现日志过滤,从而只保留感兴趣的日志;
  • 每个处理器(handler)都可以设置自己的格式器(formatter)实现同一条日志以不同的格式输出到不同的地方。

简单点说就是:日志器(logger)是入口,真正干活儿的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。

2.1.1 Logger日志记录器

Logger对象有3个任务要做:

  • 向应用程序代码暴露几个方法,使应用程序可以在运行时记录日志消息;
  • 基于日志严重等级(默认的过滤设施)或filter对象来决定要对哪些日志进行后续处理;
  • 将日志消息传送给所有感兴趣的日志handlers。

Logger对象最常用的方法分为两类:配置方法消息发送方法

最常用的配置方法如下:

方法描述
Logger.setLevel()设置日志器将会处理的日志消息的最低严重级别
Logger.addHandler() 和 Logger.removeHandler()为该logger对象添加 和 移除一个handler对象
Logger.addFilter() 和 Logger.removeFilter()为该logger对象添加 和 移除一个filter对象

logger对象配置完成后,可以使用下面的方法来创建日志记录:

方法描述
Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), Logger.critical()创建一个与它们的方法名对应等级的日志记录
Logger.exception()创建一个类似于Logger.error()的日志消息
Logger.log()需要获取一个明确的日志level参数来创建一个日志记录

一个Logger对象呢?一种方式是通过Logger类的实例化方法创建一个Logger类的实例,但是我们通常都是用第二种方式–logging.getLogger()方法。

logging.getLogger()方法有一个可选参数name,该参数表示将要返回的日志器的名称标识,如果不提供该参数,则其值为’root’。若以相同的name参数值多次调用getLogger()方法,将会返回指向同一个logger对象的引用。

多次使用注意不能创建多个logger,否则会出现重复输出日志现象。

2.1.2 Handler 日志处理器

Handler对象的作用是(基于日志消息的level)将消息分发到handler指定的位置(文件、网络、邮件等)。Logger对象可以通过addHandler()方法为自己添加0个或者更多个handler对象。比如,一个应用程序可能想要实现以下几个日志需求:

  • 1)把所有日志都发送到一个日志文件中;
  • 2)把所有严重级别大于等于error的日志发送到stdout(标准输出);
  • 3)把所有严重级别为critical的日志发送到一个email邮件地址。这种场景就需要3个不同的handlers,每个handler复杂发送一个特定严重级别的日志到一个特定的位置。
  Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略Handler.setFormatter():给这个handler选择一个格式Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

需要说明的是,应用程序代码不应该直接实例化和使用Handler实例。因为Handler是一个基类,它只定义了素有handlers都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。下面是一些常用的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’信息的出现。
2.1.3 Formater 日志格式化

Formater对象用于配置日志信息的最终顺序、结构和内容。与logging.Handler基类不同的是,应用代码可以直接实例化Formatter类。另外,如果你的应用程序需要一些特殊的处理行为,也可以实现一个Formatter的子类来完成。

Formatter类的构造方法定义如下:

logging.Formatter.__init__(fmt=None, datefmt=None, style='%')

可见,该构造方法接收3个可选参数:

  • fmt:指定消息格式化字符串,如果不指定该参数则默认使用message的原始值
  • datefmt:指定日期格式字符串,如果不指定该参数则默认使用"%Y-%m-%d %H:%M:%S"
  • style:Python 3.2新增的参数,可取值为 ‘%’, ‘{‘和 ‘$’,如果不指定该参数则默认使用’%’

一般直接用logging.Formatter(fmt, datefmt)

日志格式参数:

 |  %(name)s            Name of the logger (logging channel) 记录器的名称|  %(levelno)s         Numeric logging level for the message (DEBUG, INFO,|                      WARNING, ERROR, CRITICAL) 数字形式的日志记录级别|  %(levelname)s       Text logging level for the message ("DEBUG", "INFO",|                      "WARNING", "ERROR", "CRITICAL") 日志记录级别的文本名称|  %(pathname)s        Full pathname of the source file where the logging|                      call was issued (if available) 执行日志记录调用的源文件的路径名称|  %(filename)s        Filename portion of pathname 执行日志记录调用的源文件的文件名称|  %(module)s          Module (name portion of filename) 执行日志记录调用的模块名称|  %(lineno)d          Source line number where the logging call was issued|                      (if available) 执行日志记录调用的行号|  %(funcName)s        Function name 执行日志记录调用的函数名称|  %(created)f         Time when the LogRecord was created (time.time()|                      return value) 执行日志记录的时间|  %(asctime)s         Textual time when the LogRecord was created 日期和时间|  %(msecs)d           Millisecond portion of the creation time 毫秒部分|  %(relativeCreated)d Time in milliseconds when the LogRecord was created,|                      relative to the time the logging module was loaded|                      (typically at application startup time)|  %(thread)d          Thread ID (if available) 线程ID|  %(threadName)s      Thread name (if available) 线程名称|  %(process)d         Process ID (if available) 进程ID|  %(message)s         The result of record.getMessage(), computed just as|                      the record is emitted 记录的消息

3. 日志记录一般流程

1、创建一个logger

2、设置下logger的日志的等级

3、创建合适的Handler(FileHandler要有路径)

4、设置下每个Handler的日志等级

5、创建下日志的格式

6、向Handler中添加上面创建的格式

7、将上面创建的Handler添加到logger中

8、打印输出logger.debug\logger.info\logger.warning\logger.error\logger.critical

3.1 示例

import os
import logging
from logging import StreamHandler, FileHandler, Formatter, Filterdef logs(*args):log_name, path, msg = args# 拼接写入路径和文件filename = os.path.join(path, '{}_log.txt'.format(log_name))# 设置日志名logger = logging.getLogger(log_name)# 设置记录器的信息等级:DEBUG -> INFO -> WARNING -> ERROR -> CRITICALlogger.setLevel(logging.INFO)  # 记录器可以记录INFO及以上等级信息# 创建日志处理器1handler1 = StreamHandler()   # 流处理器,标准输出控制台#  设置级别和格式handler1.setLevel(logging.INFO)handler1.setFormatter(Formatter(fmt='[ %(asctime)s - %(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S'))# 创建日志处理器2handler2 = FileHandler(filename, encoding='utf-8')   # 输出至文件handler2.setLevel(logging.INFO)handler2.setFormatter(Formatter(fmt="[ %(asctime)s - %(levelname)s > line %(lineno)s at %(pathname)s > ] %(message)s",datefmt='%Y-%m-%d %H:%M:%S'))# 向记录器添加处理器logger.addHandler(handler1)logger.addHandler(handler2)# # 输出信息logger.info(msg)# return loggerif __name__ == '__main__':path = r'D:\02_project\Test\pingmesh'logs('om', path, '天气太热')

3.2 logging.config 实现日志记录

import os
import **logging.config**def logging_config():# 定义字典LOGGING_CONFIG = {"version": 1,"disable_existing_logger": True,  # 删除已存在其他日志的Handler"formatters": {"standard": {# "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}","format": "{levelname} {asctime} {filename} ----> {message}","style": "{",},"simple": {"format": "%(levelname)s  %(message)s","style": "%",},"test": {"format": "$levelname  $message","style": "$",},},"handlers": {"console": {"class": "logging.StreamHandler","formatter": "simple",},"sms_file": {"class": "logging.handlers.TimedRotatingFileHandler","formatter": "standard","filename": os.path.join('logs', 'sms.log'),"when": 'D',  # 根据天拆分日志"interval": 1,  # 1天"backupCount": 3,  # 备份个数"encoding": "utf-8",},# "error_file": {#     "class": "logging.handlers.TimedRotatingFileHandler",#     "formatter": "standard",#     "filename": os.path.join('logs', 'error.log'),#     "when": 'D',  # 根据天拆分日志#     "interval": 1,  # 1天#     "backupCount": 3,  # 备份个数#     "encoding": "utf-8",# },},"loggers": {"sms": {"handlers": ["sms_file", ],  # 意味着通过sms的loggers,写日志时, 级别 -> info 且 会写入到sms_file文件中"level": "INFO","propagate": False  # 通过sms写日志时,同时也会找到他的父亲},# "error": {#     "handlers": ["error_file", ],#     "level": "ERROR",#     "propagate": True# },},# "root": {#     "handlers": ["console", ],#     "level": "ERROR",#     "propagate": True# },}#  2.根据自定义对logging进行配置logging.config.dictConfig(LOGGING_CONFIG)return loggingif __name__ == '__main__':logging = logging_config()# 3.写日志logger_object = logging.getLogger("sms")logger_object.info("今天太热了")# logger_object = logging.getLogger("error")# logger_object.error(666666)

注意:

存在一个问题:日志文件不能修改或删除,否则就无法继续记录日志

相关文章:

logging.config 日志模块

logging 日志模块 简单应用: import logging logging.warning(警告!) # 输出结果: WARNING:root:警告!1. 日志等级 - debug 调试 10 最详细的日志信息,典型应用场景是 问题诊断 - info 普通信息 20 信息详细…...

win10+ vs2017用cmake编译geos3.5.1

参考教程:使用CMake编译Geos3.5.0_cmake geos-CSDN博客 注意事项: 报错:在使用cmake编译geos-3.5.1的时候,会出现报错: CMake Error at CMakeLists.txt:330 (include): include could not find load file GenerateSou…...

优化数据分析——理解与运用各类指标

写在开头 数据分析在当今信息时代扮演着至关重要的角色,而指标则是我们理解数据、揭示模式、支持决策的关键工具。本文将深入讨论各类指标的应用场景和解读方法,以帮助更全面、深入地理解数据。 1. 中心趋势指标 1.1 均值:更深层次的理解 …...

JS实现数字千分位分割(手写纯享版)

简介 在前端开发中,我们经常需要对数字进行格式化,其中一种常见的需求就是将数字表示为千分位格式,以提高可读性。本文将介绍如何使用 JavaScript 实现一个简单而有效的千分位格式化函数。 千分位格式化的需求 千分位格式化是一种将数字中…...

入门指南:介绍Python库——Pandas

个人网站 本文首发于公众号小肖学数据分析 Pandas是一个功能强大、灵活易用的Python数据处理库。 无论你是数据分析师、数据科学家还是Python初学者,掌握Pandas都将为你提供高效、便捷的数据处理和分析能力。 本文将为你详细介绍Pandas的基本概念、常用功能和使…...

数据库语句执行流程(查询原理)SQL

SQL作为一种数据库编程语言,其执行过程大致为,终端上输入SQL语句 会传输到数据库服务器,然后SQL语句在服务器内经过解析器的检查和翻译,优化器的执行效率提升,在执行器中通过存储引擎提供的数据给出结果。详细过程如下…...

FileReader与URL.createObjectURL实现图片、视频上传预览

之前做图片、视频上传预览常用的方案是先把文件上传到服务器,等服务器返回文件的地址后,再把该地址字符串赋给img或video的src属性,这才实现所谓的文件预览。实际上这只是文件“上传后再预览”,这既浪费了用户的时间,也…...

基于python+Django+SVM算法模型的文本情感识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介1. 简介2. 技术栈3. 系统架构4. 关键模块介绍5. 如何运行 二、功能三、系统四. 总结 一项目简介 # 基于 Python Django SVM 算法模型的文本情感识别系统介…...

数据结构之栈与队列习题详解解析

个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.概念题…...

C++ 动态规划 DP教程 (一)思考过程(*/ω\*)

动态规划是一种思维方法,大家首先要做的就是接受这种思维方法,认同他,然后再去运用它解决新问题。 动态规划是用递推的思路去解决问题。 首先确定问题做一件什么事情? 对这件事情分步完成,分成很多步。 如果我们把整件…...

【python基础(九)】文件和异常详解:使用、读取、写入、追加、保存用户的信息,以及优雅的处理异常

文章目录 一. 从文件中读取数据1. 读取整个文件2. 文件路径3. 逐行读取4. 创建一个包含文件各行内容的列表 二. 写入文件1. 写入空文件2. 写入多行3. 附加到文件 三. 异常1. 处理ZeroDivisionError异常2. 使用try-except代码块3. try-except-else ing4. 处理FileNotFoundError异…...

详解C语言中的指针数组和数组指针

指针数组和数组指针是 C 语言中比较常见的两种类型。它们虽然名字很相似,但是含义、用法以及指向类型都不同,需要分开理解。 指针数组 指针数组是一个数组,其中每个元素都是一个指针。这些指针可以指向不同类型的数据,也可以指向…...

【done】剑指offer18:删除链表指定节点

力扣,https://leetcode.cn/problems/shan-chu-lian-biao-de-jie-dian-lcof/description/ // 自己写的答案 class Solution {public ListNode deleteNode(ListNode head, int val) {if (head null) {return null;}if (head.val val) {return head.next;}ListNode …...

图形编辑器开发:缩放和旋转控制点

大家好,我是前端西瓜哥。好久没写图形编辑器开发的文章了。 今天来讲讲控制点。它是图形编辑器的不可缺少的基础功能。 控制点是吸附在图形上的一些小矩形和圆形点击区域,在控制点上拖拽鼠标,能够实时对被选中进行属性的更新。 比如使用旋…...

【2023 云栖】阿里云田奇铣:大模型驱动 DataWorks 数据开发治理平台智能化升级

云布道师 本文根据 2023 云栖大会演讲实录整理而成,演讲信息如下: 演讲人:田奇铣 | 阿里云 DataWorks 产品负责人 演讲主题:大模型驱动 DataWorks 数据开发治理平台智能化升级 随着大模型掀起 AI 技术革新浪潮,大数…...

Rust语言入门教程(二) - 变量与作用域

变量与作用域 变量的声明与初始化 Rust的基本语法格式如下: fn main(){let bunnies 2; }语句以分号结尾,用花括号包含语句块。 Rust的语法其实借鉴了很多其他的语言,比如C语言和Python, 所以变量定义的格式看起来也跟很多我们…...

芯知识 | Flash可更换声音语音芯片—引领音频IC技术革新的新篇章

随着科技的飞速发展,人们对于电子产品的音频性能要求越来越高。在这种背景下,Flash可更换声音语音芯片应运而生,成为音频技术领域的一颗璀璨明星。本文将详细介绍Flash可更换声音语音芯片的特点、优势以及应用场景,展望其在未来科…...

合共软件创新亮相:第102届上海电子展成就技术新篇章

2023年,第102届中国(上海)电子展活动在全球瞩目中圆满落幕。作为下半年华东地区最具影响力的电子展会,此次盛会吸引了来自全球的600家领先企业,共同探讨电子元器件行业的最新发展成果和趋势。 本届展会围绕核心先导元器…...

Ubuntu20.04清理垃圾vscode缓存

使用VM虚拟机安装了Ubuntu系统,主目录空间越来越小,硬盘扩容之后很快又空间不足,甚至出现了开机卡黑屏的情况,这里记录一下解决过程。 1 重新开机进入系统 状态:卡到了开机黑屏状态,左上角有一条小横杠 原…...

网络数据结构skb_buff原理

skb_buff基本原理 内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体,而是通过增加协议头和移动指针来操作的。如果是从L4传输到L2,则是通过往sk_buff结构体中增加该层协议头来操作;如果是从L4到L2,则是通过移动sk_…...

快速免费解决B站视频无法播放问题:m4s-converter终极指南

快速免费解决B站视频无法播放问题:m4s-converter终极指南 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经在B站缓存了珍贵…...

超越Agent:当服务器不让装软件时,用Zabbix SNMP监控的3种高阶玩法与模板优化

超越Agent:Zabbix SNMP监控在受限环境下的高阶实践 想象一下这样的场景:凌晨三点,你被告警电话惊醒,一台关键业务服务器出现性能问题。但当你准备登录排查时,却发现这台服务器严格禁止安装任何监控Agent——这是许多运…...

如何在3分钟内安全导出浏览器Cookie:Get cookies.txt LOCALLY完全指南

如何在3分钟内安全导出浏览器Cookie:Get cookies.txt LOCALLY完全指南 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 你是否曾经需要将…...

从11kHz振荡到50Hz干扰:一个运放偏置电流测试电路的血泪调试史

从11kHz振荡到50Hz干扰:一个运放偏置电流测试电路的血泪调试史 当示波器屏幕上突然出现11kHz的正弦波时,我盯着面包板上那个看似简单的运放测试电路,意识到自己正面临硬件工程师最熟悉的陌生敌人——意外振荡。这个本该安静测量pA级偏置电流的…...

Dify权限体系深度拆解:5大高危配置漏洞与7步零信任加固方案

第一章:Dify权限体系核心架构与设计哲学Dify 的权限体系并非简单的 RBAC(基于角色的访问控制)叠加,而是融合了多租户隔离、资源粒度策略、动态上下文评估与声明式策略语言(Rego)的混合型授权模型。其设计哲…...

智联e学自动刷课,智联e学自动播放

众所周知,“智联 e 学”不能自动播放。自己没事做了一个基于 Python Selenium 开发的智联 e 学自动挂机播放辅助工具。之前有分享过 python 版本,但是比较繁琐,需要自己安装 python 和 selenium 等。今天闲来无事封装成了 exe,内…...

5分钟学会Llama Factory:可视化操作,轻松实现大模型训练与微调

5分钟学会Llama Factory:可视化操作,轻松实现大模型训练与微调 1. 为什么选择Llama Factory? 在人工智能领域,大语言模型(LLM)的训练和微调一直是技术门槛较高的工作。传统方法需要编写大量代码、处理复杂的环境配置&#xff0c…...

终极指南:3步实现Zotero浏览器插件完美文献抓取

终极指南:3步实现Zotero浏览器插件完美文献抓取 【免费下载链接】zotero-connectors Chrome, Firefox, Edge, and Safari extensions for Zotero 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-connectors Zotero Connectors作为一款强大的开源浏览器…...

react-native-shared-element 性能优化技巧:避免闪烁和提升动画流畅度

react-native-shared-element 性能优化技巧:避免闪烁和提升动画流畅度 【免费下载链接】react-native-shared-element Native shared element transition "primitives" for react-native 💫 项目地址: https://gitcode.com/gh_mirrors/re/re…...

告别Keil,用VSCode+ARM-GCC+OpenOCD给STM32开发换种活法(保姆级配置流程)

从Keil到VSCode:STM32开发者的现代化工具链迁移指南 当STM32开发者第一次打开VSCode,看到那个简洁的蓝色图标时,往往会感到既兴奋又忐忑。兴奋的是终于可以摆脱传统IDE的束缚,忐忑的是面对空白的工作区不知从何开始。这正是我从Ke…...