python logging模块的使用总结


Posted in Python onJuly 09, 2019

日志级别

  • CRITICAL 50
  • ERROR 40
  • WARNING 30
  • INFO 20
  • DEBUG 10

logging.basicConfig()函数中的具体参数含义

  • filename:指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中;
  • filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“w”还可指定为“a”;
  • format:指定handler使用的日志显示格式;
  • datefmt:指定日期时间格式。,格式参考strftime时间格式化(下文)
  • level:设置rootlogger的日志级别
  • stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

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 用户输出的消息

使用logging打印日志到标准输出

import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')

 使用logging.baseConfig()将日志输入到文件

import os

logging.basicConfig(
  filename=os.path.join(os.getcwd(),'all.log'),
  level=logging.DEBUG,
  format='%(asctime)s %(filename)s : %(levelname)s %(message)s', # 定义输出log的格式
  filemode='a',
  datefmt='%Y-%m-%d %A %H:%M:%S',
)

logging.debug('this is a message')

自定义Logger

设置按照日志文件大小自动分割日志写入文件

import logging
from logging import handlers


class Logger(object):
  level_relations = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'crit': logging.CRITICAL
  }

  def __init__(self, filename, level='info', when='D', backCount=3,
         fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
    self.logger = logging.getLogger(filename)
    format_str = logging.Formatter(fmt) # 设置日志格式
    self.logger.setLevel(self.level_relations.get(level)) # 设置日志级别

    # 向控制台输出日志
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(format_str)
    self.logger.addHandler(stream_handler)

    # 日志按文件大小写入文件
    # 1MB = 1024 * 1024 bytes
    # 这里设置文件的大小为500MB
    rotating_file_handler = handlers.RotatingFileHandler(
      filename=filename, mode='a', maxBytes=1024 * 1024 * 500, backupCount=5, encoding='utf-8')
    rotating_file_handler.setFormatter(format_str)
    self.logger.addHandler(rotating_file_handler)


log = Logger('all.log', level='info')

log.logger.info('[测试log] hello, world')

按照间隔日期自动生成日志文件

import logging
from logging import handlers


class Logger(object):
  level_relations = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'crit': logging.CRITICAL
  }

  def __init__(self, filename, level='info', when='D', backCount=3,
         fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
    self.logger = logging.getLogger(filename)
    format_str = logging.Formatter(fmt) # 设置日志格式
    self.logger.setLevel(self.level_relations.get(level)) # 设置日志级别

    # 往文件里写入
    # 指定间隔时间自动生成文件的处理器
    timed_rotating_file_handler = handlers.TimedRotatingFileHandler(
      filename=filename, when=when, backupCount=backCount, encoding='utf-8')

    # 实例化TimedRotatingFileHandler
    # interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
    # S 秒
    # M 分
    # H 小时、
    # D 天、
    # W 每星期(interval==0时代表星期一)
    # midnight 每天凌晨
    timed_rotating_file_handler.setFormatter(format_str) # 设置文件里写入的格式
    self.logger.addHandler(timed_rotating_file_handler)

    # 往屏幕上输出
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(format_str)
    self.logger.addHandler(stream_handler)


log = Logger('all.log', level='info')
log.logger.info('[测试log] hello, world')

logging 模块在Flask中的使用
我在使用Flask的过程中看了很多Flask关于logging的文档,但使用起来不是很顺手,于是自己就根据Flask的官方文档写了如下的log模块,以便集成到Flask中使用。

restful api 项目目录:

.
├── apps_api
│  ├── common
│  ├── models
│  └── resources
├── logs
├── migrations
│  └── versions
├── static
├── templates
├── test
└── utils
└── app.py
└── config.py
└── exts.py
└── log.py
└── manage.py
└── run.py
└── README.md
└── requirements.txt

log.py 文件

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

import logging
from flask.logging import default_handler
import os

from logging.handlers import RotatingFileHandler
from logging import StreamHandler

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

LOG_PATH = os.path.join(BASE_DIR, 'logs')

LOG_PATH_ERROR = os.path.join(LOG_PATH, 'error.log')
LOG_PATH_INFO = os.path.join(LOG_PATH, 'info.log')
LOG_PATH_ALL = os.path.join(LOG_PATH, 'all.log')

# 日志文件最大 100MB
LOG_FILE_MAX_BYTES = 100 * 1024 * 1024
# 轮转数量是 10 个
LOG_FILE_BACKUP_COUNT = 10


class Logger(object):

  def init_app(self, app):
        # 移除默认的handler
    app.logger.removeHandler(default_handler)

    formatter = logging.Formatter(
      '%(asctime)s [%(thread)d:%(threadName)s] [%(filename)s:%(module)s:%(funcName)s] '
      '[%(levelname)s]: %(message)s'
    )

    # 将日志输出到文件
    # 1 MB = 1024 * 1024 bytes
    # 此处设置日志文件大小为500MB,超过500MB自动开始写入新的日志文件,历史文件归档
    file_handler = RotatingFileHandler(
      filename=LOG_PATH_ALL,
      mode='a',
      maxBytes=LOG_FILE_MAX_BYTES,
      backupCount=LOG_FILE_BACKUP_COUNT,
      encoding='utf-8'
    )

    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    stream_handler = StreamHandler()
    stream_handler.setFormatter(formatter)
    stream_handler.setLevel(logging.INFO)

    for logger in (
        # 这里自己还可以添加更多的日志模块,具体请参阅Flask官方文档
        app.logger,
        logging.getLogger('sqlalchemy'),
        logging.getLogger('werkzeug')

    ):
      logger.addHandler(file_handler)
      logger.addHandler(stream_handler)

在exts.py扩展文件中添加log模块

# encoding: utf-8
from log import Logger

logger = Logger()

在app.py 文件中引入logger模块,这个文件是create_app的工厂模块。

# encoding: utf-8
from flask import Flask
from config import CONFIG
from exts import logger


def create_app():
  app = Flask(__name__)

  # 加载配置
  app.config.from_object(CONFIG)

    # 初始化logger
  logger.init_app(app)

  return app

运行run.py

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

from app import create_app

app = create_app()

if __name__ == '__main__':
  app.run()
$ python run.py
* Serving Flask app "app" (lazy loading)
* Environment: production
  WARNING: This is a development server. Do not use it in a production deployment.
  Use a production WSGI server instead.
* Debug mode: on
2019-07-08 08:15:50,396 [140735687508864:MainThread] [_internal.py:_internal:_log] [INFO]: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
2019-07-08 08:15:50,397 [140735687508864:MainThread] [_internal.py:_internal:_log] [INFO]: * Restarting with stat
2019-07-08 08:15:50,748 [140735687508864:MainThread] [_internal.py:_internal:_log] [WARNING]: * Debugger is active!
2019-07-08 08:15:50,755 [140735687508864:MainThread] [_internal.py:_internal:_log] [INFO]: * Debugger PIN: 234-828-739

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python深入学习之闭包
Aug 31 Python
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
Mar 31 Python
在Python 3中实现类型检查器的简单方法
Jul 03 Python
Python实现的中国剩余定理算法示例
Aug 05 Python
python 函数传参之传值还是传引用的分析
Sep 07 Python
pandas修改DataFrame列名的方法
Apr 08 Python
详解从Django Rest Framework响应中删除空字段
Jan 11 Python
Python网络爬虫之爬取微博热搜
Apr 18 Python
Python面向对象之继承原理与用法案例分析
Dec 31 Python
使用Keras加载含有自定义层或函数的模型操作
Jun 10 Python
pytorch Dropout过拟合的操作
May 27 Python
python实现简易自习室座位预约系统
Jun 30 Python
Django中如何使用sass的方法步骤
Jul 09 #Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
Jul 08 #Python
使用python socket分发大文件的实现方法
Jul 08 #Python
python查看文件大小和文件夹内容的方法
Jul 08 #Python
python 搜索大文件的实例代码
Jul 08 #Python
代码实例讲解python3的编码问题
Jul 08 #Python
Python参数类型以及常见的坑详解
Jul 08 #Python
You might like
Javascript实例教程(19) 使用HoTMetal(3)
2006/12/23 Javascript
JavaScript 学习笔记(七)字符串的连接
2009/12/31 Javascript
extjs之去除s.gif的影响
2010/12/25 Javascript
jQuery常见开发技巧详细整理
2013/01/02 Javascript
JavaScript栏目列表隐藏/显示简单实现
2013/04/03 Javascript
jQuery插件HighCharts绘制2D半圆环图效果示例【附demo源码下载】
2017/03/09 Javascript
angular过滤器实现排序功能
2017/06/27 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
Vuejs实现购物车功能
2017/11/05 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
2019/07/08 Javascript
JavaScript图片旋转效果实现方法详解
2020/06/28 Javascript
JS判断数组四种实现方法详解
2020/06/29 Javascript
简单介绍Python中利用生成器实现的并发编程
2015/05/04 Python
python计算圆周率pi的方法
2015/07/11 Python
python实现多线程抓取知乎用户
2016/12/12 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
django 2.0更新的10条注意事项总结
2018/01/05 Python
分析python动态规划的递归、非递归实现
2018/03/04 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
Python从使用线程到使用async/await的深入讲解
2018/09/16 Python
Python学习笔记之变量、自定义函数用法示例
2019/05/28 Python
用openCV和Python 实现图片对比,并标识出不同点的方式
2019/12/19 Python
Python使用configparser库读取配置文件
2020/02/22 Python
使用canvas绘制超炫时钟
2014/12/17 HTML / CSS
Zavvi荷兰:英国大型音像制品和图书游戏零售商
2018/03/22 全球购物
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
Linux文件操作命令都有哪些
2015/02/27 面试题
班级标语大全
2014/06/21 职场文书
高中综合实践活动总结
2014/07/07 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
高中生第一学年自我鉴定2015
2014/09/28 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
劳动保障事务所个人工作总结
2015/08/12 职场文书
2016年“5.12”护士节慰问信
2015/11/30 职场文书
幼儿教师三分钟演讲稿
2019/06/21 职场文书
windows安装 redis 6.2.6最新步骤详解
2022/04/26 Redis