python-logging使用

本文介绍python中logging模块使用

前言

python日志模块使用,为项目添加日志监控

日志

日志级别

1
2
3
4
5
6
7
8
9
10
11
DEBUG   -- 调试信息

INFO -- 记录关键流程信息,是否走通或终端

WARNING -- 告警信息,比如超时,错误可能

ERROR -- 错误信息,程序会因为此错误导致某些功能不能正常运行

CRITICAL-- 影响整个程序运行的错误信息

FATAL -- 记录影响整个程序运行的错误信息/程序退出的信息

日志分级是为了开发和测试以及定位错误的效率,比如正常的开发流程是 dev环境 -> test环境 -> online环境
通过日志分级,可以根据配置在不同的环境只打印出某些级别以上的日志代码,能在不影响线上运行效率的情况下,提高开发/测试/错误定位的效率
举个例子

1
2
3
4
5
6
7
8
9
10
dev  - DEBUG及以上的消息全部打印,能清楚地看到一次请求中所有的日志链路(查看一些关键步骤的结果的值)

test - INFO及以上的消息全部打印,本地测通之后,在测试环境只需要知道整个处理流程的步骤,到哪一段的日志中断,那么可以快速定位到,
再回到dev环境定位

online - 一般看情况选择后四种
若是依赖的上游服务过多,可以为这些服务添加超时报警类似的信息,WARNING
遇到接口挂掉的情况,但不影响程序运行,降级处理,ERROR
影响程序的正常运行,使某段代码给你中断,比如空指针异常等,CRITICAL
某段代码的功能影响了这个程序的运行,一般非逻辑错误,如:初始化失败|系统内存不足 等系统级别错误下使用,FATAL

一般我们在线上系统很难实时去定位系统,在成千上万的请求中,几乎不可能找到你要的那个request,所以记录错误也是一个很重要的一环,方便在遇到错误之后(第一件事情肯定是先回滚减少损失)快速发现错误,并修复它重新测试上线。

日志分块/写入格式

日志分块:
  一般看实际情况,首先,你要确定你的日志量大小,正常来说我们设定成小时级别是比较方便文件分块,一天24份日志文件,当你需要使用或备份时,拉取文件的大小和次数相对比较合理
  若你单台服务及其的qps及其大,以至于每分钟都能生成很大的日志(几百MB,GB级甚至更多),那么推荐你的日志级别设定成分钟级别
  若你的程序只是每天跑一次(定时脚本等),也可以设定成天级别的

写入格式:
  看个人习惯,除了打印出错误信息,以及一些别的关键信息(一般推荐: 时间戳,错误文件名字,错误的行数 ,错误的func名….等等)

logging模块的使用

在python中我们可以使用以下代码简单引入logging模块,在主文件中引入这个config.py。之后再在主文件中import任意的模块,在每个模块中的logging方法就能保证都用的是统一配置的自定义日志格式

主要配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import logging
import datetime
file_name = ("./log") #自定义文件名字和路径
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s [line:%(lineno)d] [func:%(funcName)s] %(levelname)s : %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='%s_%s.log'%(file_name ,datetime.datetime.now().strftime("%Y-%m-%d") ), #时间戳后缀
filemode='a')

#save as config.py

以上这段代码可以写在任意py文件的开头处,但是在一个项目中的话,推荐将其写入到 config.py文件中,我们在 main.py中可以引入 config.py ,这样的话,能通过config的配置,控制全局的日志输出格式和级别.

具体代码使用

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import logging

def test(name):
logging.info("i am here with " + name)

pass

#save as logB.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from config import *
import logB

def test(name):
logging.info("i am here with " + name)

pass

if __name__ == "__main__":
test("A")
logB.test("B")
pass

#save as main.py

执行./main.py ,输出的格式如下

1
2
3
4
Fri, 30 Apr 2021 16:06:35 main.py [line:10] [func:test] INFO : i am here withA
Fri, 30 Apr 2021 16:06:35 logB.py [line:7] [func:test] INFO : i am here with B

#filename : log_2021-04-30.log

我们只需要在程序的主入口中引入所有需要用到的模块,这样在模块中具体的业务代码中用到的logging方法就会优先使用到logging.basicConfig的配置格式。

end

本文简单介绍了个人常用代码中添加日志记录的一些常用写法,当然在大型(py或其他语言)的项目中,日志的格式更加规范化,分级也会更清晰,支持的扩展功能也会更多.