运维开发中日志模块logging的最佳实践

简单介绍:

说明: 此模块儿提供了文件,HTTP GET/POST,SMTP,SOCKET等方式实现日志记录,甚至可以自动实现具体的日志记录方式

 

快速安装:

pip install --upgrade logging

 

处理流程:

wKioL1fpGgWT6WX0AADB8mVHrYk784.png

 

日志级别:

属性名称 属性说明
logging.NOTSET 默认为0
logging.DEBUG 调试为10
logging.INFO 一般为20
logging.WARN 警告为30
logging.ERROR 错误为40
logging.CRITICAL 严重为50
logging._levelNames 日志级别字典

 

快速配置:

logging.basicConfig(**kwargs) -> None

说明: 快速配置root logger对象,支持filename,filemode,format,datefmt,level,stream,由于是针对于root logger对象设置,所以获取日志对象时候必须logging.getLogger('')的name字段留空

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True) -> None

说明: 快速配置日志对象,所有的对象配置都可以通过配置文件指定,而且还支持灵活选择处理方式[loggers]

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

42

; 定义多个日志对象

keys=root, error

[handlers]

; 定义多个处理对象

keys=root, error

[formatters]

; 定义多个格式对象

keys=root, error

[logger_root]

level=NOTSET

; 处理类,可以有多个,逗号隔开

handlers=root

; logger名称,如果不设置则默认root

qualname=root

; 不继承父类的log信息

propagate=0

[logger_error]

level=INFO

; 保证错误信息也在终端打印

handlers=error, root

qualname=error

propagate=0

[handler_root]

; 处理类,可以有多个,逗号隔开

class=StreamHandler

; 参数元素,可以有多个逗号隔开

args=(sys.stdout,)

; 日志级别,NOTSET接受任何级别日志

; 设置处理对象的格式

formatter=root

[handler_error]

class=logging.handlers.TimedRotatingFileHandler

args=('./logs/error.log', 'd', 1, 7)

formatter=error

[formatter_root]

; 设置格式对象格式

format=%(asctime)s - %(levelname)s - %(message)s

; 设置日期格式

datefmt=

[formatter_error]

format=%(asctime)s - %(levelname)s - %(filename)s - %(lineno)s - %(message)s

datefmt=

说明: 默认解析按照ini格式解析,配置文件必须包含[logger],[handlers],[formatters]三个节点,分别表示日志对象,处理对象和格式对象

 

日志对象:

创建对象

说明: 日志对象可以添加多个处理对象

logging.getLogger(name=None) -> logger

说明: 快速创建一个日志对象,如果没有指定name则返回root logger对象,name支持.连接结合过滤对象使用

对象方法

l.addHandler(handler) -> None

说明: 为日志对象添加处理对象

l.debug(msg, *args, **kwargs, exc_info=true) -> None

说明: 使用调试模式写日志,*args,**kwargs会自动替换msg中替换字符串,exc_info为true时会记录异常信息

l.info(msg, *args, **kwargs, exc_info=true) -> None

说明: 使用默认模式写日志,*args,**kwargs会自动替换msg中替换字符串,exc_info为true时会记录异常信息

l.warning(msg, *args, **kwargs, exc_info=true) -> None

说明: 使用警告模式写日志,*args,**kwargs会自动替换msg中替换字符串,exc_info为true时会记录异常信息

l.error(msg, *args, **kwargs, exc_info=true) -> None

说明: 使用错误模式写日志,*args,**kwargs会自动替换msg中替换字符串,exc_info为true时会记录异常信息

l.critical(msg, *args, **kwargs, exc_info=true) -> None

说明: 使用严重模式写日志,*args,**kwargs会自动替换msg中替换字符串,exc_info为true时会记录异常信息

 

处理对象:

说明: logging模块默认只提供了基础的流处理类(StreamHandler)和文件处理类(FileHandler),如果要使用扩展处理类,需要import logging.handlers导入扩展处理类,才可以使用.

创建对象

说明: 日志对象可以添加多个处理对象,每个处理对象又可以添加多个过滤对象,这样日志就会经过过滤器

logging.StreamHandler(stream=None) -> StreamHandler

说明: 创建一个流处理对象,参数stream可以是任何文件对象,默认是sys.stderr

logging.FileHandler(filename, mode='a', encoding=None, delay=0) -> FileHandler

说明: 同上,比较之上会自动帮你打开文件,创建一个文件处理对象

logging.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0) -> RotatingFileHandler

说明: 同上但可轮询,当超出指定大小日志文件被重命名(末尾附加数字),创建新文件继续输出,maxBytes为0时表示无限大,backupCount表示备份文件数量

logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False) -> TimedRotatingFileHandler

说明: 同上但可轮询,当超出指定时间日志文件被重命名(末尾附加时间),创建新文件继续输出,when可为s秒/m分/h时/d天/w星期,interval表示频率

logging.handlers.SocketHandler(host, port) -> SocketHandler

说明: 创建一个TCP处理对象,将日志发送到对应主机的端口

logging.handlers.DatagramHandler(host, port) -> DatagramHandler

说明: 创建一个UDP处理对象,将日志发送到对应主机的端口

logging.handlers.SysLogHandler(address=('localhost', 514), facility=1, socktype=None) -> SysLogHandler

说明: 创建一个本地处理对象,将日志通过syslogd写入Linux系统日志

logging.handlers.NTEventLogHandler(appname, dllname=None, logtype='Application') -> NTEventLogHandler

说明: 创建一个本地处理对象,将日志通过evetlog写入Windows事件日志

logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None)

说明: 创建一个邮件处理对象,将日志通过邮件发送到对应的的邮箱

logging.handlers.MemoryHandler(capacity, flushLevel=40, target=None) -> MemoryHandler

说明: 创建一个内存处理对象,将日志零时存储到内存定期刷新到target

logging.handlers.HTTPHandler(host, url, method='POST') -> HTTPHandler

说明: 创建一个HTTP处理对象,将日志通过http接口发送到对应服务器存储

对象方法

h.setLevel(level) -> None

说明: 为日志处理对象设置日志级别,一旦设置,只有当超出此级别的日志才会被处理

h.setFormatter(fmt) -> None

说明: 为日志处理对象设置格式对象,具体格式可参考格式对象相关信息

 

格式对象:

logging.Formatter(fmt=None, datefmt=None) -> Formatter

说明: 创建一个格式对象,fmt为日志信息格式,datafmt为时间格式,默认为"%Y-%m-%d %H:%M:%S"

特殊字段

字段名称 字段说明
%(name)s logger的名称
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的完整路径名,可能为空
%(filename)s 调用日志输出函数的完整文件名,可能为空
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出所在的代码行
%(created)f 当前时间,默认时间戳格式
%(relativeCreated)d 自从logger创建以来的毫秒数
%(asctime)s 字符串形式的当前时间,默认"年-月-日 小时:分钟:秒,毫秒"
%(thread)d 线程ID,可能没有
%(threadName)s 线程名,可能没有
%(process)d 进程ID,可能没有
%(message)s 用户输出的消息

 

过滤对象:

说明: 每个处理对象可以添加多个过滤对象,只要有一个过滤对象拒绝,日志信息就不会被处理

logging.Filter(name="") -> Filter

说明: 创建一个过滤器,日志对象的名字格式一般为a.b.c,当name为a.b时表示只有前缀为a.b的日志才会被处理,否则日志会被丢弃.

 

应用场景:

1. RotatingFileHandler和TimedRotatingFileHandler都是线程安全的,可用于多线程场景

2. 多进程场景官方推荐使用TCP/UDP传输日志,单台压测支持6000~9000条/s记录,还可以考虑使用Python-logstash或pyzmq提供的日志句柄

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# 51CTOBG: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

import logging

import logging.config

# 说明: 导入其它模块

if __name__ == '__main__':

    logging.config.fileConfig('logging.conf')

    root_logger = logging.getLogger('root')

    error_logger = logging.getLogger('error')

    root_logger.info('info message.')

    error_logger.error('error message.')

 

登录乐搏学院官网http://www.learnbo.com/

或关注我们的官方微博微信,还有更多惊喜哦~

 

本文出自 “满满李 - 运维开发之路” 博客,请务必保留此出处http://xmdevops.blog.51cto.com/11144840/1856763

转载于:https://my.oschina.net/learnbo/blog/847531