Python日志模块logging

2022-12-21 18:39:45 浏览数 (2)

logging是Python自带的日志系统, 使用方便灵活.

示例, 将警告输出到终端:

代码语言:javascript复制
>>>import logging
>>>logging.warning('This is warning message')
WARNING:root:This is warning message

我们可以自定义logger来向文件和终端写日志, 并重设了日志的格式:

代码语言:javascript复制
import logging
logger = logging.getLogger("service log")
logger.setLevel(logging.DEBUG)

fh = logging.FileHandler('log/info.log', 'a')
fh.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S")
fh.setFormatter(formatter)
ch.setFormatter(formatter)

logger.addHandler(fh)
logger.addHandler(ch)

写入日志:

代码语言:javascript复制
>>>logger.info("admin login success")
2017-02-21 11:58:42 - service log - INFO - admin login success

logging

logging模块主要提供了四个类:

  • logger提供了应用程序可以直接使用的接口;
  • handler将(logger创建的)日志记录发送到合适的输出通道;
  • filter决定输出哪条日志记录;
  • formatter决定日志记录的最终输出格式;

这里提供一个

logger

logger默认提供5个级别的日志输出, 从高到低为:

  1. logger.critical(msg)
  2. logger.error(msg)
  3. logger.warning(msg)
  4. logger.info(msg)
  5. logger.debug(msg)

logger只输出高于或等于当前级别的日志, logging的root logger默认级别为info.

代码语言:javascript复制
>>> log = logging.getLogger()
>>> log.setLevel(logging.INFO)
>>> logging.INFO
20

logger可以添加handler, filter和formatter以增强功能:

  • Logger.addHandler(handler)
  • Logger.removeHandler(handler)
  • Logger.addFilter(filter)
  • Logger.removeFilter(filter)

handler

Handler把Logger记录发到相应的通道, logging中提供了常用的几个Handler:

  • StreamHandler 发送日志到终端输出流中
  • FileHandler 发送日志到日志文件中
  • NullHandler 无操作的日志处理类

将日志输出到文件:

代码语言:javascript复制
>>> logger = logging.getLogger()
>>> fh = logging.FileHandler('test.log', 'w')
>>> logger.addHandler(fh)
>>> logger.warning('This is warning message')
WARNING:root:This is warning message
~$ cat test.log
This is warning message

其它的Handlers在logging.handlers中:

  • RotatingFileHandler 在一个日志文件到达最大字数后建立新的文件记录日志
  • TimedRotatingFileHandler 发生日志到文件,并在适当的事件间隔进行轮徇
  • SocketHandler 通过TCP协议发送日志
  • DatagramHandler 通过UDP协议发送日志
  • SysLogHandler 发送日志到UNIX syslog服务,并支持远程syslog服务
  • NTEventLogHandler 发送日志到WindowsNT/2000/XP事件日志
  • SMTPHandler 通过SMTP协议发送日志
  • MemoryHandler 发送日志到内存中的缓冲区,并在达到特定条件时清空
  • HTTPHandler 通过GET或POST方法发送日志到HTTP服务器

Formatter

Formatter对象设置日志信息的格式, 示例:

代码语言:javascript复制
>>> logger = logging.getLogger()
>>> handler = logging.StreamHandler()
>>> formatter = logging.Formatter('%(name)-6s: %(levelname)-8s %(asctime)-8s %(message)s')
>>> handler.setFormatter(formatter)
>>> logger.addHandler(handler)
>>> logger.warning('This is warning message')
WARNING:root:This is warning message
root  : WARNING  2016-06-07 21:48:57,801 This is warning message

第二行信息即为新增Formatter输出的没,这里没有移除原有Formatter所以输出了两条信息.

Formatter的标识符如下表所示:

%(name)s

Logger的名字

%(levelno)s

数字形式的日志级别

%(levelname)s

文本形式的日志级别

%(pathname)s

调用日志输出函数的模块的完整路径名,可能没有

%(filename)s

调用日志输出函数的模块的文件名

%(module)s

调用日志输出函数的模块名

%(funcName)s

调用日志输出函数的函数名

%(lineno)d

调用日志输出函数的语句所在的代码行

%(created)f

当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d

输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s

字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d

线程ID。可能没有

%(threadName)s

线程名。可能没有

%(process)d

进程ID。可能没有

%(message)s

用户输出的消息

Filter

logging.getLogger()时参数的格式类似于“A.B.C”, 这样做也便于Filter的配置.名为“A.B”的过滤器只让名字带有 “A.B”前缀的Logger输出信息.

代码语言:javascript复制
>>>import logging
>>>logger = logging.getLogger('cn.finley')
>>>handler = logging.StreamHandler()
>>>filter = logging.Filter('cn.finley')
>>>handler.addFilter(filter)
>>>logger.addHandler(handler)
>>>logger.warning('This is warning message')
>>>
>>>fake_logger = logging.getLogger('cn.fakefinley')
>>>handler = logging.StreamHandler()
>>>filter = logging.Filter('cn.finley')
>>>handler.addFilter(filter)
>>>fake_logger.addHandler(handler)
>>>fake_logger.warning('This is warning message')
This is warning message

可以看到fake_logger的输出被拦截

模块方法

logging模块提供了root logger.

logging模块也提供了一系列模块方法:

  • logging.getLogger([name]) 根据config返回指定的logger, 默认返回root logger
  • logging.basicConfig(): 用默认Formatter为日志系统建立一个StreamHandler,设置baseConfig并加到root logger中

logging.debug(), logging.info(), logging.warning(), logging.error()、logging.critical()可以直接通过root logger输出日志信息.

logging.basicConfig

basicConfig方法提供对RootHandler的基本配置,示例:

代码语言:javascript复制
logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='myapp.log',
                filemode='w')

logging.config

logging.config模块可以通过文件配置logger, 先展示配置文件:

代码语言:javascript复制
#logger.conf
###############################################
[loggers]
keys=root,example01,example02
[logger_root]
level=DEBUG
handlers=hand01,hand02
[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0
[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0
###############################################
[handlers]
keys=hand01,hand02,hand03
[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('myapp.log', 'a')
[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=('myapp.log', 'a', 10*1024*1024, 5)
###############################################
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%a, %d %b %Y %H:%M:%S
[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=

使用.conf文件配置logger:

代码语言:javascript复制
>>> import logging
>>> import logging.config
>>> 
>>> logging.config.fileConfig("logger.conf")
>>> logger = logging.getLogger("example01")
>>> 
>>> logger.debug('This is debug message')
>>> logger.info('This is info message')
example01   : INFO     This is info message
>>> logger.warning('This is warning message')
example01   : WARNING  This is warning message

0 人点赞