Python:logging日志模块

发布时间 2023-11-09 20:55:59作者: 七落安歌

Python:logging日志模块

1、logging日志的介绍

,在现实生活中,记录日志非常重要,比如:银行转账时会有转账记录;飞机飞行过程中,会有个黑盒子(飞行数据记录器)记录着飞机的飞行过程,那在咱们python程序中想要记录程序在运行时所产生的日志信息,怎么做呢?

可以使用 logging 这个包来完成

记录程序日志信息的目的:

  1. 可以很方便的了解程序的运行情况
  2. 可以分析用户的操作行为、喜好等信息
  3. 方便开发人员检查bug

2、logging日志级别介绍

日志等级可以分为5个,从低到高分别是:

  1. DEBUG
  2. INFO
  3. WARNING
  4. ERROR
  5. CRITICAL

日志等级说明

  • DEBUG:程序调试bug时使用
  • INFO:程序正常运行时使用
  • WARNING: 程序未按预期运行时使用,但并不是错误,如:用户登陆密码输入错误
  • ERROR: 程序出错误时使用,如:IO操作失败
  • CTITICAL: 特别严重的问题,导致程序不能继续运行时使用,如磁盘为空,一般很少使用
  • 默认是WARNING等级,在WARNING及以上等级才记录日志信息
  • 日志从低到高的顺序为:DEBUG<INFO<WARNING<ERROR<CRTICAL

3、logging日志的使用

在logging包中记录日志的方式有两种:

  1. 输出到控制台
  2. 保存到日志文件

日志信息输出到控制台的示例代码:

import logging

logging.debug('这是一个debug级别的日志信息')
logging.info('这是一个info级别的日志信息')
logging.warning('这是一个warning级别的日志信息')
logging.error('这是一个error级别的日志信息')
logging.critical('这是一个critical级别的日志信息')

运行结果:

image-20231025202840608

说明:

  • 日志信息只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING

logging日志等级和输出格式设置:

# 第一步:导入模块
import logging

# 设置日志输出的级别 代表大于等于该级别的信息都可以输出
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')

# 第二步:输出日志信息到终端1
logging.debug('这是一个DEBUG级别的日志信息')
logging.info('这是一个INFO级别的日志信息')
logging.warning('这是一个warning级别的日志信息')
logging.error('这是一个ERROR级别的日志信息')
logging.critical('这是一个critical级别的日志信息')

运行结果:

image-20231025203101871

代码说明:

  • level :设置日志的等级
  • format:表示日志的输出格式,参数说明:
    • %(levelname) s : 打印日志级别名称
    • %(filename) s : 打印当前执行程序名
    • %(lineno)d: 打印日志的当前行号
    • %(asctime)s :打印日志的时间
    • %(message)s : 打印日志信息

logging.basicConfig函数各参数:

  • filename:指定日志文件名;

  • filemode:和file函数意义相同,指定日志文件的打开模式,'w'或者'a';

  • format:指定输出的格式和内容,format可以输出很多有用的信息,

  • datefmt:指定时间格式,同time.strftime();

  • level:设置日志级别,默认为logging.WARNNING;

  • stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,stream和filename同时指定时,stream被忽略;

4、日志信息保存到文件中

代码示例:

import logging

# 设置日志输出级别和输出格式
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    filename='logging.txt',  # 写入到logging.txt文件中
                    filemode='w'  # 写入的模式
                    )

logging.debug('这是一个DEBUG级别的日志信息')
logging.info('这是一个INFO级别的日志信息')
logging.warning('这是一个WARNING级别的日志信息')
logging.error('这是一个ERROR级别的日志信息')
logging.critical('这是一个CRITICAL级别的日志信息')
  • 如果出现中文乱码问题,调整代码如下:
import logging


f = open('logging1.txt', 'a', encoding='utf-8')
# 设置日志输出级别和输出格式
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    # filename='logging.txt',  # 写入到logging.txt文件中
                    # filemode='w'  # 写入的模式
                    stream=f
                    )

logging.debug('这是一个DEBUG级别的日志信息')
logging.info('这是一个INFO级别的日志信息')
logging.warning('这是一个WARNING级别的日志信息')
logging.error('这是一个ERROR级别的日志信息')
logging.critical('这是一个CRITICAL级别的日志信息')

运行结果:image-20231025211208113

5、logging日志在Web项目中应用

# coding=gbk
from fastapi import FastAPI
from fastapi import Response
import uvicorn
import logging

app = FastAPI()

# 配置logging日志信息
f = open('web项目.log', 'w', encoding='utf-8')
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    # filename='web项目.log',
                    # filemode='a'
                    stream=f
                    )


# 收发数据 请求html中的图片资源
@app.get("/images/{path}")
def get_pic(path: str):
    with open(f"source/images/{path}", 'rb') as f:
        data = f.read()
    # 打log
    logging.info('访问了' + path)
    # logging.error()
    # 响应数据
    return Response(content=data, media_type="jpg")


# 收发数据 请求页面的数据
@app.get('/{path}')
def request_html(path: str):
    with open(f'source/html/{path}', 'rb') as f:
        data = f.read()
    logging.info('访问了' + path)
    # logging.error()
    # 响应数据和数据格式
    return Response(content=data, media_type='text/html')


# 添加一个,如果没有输入要访问具体的页面,默认打开主页面
@app.get('/')
def main():
    with open('source/html/index.html', 'rb') as f:
        data = f.read()
    # 访问主页,打log
    logging.info('访问了html主页')
    # logging.error()
    return Response(content=data, media_type='text/html')


# 启动服务器 参数:FastAPI框架对象、IP地址、端口号
uvicorn.run(app, host='127.0.0.1', port=9000)

运行结果:

image-20231026163737758

6、logging中的补充

常用函数

函数 说明
logging.debug(msg, *args, **kwargs) 创建一条严重级别为DEBUG的日志记录
logging.info(msg, *args, **kwargs) 创建一条严重级别为INFO的日志记录
logging.warning(msg, *args, **kwargs) 创建一条严重级别为WARNING的日志记录
logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录
logging.critical(msg, *args, **kwargs) 创建一条严重级别为CRITICAL的日志记录
logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录
logging.basicConfig(**kwargs) 对root logger进行一次性配置
  • 不推荐使用basicConfig对日志等级进行自我创作,因为会影响代码的移植性,代码在别人那里容易起冲突

Formatters格式

属性 格式 描述
asctime %(asctime)s 日志产生的时间,默认格式为msecs2003-07-0816:49:45,896
msecs %(msecs)d 日志生成时间的亳秒部分
created %(created)f time.tme)生成的日志创建时间戳
message %(message)s 具体的日志信息
filename %(filename)s 生成日志的程序名
name %(name)s 日志调用者
funcname %( funcname)s 调用日志的函数名
levelname %(levelname)s 日志级別( DEBUG,INFO, WARNING, 'ERRORCRITICAL)
levene %( leveling)s 日志级别对应的数值
lineno %(lineno)d 日志所针对的代码行号(如果可用的话)
module %( module)s 生成日志的模块名
pathname %( pathname)s 生成日志的文件的完整路径
process %( (process)d 生成日志的进程D(如果可用)
processname (processname)s 进程名(如果可用)
thread %(thread)d 生成日志的线程D(如果可用)
threadname %( threadname)s 线程名(如果可用)