Python logging 模块和使用经验

本文主要使用python的日志模块logging进行操作.

日志

日志系统通常有下面几种级别,看情况使用:

  • FATAL - 导致程序退出的严重系统级错误,不可恢复,当错误发生时,系统管理员需要立即介入,谨慎使用。
  • ERROR - 运行时异常以及预期之外的错误,也需要立即处理,但紧急程度低于FATAL,当错误发生时,影响了程序的正确执行。需要注意的是这两种级别属于服务自己的错误,需要管理员介入,用户输入出错不属于此分类。
  • WARN - 预期之外的运行时状况,表示系统可能出现问题。对于那些目前还不是错误,然而不及时处理也会变成错误的情况,也可以记为WARN,如磁盘过低。
  • INFO - 有意义的事件信息,记录程序正常的运行状态,比如收到请求,成功执行。通过查看INFO,可以快速定位WARN,ERROR, FATAL。INFO不宜过多,通常情况下不超过TRACE的10%。
  • DEBUG - 与程序运行时的流程相关的详细信息以及当前变量状态。
  • TRACE - 更详细的跟踪信息。DEBUG和TRACE这两种规范由项目组自己定义,通过该种日志,可以查看某一个操作每一步的执行过程,可以准确定位是何种操作,何种参数,何种顺序导致了某种错误的发生.

日志最好放到单独的日志目录,例如 /var/logs/ 下,按照应用分成不同的目录,或者是文件。日志不要放在应用目录下,那样不利于自动化部署和应用升级,备份等。

一般对于日志,下列是不好的做法:

  • 日志中含有用户敏感信息
  • 线上程序中使用 print
  • 生产环境使用 debug 级别日志

python 日志

好习惯

  • root级别的设置: 日志格式, 有利于标准化
  • class 中设置logger self.logger = logging.getLogger(type(self).name)
  • 模块,文件中设置 logger logger = logging.getLogger(name)
  • 使用JSON YAML等格式来配置logging,感觉比使用代码或者 ini格式看起来更方面
  • 错误日志是比较特殊的日志,因为它需要更多的信息,例如错误产生的上下文,还有错误堆栈等信息。可以通过 python logging context pypi 关键词google一些信息,或者自己设计一个 logging handler 来实现。

下面是一个常用python日志代码,直接使用,很方便:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#encoding:utf-8
import logging
from logging import Logger
from logging.handlers import TimedRotatingFileHandler

'''
日志模块
1. 同时将日志打印到屏幕跟文件中
2. 默认值保留近7天日志文件
'''
def init_logger(logger_name,logging_path):
if logger_name not in Logger.manager.loggerDict:
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
handler = TimedRotatingFileHandler(filename=logging_path+"/all.log",when='D',backupCount = 7)
datefmt = '%Y-%m-%d %H:%M:%S'
format_str = '[%(asctime)s]: %(name)s %(filename)s[line:%(lineno)s] %(levelname)s %(message)s'
formatter = logging.Formatter(format_str,datefmt)
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)
logger.addHandler(handler)
console= logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(console)

handler = TimedRotatingFileHandler(filename=logging_path+"/error.log",when='D',backupCount=7)
datefmt = '%Y-%m-%d %H:%M:%S'
format_str = '[%(asctime)s]: %(name)s %(filename)s[line:%(lineno)s] %(levelname)s %(message)s'
formatter = logging.Formatter(format_str,datefmt)
handler.setFormatter(formatter)
handler.setLevel(logging.ERROR)
logger.addHandler(handler)
logger = logging.getLogger(logger_name)
return logger

if __name__ == "__main__":
logger = init_logger("datatest",logging_path=".")
logger.error('test_error')
logger.info("test-info")
logger.warn("test-warn")

对于使用时候,直接:

1
2
3
4
5
from you_logging_filename.py import init_logger
logger = init_logger("datatest",logging_path=".")
def you_functiuon():
logger.info()
logger.error()

-------------本文结束感谢您的阅读-------------
;