码迷,mamicode.com
首页 > 编程语言 > 详细

Python日志模块的配置和使用

时间:2020-02-22 20:02:27      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:exception   return   minutes   path   rgs   mes   creation   red   disable   

日志

一、日志的级别

  • CRITICAL : 50

  • ERROR : 40

  • WARNING : 30

  • INFO : 20

  • DEBUG : 10

  • NOTSET : 0 (无日志记录)

    级别 常量 引用方式
    critical 50 logging.CRITICAL
    error 40 logging.ERROR
    warning 30 logging.WARNING
    info 20 logging.INFO
    debug 10 logging.DEBUG
    noset 0 logging.NOSET

二、日志的流程

技术图片

logger中的传递

  1. Logger 中的日志先经过等级筛选,将高于设定等级的日志信息创建LogRecord对象。
  2. 在__过滤器__中进行处理。
  3. 传递到处理器
  4. 是否发送至父级日志进行处理

在handler中的传递

  1. 先经过等级筛选
  2. 处理器中的过滤器经行过滤
  3. 发送给响应的处理句柄

三、格式化消息

属性名称 格式 描述
args 不需要格式化。 The tuple of arguments merged into msg to produce message, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).
asctime %(asctime)s
created %(created)f Time when the LogRecord was created (as returned by time.time()).
exc_info 不需要格式化。 Exception tuple (à la sys.exc_info) or, if no exception has occurred, None.
filename %(filename)s Filename portion of pathname.
funcName %(funcName)s Name of function containing the logging call.
levelname %(levelname)s Text logging level for the message (‘DEBUG‘, ‘INFO‘, ‘WARNING‘, ‘ERROR‘, ‘CRITICAL‘).
levelno %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).
lineno %(lineno)d Source line number where the logging call was issued (if available).
message %(message)s The logged message, computed as msg % args. This is set when Formatter.format() is invoked.
module %(module)s 模块 (filename 的名称部分)。
msecs %(msecs)d Millisecond portion of the time when the LogRecord was created.
msg 不需要格式化。 The format string passed in the original logging call. Merged with args to produce message, or an arbitrary object (see 使用任意对象作为消息).
name %(name)s Name of the logger used to log the call.
pathname %(pathname)s Full pathname of the source file where the logging call was issued (if available).
process %(process)d 进程ID(如果可用)
processName %(processName)s 进程名(如果可用)
relativeCreated %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.
stack_info 不需要格式化。 Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.
thread %(thread)d 线程ID(如果可用)
threadName %(threadName)s 线程名(如果可用)

四、轮替日志

按数量轮替

# 配置文件中的字典参数
'handler_name':{
    'class':'logging.handlers.RotatingFileHandler',  # 日志轮替的类
    'level':'DEBUG',    # 记录等级
    'formatter':'standard', # 使用的消息格式,填写formatters中的键名
    'filename':log_file_name, # 日志文件路径
    'maxBytes':512, # 单个日志最大体积,单位:字节
    'backupCount':4, # 轮替最多保存数量
    'encoding':'utf-8', # 字符编码
},

按时间轮替

# 配置文件中的字典参数
'handler_name':{
    'class':'logging.handlers.TimedRotatingFileHandler',  # 日志轮替的类
    'level':'DEBUG',    # 记录等级
    'formatter':'standard', # 使用的消息格式,填写formatters中的键名
    'filename':log_file_name, # 日志文件路径
    'when':'S', # 时间单位。
    'interval':10, # 间隔时常
    'backupCount':4, # 轮替最多保存数量
    'encoding':'utf-8', # 字符编码
},

when 是一个字符串,定义了日志切分的间隔时间单位,这是一个枚举类,可选参数如下:
"S":Second 秒
"M":Minutes 分钟
"H":Hour 小时
"D":Days 天
"W":Week day(0 = Monday)
"midnight":Roll over at midnight

五、日志配置

使用方法来配置日志

import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

使用配置文件来配置日志

.py脚本

import logging
import logging.config

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

# create logger
logger = logging.getLogger('simpleExample')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

配置文件logging.conf:

[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

使用字典来配置日志

  • version - 用数字表示的模式版本,当前有效值只能为1,主要是为了后续配置升级后提供兼容性
  • formatters - 格式化对象,值还是一个dict,该dict的键为格式化对象的id,值为一个dict,存储了formatter对象的配置内容
    • format: None
    • datefmt: None
  • filters - 过滤器对象,逻辑同formatters
    • name: ‘‘
  • handlers - 逻辑同formatters
    • class(必须的): handler类的全限定名
    • level(可选的): handler对象级别
    • formatter(可选的):为formatters中定义的formatter对象id
    • filters(可选的):为一个filter对象的列表,里面存放filters中定义的filter对象id
      也可以存入其他的参数,视实际handler对象而定
  • loggers - 逻辑同formatters,该logger对象的id也是logger name
    • level(可选的):logger对象级别
    • propagate(可选的):logger对象的消息传递设置
    • filters(可选的):为一个filter对象的列表,里面存放filters中定义的filter对象id
    • handlers(可选的):为一个handler对象的列表,里面存放handlers中定义的handler对象id
  • root - 值为dict,存放root这个logger对象的配置,但是propagate这个值对root没用
  • incremental - 该配置文件的配置是否作为已有配置的一个补充,该值默认为False,即覆盖原有配置,如果为True,也不是完全覆盖,因为filter对象和formatter对象是匿名的,无法获取到具体的对象,也就无法修改,但是可以替代logger对象的levelpropagate属性,handler对象的level属性
  • disable_existing_loggers - 是否禁用已存在的logger对象,默认是True,如果incrementalTrue的话,该值就会被忽略

注:上述的id处理loggers里的id用来表示实际logger对象的name以外,其他对象的id只是作一个标识作用,用来表示对象之间的联系

通过字典配置参数调用日志,完整代码:

import os
import logging.config

full_formatter = '[%(asctime)s] - [%(levelname)s] - [%(name)s] - [%(module)s模块:%(lineno)d行] - [%(message)s]'
simple_formatter = '[%(asctime)s] - [%(levelname)s] - [%(name)s] - [%(message)s]'

logdir = os.path.join(os.path.dirname(__file__),'logs')

if not os.path.exists(logdir) or not os.path.isdir(logdir):
    os.mkdir(logdir)

log_file_name = 'default.log'
log_file_name2 = 'common.log'

log_file_name = os.path.join(logdir,log_file_name)
log_file_name2 = os.path.join(logdir,log_file_name2)

LOGGING_DICT = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': full_formatter,
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': simple_formatter
        }
    },
    'filters': {},
    'handlers': {
        'sh': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        'fh':{
            'class':'logging.handlers.RotatingFileHandler',
            'level':'DEBUG',
            'formatter':'standard',
            'filename':log_file_name,
            'maxBytes':512,
            'backupCount':4,
            'encoding':'utf-8',
        },
        'fth':{
            'class':'logging.handlers.TimedRotatingFileHandler',
            'level':'WARNING',
            'formatter':'standard',
            'filename':log_file_name2,
            'when':'S',
            'interval':3,
            'backupCount':10,
            'encoding':'utf-8',
        }

    },
    'loggers': {
        '': {
            'level': 'DEBUG',
            'handlers': ['sh','fh','fth'],
            'propagate': True,
        }
    }
}

def load_log_cfg():
    logging.config.dictConfig(LOGGING_DICT)
    logger2 = logging.getLogger(__name__)
    return logger2

if __name__ == '__main__':

    import time

    log = load_log_cfg()
    t = time.localtime(1111111111)
    print(t)
    while True:
        log.error('这是一个错误日志')
        log.critical('这是一个致命错误日志')
        log.warning('这是一个警告日志')
        log.info('这是一个信息日志')
        time.sleep(3)

Python日志模块的配置和使用

标签:exception   return   minutes   path   rgs   mes   creation   red   disable   

原文地址:https://www.cnblogs.com/jiaowoxiaoming/p/12346657.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!