吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1060|回复: 14
收起左侧

[学习记录] 纯净版 - python日志模块学习笔记

  [复制链接]
redballoon 发表于 2023-3-29 18:02

logging模块的使用

这个模块为应用与库实现了灵活的事件日志系统的函数与类。

使用标准库提供的 logging API 最主要的好处是,所有的 Python 模块都可能参与日志输出,包括你自己的日志消息和第三方模块的日志消息。

导入模块

import logging

不需要下载,是python的内置模块。

简单使用

简单使用可以代替print函数来进行代码的调试。据说日志输出要比print输出要快一些,而且还是线程安全的(即在使用多线程或线程池时输出的结果是有序的)。

logging.debug('调试中...')
logging.info('输出的信息...')
logging.warning('warning!')
logging.error('出现错误!')
logging.critical('严重错误!')

运行结果:

1.png

只输出了三条信息,这是因为日志是有一个级别的,而默认是warning级别,而比warning级别低的语句就不会输出。

可以自己设置日志级别,来输出全部的日志结果。

logging.basicConfig(level=logging.DEBUG)  
  • 日志级别(由高到低)

    CRITICAL = 50
    ERROR = 40
    WARNING = 30
    INFO = 20
    DEBUG = 10
    NOTSET = 0

需要使用 Logging 的原因各有不同。这些原因可以根据严重性的不同分为如下几类。

image-20230317233842628.png

默认的级别时WARNING,意味默认的级别下,显示的日志信息必须时 >= WARNING的级别才会进行输出。
日志的记录可以由不同的方式,最简单的是把日志直接输出到console,另外一种就是可以把他们写到文件。

将日志输出到文件中

# 输出到日志文件中
logging.basicConfig(level=logging.INFO,
                    filename='log.txt',
                    filemode='w')  # 默认filemode 是追加写入的方式
logging.debug('调试中...')
logging.info('输出的信息...')
logging.warning('warning!')
logging.error('出现错误!')
logging.critical('严重错误!')

运行结果:

image-20230318000710973.png

有没有发现输出到文件中是不是少了debug的信息😃,细心的朋友肯定能知道是因为设置的日志级别是info, debug级别比info低自然不会输出啦。

来继续学习,仅仅这样可不够😁

将日志输出到控制台

废话,不加filename不就好啦。🙄

日志输出格式美化

# 美化日志输出
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(lineno)s >>> %(message)s',  # %()s 是固定格式
                    datefmt='%Y-%m-%d %H:%M:%S')
logging.info('这是一条正常信息')
logging.warning('这是一条警告信息')
logging.error('这是一条错误信息')
logging.critical('这是一条致命的错误信息')

运行结果:

image-20230318002359522.png

更多的format参数:

image-20230318122510824.png

高级应用

在官方文档中有4个重要的对象,分别是logger(记录器)、handler(处理器)、filter(过滤器)、formatter(格式器)。

  • 记录器对象

    提供应用程序代码能直接使用的接口

  • 处理器对象

    将记录器产生的日志发送到目的地(控制台或文件)

  • 过滤器对象

    提供更好的粒度控制,决定哪些日志会被输出

  • 格式化器对象

    设置日志内容的组成结构和消息字段

2.jpg

# logger记录器
'''
1. 提供应用程序的调用接口
logger = logging.getLogger(__name__)  默认是root, 也可以自定义其他
2. 决定日志记录的级别
logger.setLevel()
3. 将日志内容传递到相关联的handler中
logger.addHandler() 和 logger.removeHandler()
'''

# handler处理器
'''
# 最常用的两个 StreamHandler 和 FileHandler
# 所有的Handler处理器都可以使用 setFormatter() 来设置当前Handler对象的消息格式
'''

# formatter格式器
'''
ft = logging.Formatter(fmt=None, datefmt=None, style='%')
style参数默认为%, 这表示 %(<dictionary key>)s 格式的字符串
'''

需求:我们即想在控制台输出日志,也想在文件中输出日志时,高级的做法

# 记录器
logger = logging.getLogger('redballoon')
logger.setLevel(level=logging.INFO)
# print(logger)

# 处理器
# 定义StreamHandler输出到控制台
console_handler = logging.StreamHandler()
#定义FileHandler输出到日志文件
file_handler = logging.FileHandler(filename='2023-3-18-log.txt')

console_handler.setLevel(level=logging.DEBUG)
# 如果没有给handler设置日志级别,将使用logger的日志级别
# file_handler.setLevel(level=logging.INFO)
# * 若是设置了logger记录器的日志级别,又设置了console_handler的日志级别,则会以logger的级别为准。

# 格式化器
fmt = logging.Formatter('%(asctime)s %(levelname)s %(filename)s:%(lineno)s >>> %(message)s')

# 给处理器添加格式
console_handler.setFormatter(fmt)
file_handler.setFormatter(fmt)

# 给记录器添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)

logger.debug('这是调试的信息')
logger.info('这是一条正常信息')
logger.warning('这是一条警告信息')
logger.error('这是一条错误信息')
logger.critical('这是一条致命的错误信息')

控制台运行结果:

image-20230318012145740.png

日志文件结果:

image-20230318012221760.png

哎,有问题呀,我想要的是控制台输出dubug的级别,日志文件输出info的级别。现在这咋都一样啊。

1.这是因为我前面说过,如果同时设置了console_handler的级别和logger的日志级别,则会以logger的级别为准。

2.而如果不设置logger的日志级别,则会是默认的warning级别。

想要解决,就设置logger的日志级别为最低的debug级别,再分别设置console_handler 和 file_handler的日志级别就好啦。

修改后代码如下:

# 记录器
logger = logging.getLogger('redballoon')
logger.setLevel(level=logging.DEBUG)

# 处理器
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler(filename='2023-3-18-log.txt')

console_handler.setLevel(level=logging.DEBUG)
# 如果没有给handler设置日志级别,将使用logger的日志级别
file_handler.setLevel(level=logging.INFO)
# * 若是设置了logger记录器的日志级别,又设置了console_handler的日志级别,则会以logger的级别为准。

# 格式化器
fmt = logging.Formatter('%(asctime)s %(levelname)s %(filename)s:%(lineno)s >>> %(message)s')

# 给处理器添加格式
console_handler.setFormatter(fmt)
file_handler.setFormatter(fmt)

# 给记录器添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)

logger.debug('这是调试的信息')
logger.info('这是一条正常信息')
logger.warning('这是一条警告信息')
logger.error('这是一条错误信息')
logger.critical('这是一条致命的错误信息')
  • 过滤器的使用

Filters 可被 HandlersLoggers 用来实现比按层级提供更复杂的过滤操作。

使用场景,在有多个记录器时,如果想指定输出某一个的信息可使用过滤器。

通过记录器名称来设置过滤器,满足我们设置的名称便会被输出

# 记录器
logger1 = logging.getLogger('redballoon')
logger2 = logging.getLogger('blueballoon')
logger1.setLevel(level=logging.DEBUG)
# logger2.setLevel(level=logging.DEBUG)  不设置让他为默认级别

# 处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(level=logging.DEBUG)

# 过滤器  满足过滤器设置的记录器名称便会被输出
# 定义一个过滤器
flt = logging.Filter('blueballoon')
# 关联过滤器
console_handler.addFilter(flt)

# 格式化器
fmt = logging.Formatter('%(name)-12s | %(asctime)s %(levelname)s %(filename)s:%(lineno)s >>> %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',)

# 给处理器添加格式
console_handler.setFormatter(fmt)

# 给记录器添加处理器
logger1.addHandler(console_handler)
logger2.addHandler(console_handler)

logger1.debug('这是调试的信息')
logger1.info('这是一条正常信息')
logger1.warning('这是一条警告信息')
logger1.error('这是一条错误信息')
logger1.critical('这是一条致命的错误信息')
print('=========================================')
logger2.debug('这是调试的信息')
logger2.info('这是一条正常信息')
logger2.warning('这是一条警告信息')
logger2.error('这是一条错误信息')
logger2.critical('这是一条致命的错误信息')

运行结果:

3.png

可以看到只输出了记录器为 blueballoon 的日志信息。

以上就是本菜鸟的学习笔记和理解,希望对你们有用。

image-20230318002635412.png

免费评分

参与人数 3吾爱币 +3 热心值 +3 收起 理由
小傲宇 + 1 + 1 谢谢@Thanks!
mtDNA + 1 + 1 我很赞同!
wanfon + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

johnversion 发表于 2023-3-29 18:08
楼主加油~~~~
yitiaocaoyu 发表于 2023-3-29 18:29
flyikun 发表于 2023-3-29 18:33
aceronethree 发表于 2023-3-29 18:38
可以可以,楼主加油
cxx0515 发表于 2023-3-29 18:45
怎么应用到代码中,有例子没?
 楼主| redballoon 发表于 2023-3-29 19:05
cxx0515 发表于 2023-3-29 18:45
怎么应用到代码中,有例子没?

配置好直接就用啦,logging.info('这是输出的内容')跟print一样
brooks 发表于 2023-3-29 19:33
非常详细,清晰明了,谢谢分享!
xiaoyaowolf 发表于 2023-3-29 19:37
学习了,我的思路还好……………………
t5656 发表于 2023-3-29 20:15
先摩拜一下,做个记号
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-23 16:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表