栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python日志模块logging,基础知识和高级知识

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python日志模块logging,基础知识和高级知识

logging基本知识

logging是一个python内置的包,即文件夹logging下有一个__init__.py文件

知识点主要包括:

  1. 日志5个级别:logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL
  2. 配置:logging.basicConfig(…)
  3. 配置信息:日志输出文件filename, 日志格式format, 日期格式datefmt, 日志级别level)
  4. 格式信息:%(asctime)s %(levelname)s %(thread)-8d %(name)s %(message)s
  5. 日期格式:%Y-%m-%d %H:%M:%S
  6. logger = logging.getLogger(‘loggername’)这里的loggername即格式中的name
  7. logging.info(msg, args, **kwargs), msg和args可以使用%s一起进行格式化,**kwargs可以填入exc_info=True,这样能够捕获异常信息
日志基础版
# -*- coding:utf-8 -*-
import logging
import traceback


logging.basicConfig(filename='log_learn.log',
                    format='[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    level=logging.INFO)

logger = logging.getLogger(__file__)


def division(v):
    return 10/v

# 使用exc_info参数来捕获异常信息,%s可以进行格式化
try:
    division(0)
except:
    logger.error('函数%s报错,报错信息为:', division.__name__, exc_info=1)


# 使用traceback.format_exc()来捕获异常信息
try:
    division(0)
except:
    trace_info = traceback.format_exc()
    msg = '函数{func_name}报错,报错信息为:n{trace_info}'.format(
            func_name=division.__name__,
            trace_info=trace_info)
    logger.error(msg)

format

 |  %(name)s            Name of the logger (logging channel)
 |  %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
 |                      WARNING, ERROR, CRITICAL)
 |  %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
 |                      "WARNING", "ERROR", "CRITICAL")
 |  %(pathname)s        Full pathname of the source file where the logging
 |                      call was issued (if available)
 |  %(filename)s        Filename portion of pathname
 |  %(module)s          Module (name portion of filename)
 |  %(lineno)d          Source line number where the logging call was issued
 |                      (if available)
 |  %(funcName)s        Function name
 |  %(created)f         Time when the LogRecord was created (time.time()
 |                      return value)
 |  %(asctime)s         Textual time when the LogRecord was created
 |  %(msecs)d           Millisecond portion of the creation time
 |  %(relativeCreated)d Time in milliseconds when the LogRecord was created,
 |                      relative to the time the logging module was loaded
 |                      (typically at application startup time)
 |  %(thread)d          Thread ID (if available)
 |  %(threadName)s      Thread name (if available)
 |  %(process)d         Process ID (if available)
 |  %(message)s         The result of record.getMessage(), computed just as
 |                      the record is emitted
logging高级知识
  • Logger 提供接口给代码,让其操作记录日志
  • Handler 确定日志输出的目的地,可以是文件、控制台等
  • Filter 拒绝不需要的日志内容
  • Formatter 日志内容的格式
日志记录的流程(官网流程图)
  1. 代码调用接口如 logger.info
  2. 判断是否满足logger的level,满足则创建LogRecord
  3. Filter是否要拒绝日志,如果不拒绝则进入handler
  4. handler判断日志是否满足level,满足则进行Filter
  5. Filter如果没有拒绝,则emit,进行发出
创建3个输出地方的日志记录器
# -*- coding:utf-8 -*-
import logging


# 1、创建日志记录器,使用当前文件路径名作为日志名称,级别为INFO
logger = logging.getLogger(__file__)
logger.setLevel(logging.INFO)

# 2、创建3个日志输出,2个文件,一个控制台
handler_file_1 = logging.FileHandler('file_1.log')
handler_file_1.setLevel(logging.INFO)           # 打印INFO级别及以上的日志信息

handler_file_2 = logging.FileHandler('file_2.log')
handler_file_2.setLevel(logging.ERROR)          # 只打印报错级别及以上的日志信息

handler_stream = logging.StreamHandler()    
handler_stream.setLevel(logging.ERROR)          # 只打印报错级别及以上的日志信息

# 3、创建格式
formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(name)s %(message)s')
handler_file_1.setFormatter(formatter)
handler_file_2.setFormatter(formatter)
handler_stream.setFormatter(formatter)

# 4、操作输出器handler添加到logger
logger.addHandler(handler_file_1)
logger.addHandler(handler_file_2)
logger.addHandler(handler_stream)


def add_value(value):
    logger.info('参数值为:%s', value)
    return value


def division(value):
    try:
        10/value
    except:
        logger.error('发生报错,报错信息为:', exc_info=1)


add_value(0)
division(0)

使用dictConfig来简化上边的操作(功能内容并非完全一致,仅供参考)

# -*- coding:utf-8 -*-
import logging
from logging import config

log_config = {
    'version': 1,
    'loggers': {
        '': {
            'handlers': ['file', 'stream'],
            'level': 'INFO',
        }
    },
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'log/log_config.log',
            'level': 'INFO',
            'formatter': 'default'
        },
        'stream': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
            'formatter': 'simple'
        }
    },
    'formatters': {
        'default': {
            'format': '[%(asctime)s] %(levelname)s %(pathname)s %(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': '[%(asctime)s] %(message)s'
        }
    }
}


logging.config.dictConfig(log_config)
logger = logging.getLogger(__file__)


def add_log(data):
    logger.info('执行函数,打印日志,参数为:%s', data)


def division(v):
    try:
        10/v
    except:
        logger.error('函数报错,报错信息为:', exc_info=1)


add_log(10)
division(0)
dictConfig注意事项:
  1. 编写dictConfig,实际上就是对logging使用logger, handler, filter, formatter的使用,将参数统一写到这里
  2. 第一层的这几个单词要加s:loggers,handlers,formatters
  3. loggers底下的handlers是加s的
  4. handlers底下的formatter是不加s的
  5. loggers底下不能直接写handlers,level,要多一层字典,可以用'':{}的形式(如果命名一个会出现报错,不知道什么原因)
  6. class和level的填写,也是用字符串,就是要加上引号,而不是直接写类和常量。
  7. loggers下的handlers的值是一个列表,如果只有一个handler,也要写成列表形式
  8. delay表示延时,FileHandler默认是False,表示实时写入日志,TimedRotatingHandler默认是True,要改成False才会实时写入日志
日志高级版
# -*- coding:utf-8 -*-
import logging
from logging import config
import os

# 创建log文件夹,使用项目名设置log文件名称
project_name = os.path.dirname(__file__).split('/')[-1]
if not os.path.exists('log'):
    os.mkdir('log')

log_file = 'log/' + str(project_name) + '.log'
log_rotate_file = 'log/' + str(project_name) + '_rotate.log'

log_config = {
    'version': 1,
    'loggers': {
        '': {
            'handlers': ['file', 'rotate_file'],
            'level': 'INFO'
        }
    },
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',     # delay默认是False,实时写入
            'filename': log_file,
            'level': 'INFO',
            'formatter': 'default_fmt'
        },
        'rotate_file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': log_rotate_file,
            'level': 'INFO',
            'formatter': 'default_fmt',
            'when': 'D',
            'interval': 1,          # 配合when使用,1D表示间隔1天就会分割一个日志
            'backupCount': 90,      # 保留90个日志,每天1个,相当于一共保留90天
            'delay': False          # 默认是True,不会实时写入,改成False,就不会推迟,实时写入日志
        }
    },
    'formatters': {
        'default_fmt': {
            'format': '[%(asctime)s] %(levelname)s %(pathname)s:%(lineno)d %(message)s',
            # 'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple_fmt': {
            'format': '[%(asctime)s] %(message)s'
        }
    }
}
logging.config.dictConfig(log_config)
logger = logging.getLogger(__file__)


logger.debug('这是debug信息')
logger.info('这是info信息')
logger.error('这是error信息')


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339866.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号