纯净版 - python日志模块学习笔记
# logging模块的使用这个模块为应用与库实现了灵活的事件日志系统的函数与类。
使用标准库提供的 logging API 最主要的好处是,所有的 Python 模块都可能参与日志输出,包括你自己的日志消息和第三方模块的日志消息。
## 导入模块
```python
import logging
```
不需要下载,是python的内置模块。
## 简单使用
简单使用可以代替print函数来进行代码的调试。据说日志输出要比print输出要快一些,而且还是线程安全的(即在使用多线程或线程池时输出的结果是有序的)。
```python
logging.debug('调试中...')
logging.info('输出的信息...')
logging.warning('warning!')
logging.error('出现错误!')
logging.critical('严重错误!')
```
运行结果:
只输出了三条信息,这是因为日志是有一个级别的,而默认是warning级别,而比warning级别低的语句就不会输出。
可以自己设置日志级别,来输出全部的日志结果。
```python
logging.basicConfig(level=logging.DEBUG)
```
+ 日志级别(由高到低)
```python
CRITICAL = 50
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10
NOTSET = 0
```
需要使用 Logging 的原因各有不同。这些原因可以根据严重性的不同分为如下几类。
默认的级别时WARNING,意味默认的级别下,显示的日志信息必须时 `>=` WARNING的级别才会进行输出。
日志的记录可以由不同的方式,最简单的是把日志直接输出到console,另外一种就是可以把他们写到文件。
### 将日志输出到文件中
```python
# 输出到日志文件中
logging.basicConfig(level=logging.INFO,
filename='log.txt',
filemode='w')# 默认filemode 是追加写入的方式
logging.debug('调试中...')
logging.info('输出的信息...')
logging.warning('warning!')
logging.error('出现错误!')
logging.critical('严重错误!')
```
运行结果:
有没有发现输出到文件中是不是少了debug的信息😃,细心的朋友肯定能知道是因为设置的日志级别是info, debug级别比info低自然不会输出啦。
来继续学习,仅仅这样可不够😁
### 将日志输出到控制台
废话,不加filename不就好啦。🙄
### 日志输出格式美化
```python
# 美化日志输出
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('这是一条致命的错误信息')
```
运行结果:
更多的format参数:
## 高级应用
在官方文档中有4个重要的对象,分别是logger(记录器)、handler(处理器)、filter(过滤器)、formatter(格式器)。
+ 记录器对象
提供应用程序代码能直接使用的接口
+ 处理器对象
将记录器产生的日志发送到目的地(控制台或文件)
+ 过滤器对象
提供更好的粒度控制,决定哪些日志会被输出
+ 格式化器对象
设置日志内容的组成结构和消息字段
```python
# 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 格式的字符串
'''
```
需求:我们即想在控制台输出日志,也想在文件中输出日志时,高级的做法
```python
# 记录器
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('这是一条致命的错误信息')
```
控制台运行结果:
日志文件结果:
哎,有问题呀,我想要的是控制台输出dubug的级别,日志文件输出info的级别。现在这咋都一样啊。
> 1.这是因为我前面说过,如果同时设置了console_handler的级别和logger的日志级别,则会以logger的级别为准。
>
> 2.而如果不设置logger的日志级别,则会是默认的warning级别。
想要解决,就设置logger的日志级别为最低的debug级别,再分别设置console_handler 和 file_handler的日志级别就好啦。
修改后代码如下:
```python
# 记录器
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` 可被 `Handlers` 和 `Loggers` 用来实现比按层级提供更复杂的过滤操作。
使用场景,在有多个记录器时,如果想指定输出某一个的信息可使用过滤器。
通过记录器名称来设置过滤器,满足我们设置的名称便会被输出
```python
# 记录器
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('这是一条致命的错误信息')
```
运行结果:
可以看到只输出了记录器为 blueballoon 的日志信息。
以上就是本菜鸟的学习笔记和理解,希望对你们有用。 楼主加油~~~~ 学一下看看怎么样 写的很详细 可以可以,楼主加油 怎么应用到代码中,有例子没? cxx0515 发表于 2023-3-29 18:45
怎么应用到代码中,有例子没?
配置好直接就用啦,logging.info('这是输出的内容')跟print一样
非常详细,清晰明了,谢谢分享! 学习了,我的思路还好…………………… 先摩拜一下,做个记号
页:
[1]
2