python日志模块记录一

logging日志模块

logging模块,干什么用

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别,级别依次升高。下面来具体看下:

DEBUG    调试 10

INFO     正常 20

WARNING   警告 30

ERROR    错误 40

CRITICAL   严重 50

默认级别为warning,默认打印到终端

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''
logging.basicConfig(filename='example.log',
                    level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s  %(filename)s %(funcName)s  %(lineno)s',
                    datefmt='%Y/%m/%d %H:%M:%S %p')
'''
   level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说大于等于INFO级别的日志才会被纪录到文件里,
 如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。第二次运行会以追加模式接着写。
'''
logging.debug('This message should go to the log file') # 这里等级低于INFO不会被输出
logging.info('welcome come !')   # 高于等于info才会输出
logging.warning("user [cc] attempted wrong password more than 3 times")

# 结果: WARNING:root:user [cc] attempted wrong password more than 3 times

python中时间日期格式化符号:

  • %y 两位数的年份表示(00-99)
  • %Y 四位数的年份表示(000-9999)
  • %m 月份(01-12)
  • %d 月内中的一天(0-31)
  • %H 24小时制小时数(0-23)
  • %I 12小时制小时数(01-12)
  • %M 分钟数(00=59)
  • %S 秒(00-59)
  • %a 本地简化星期名称
  • %A 本地完整星期名称
  • %b 本地简化的月份名称
  • %B 本地完整的月份名称
  • %c 本地相应的日期表示和时间表示
  • %j 年内的一天(001-366)
  • %p 本地A.M.或P.M.的等价符
  • %U 一年中的星期数(00-53)星期天为星期的开始
  • %w 星期(0-6),星期天为星期的开始
  • %W 一年中的星期数(00-53)星期一为星期的开始
  • %x 本地相应的日期表示
  • %X 本地相应的时间表示
  • %Z 当前时区的名称
  • %% %号本身

format参数格式化

format参数中可能用到的格式化串:
%(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用户输出的消息

日志输出流程

日志输出的流程(画图理解)

image.png

日志的handle种类

一、StreamHandler

流handler——包含在logging模块中的三个handler之一。

能够将日志信息输出到sys.stdout, sys.stderr 或者类文件对象(更确切点,就是能够支持write()和flush()方法的对象)。

只有一个参数:

image

日志信息会输出到指定的stream中,如果stream为空则默认输出到sys.stderr。

二、FileHandler

logging模块自带的三个handler之一。继承自StreamHandler。将日志信息输出到磁盘文件上。

构造参数:

image

模式默认为append,delay为true时,文件直到emit方法被执行才会打开。默认情况下,日志文件可以无限增大。

三、NullHandler

空操作handler,logging模块自带的三个handler之一。
没有参数。

四、WatchedFileHandler

位于logging.handlers模块中。用于监视文件的状态,如果文件被改变了,那么就关闭当前流,重新打开文件,创建一个新的流。由于newsyslog或者logrotate的使用会导致文件改变。这个handler是专门为linux/unix系统设计的,因为在windows系统下,正在被打开的文件是不会被改变的。
参数和FileHandler相同:

image

五、RotatingFileHandler

位于logging.handlers支持循环日志文件。

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

参数maxBytes和backupCount允许日志文件在达到maxBytes时rollover.当文件大小达到或者超过maxBytes时,就会新创建一个日志文件。上述的这两个参数任一一个为0时,rollover都不会发生。也就是就文件没有maxBytes限制。backupcount是备份数目,也就是最多能有多少个备份。命名会在日志的base_name后面加上.0-.n的后缀,如example.log.1,example.log.1,…,example.log.10。当前使用的日志文件为base_name.log。

六、TimedRotatingFileHandler

定时循环日志handler,位于logging.handlers,支持定时生成新日志文件。

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

参数when决定了时间间隔的类型,参数interval决定了多少的时间间隔。如when=‘D’,interval=2,就是指两天的时间间隔,backupCount决定了能留几个日志文件。超过数量就会丢弃掉老的日志文件。

when的参数决定了时间间隔的类型。两者之间的关系如下:

image

utc参数表示UTC时间。

七、其他handler——SocketHandler、DatagramHandler、SysLogHandler、NtEventHandler、SMTPHandler、MemoryHandler、HTTPHandler

这些handler都不怎么常用,所以具体介绍就请参考官方文档 其他handlers

下面使用简单的例子来演示handler的使用:

例子一——不使用配置文件的方式(StreamHandler):

img
img

输出到控制台的结果:

img

例子二——使用配置文件的方式(TimedRotatingFileHandler) :

log.conf 日志配置文件:

img
img

获取logger方法:

img

配置logger并且调用:

img

控制台和日志文件中都会输出:

img

记录日志到控制台,和文件

import logging
from logging import handlers
# 步骤1:创建一个收集器对象,并且设置等级.
logger = logging.getLogger("阿登的日志")
logger.setLevel(10)  # 设置全局的日志等级

#步骤2:设置handle:一个输出到控制台,一个输出到日志

ch = logging.StreamHandler()
fh = handlers.RotatingFileHandler(filename="size_01.log",mode="a",maxBytes=1024*1024*2,backupCount=4,encoding="utf-8")

# 步骤3: 为所有handle设置等级
ch.setLevel(10)
fh.setLevel(10)

# 步骤4: 设置formatter
formatter = logging.Formatter ("'%(asctime)s - [%(levelname)s] - [filename]:%(filename)s - [name]:%(name)s - [line]:%(lineno)d -[def]:%(funcName)s - [msg]: %(message)s'")

# 步骤5: formatter组件和所有handle绑定
ch.setFormatter(formatter)
fh.setFormatter(formatter)

# 步骤6: handle添加到logger

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

# 调用logger

logger.debug("this is debug13")

yaml配置日志

image.png
import logging
from logging import config
import yaml

with open(r"data.yaml", "r",encoding="utf-8") as f:
    datas = yaml.load(f,Loader=yaml.FullLoader) # Loader=yaml.FullLoader 去除警告
    print(datas) 
    pass

config.dictConfig(datas)
logger = logging.getLogger('adeng')
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

配置文件data.yaml

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  console_err:
    class: logging.StreamHandler
    level: ERROR
    formatter: simple
    stream: ext://sys.stderr
  file:
    class: logging.FileHandler
    level: DEBUG
    formatter: simple
    filename: adeng_01.log
    encoding: utf-8
loggers:
  adeng:
    level: DEBUG
    handlers: [console,file]
    propagate: yes
root:
  level: DEBUG
  handlers: [console_err]

未完待续

你可能感兴趣的:(python日志模块记录一)