前言

程序和脚本往往是无人值守运行的,一旦发生问题,就需要我们去追溯当时的情况来定位问题的原因。

这便需要我们在程序和脚本中引入日志的功能。

相比于print信息,使用logging日志有以下优点

可以记录输出日志的时间、文件、函数以及代码行,甚至线程名和线程号

可以分等级记录日志(调试级、信息级、警告级、错误级、严重错误级)

即可以实时输出到屏幕,也可以输出到文件

基本使用

Python中使用自带的logging模块输出日志,logging模块的主要组件为logger日志记录器,如下图。

基本使用如下

import logging

logging.debug('调试级别的日志')

logging.info('信息级别的日志')

logging.warning('警告级别的日志') # 或logging.warn('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

try:

1/0

except Exception as ex:

logging.exception(ex) # 错误级别的日志,显示多行回溯信息

运行结果为

WARNING:root:警告级别的日志

ERROR:root:错误级别的日志

CRITICAL:root:严重错误级别的日志

ERROR:root:division by zero

Traceback (most recent call last):

File "", line 9, in

1/0

ZeroDivisionError: division by zero

发现只显示warning、error、critical的日志,这是因为logging中的默认日志记录器(root logger)的level级别是logging.WARNING,即默认只显示警告级别以上的日志。

修改日志等级

我们可以使用logging.basicConfig来修改root logger的设置。

import logging

logging.basicConfig(level=logging.DEBUG) # 配置全局root logger

logging.debug('调试级别的日志')

logging.info('信息级别的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

再次运行,发现所有的日志都可以输出了。

level日志等级支持

logging.NOTSET: 未设置,输出所有级别的日志

logging.DEBUG: 调试级别,输出所有级别的日志

logging.INFO: 信息级别,输出包含信息级别以上的日志

logging.WARNING: 警告级别,输出包含警告级别的日志

logging.ERROR: 错误级别,输出包含错误级别以上的日志

logging.CRITICAL: 严重错误级别,仅输出严重错误日志

日志等级的关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET

修改日志格式

日志默认的格式为WARNING:root:警告级别的日志,即等级:Logger名称:输出消息。我们也可以在logging.basicConfig中使用format参数来修改其输出格式。

import logging

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s')

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

运行输出如下:

2020-11-04 10:11:49,238 - DEBUG - 调试级别的日志

2020-11-04 10:11:49,238 - INFO - 信息基本的日志

2020-11-04 10:11:49,238 - WARNING - 警告级别的日志

2020-11-04 10:11:49,238 - ERROR - 错误级别的日志

2020-11-04 10:11:49,238 - CRITICAL - 严重错误级别的日志

format中使用%(变量名)s这样的具名占位符,来输出不同的信息,其他的字符则原样显示。

支持的变量如下:

%(levelno)s: 打印日志级别的数值

%(levelname)s: 打印日志级别名称

%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]

%(filename)s: 打印当前执行程序名

%(funcName)s: 打印日志的当前函数

%(lineno)d: 打印日志的当前行号(因为是数字,所以使用%d)

%(asctime)s: 打印日志的时间

%(thread)d: 打印线程ID

%(threadName)s: 打印线程名称

%(process)d: 打印进程ID

%(message)s: 打印日志信息

对于日期,我们可以使用datefmt来修改,比如,将上例中的logging.basicConfig修改为

...

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S')

...

输出形式如下:

2020年11月04日 10:19:04 - DEBUG - 调试级别的日志

2020年11月04日 10:19:04 - INFO - 信息基本的日志

2020年11月04日 10:19:04 - WARNING - 警告级别的日志

2020年11月04日 10:19:04 - ERROR - 错误级别的日志

2020年11月04日 10:19:04 - CRITICAL - 严重错误级别的日志

输出到文件

日志是默认输出的屏幕的,也可以通过logging.basicConfig中的filename将日志输出到文件。

import logging

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S',

filename='run.log',

filemode='a'

)

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

运行后,日志将不会输出到屏幕,转而输出到文件中,filemode支持'w'每次覆盖和'a'追加模式。

自定义handlers

如果想即输出到屏幕又输出到文件,我们可以在logging.basicConfig的handlers参数中添加两个不同的handler来实现,logging.StreamHander()可以用于输出到屏幕,logging.FileHandler()可以用于输出到文件。

import logging

cli_handler = logging.StreamHandler() # 输出到屏幕的日志处理器

file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8') # 输出到文件的日志处理器

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s - %(levelname)s - %(message)s',

datefmt='%Y年%m月%d日 %H:%M:%S',

handlers=[cli_handler, file_handler] # 添加两个日志处理器

)

logging.debug('调试级别的日志')

logging.info('信息基本的日志')

logging.warning('警告级别的日志')

logging.error('错误级别的日志')

logging.critical('严重错误级别的日志')

这样便可以即输出到屏幕又输出到文件了。

自定义Logger

使用logging.basicConfig是直接配置全局的root logger,会对项目中所有的模块及三方包产生影响。

为了不影响其他模块和三方包的日志输出,我们可以使用自定义Logger,即日志记录器,基本步骤为

使用logging.getLogger()新建一个logger对象,并配置期日志等级(总日志开关)

新建多个日志处理器,分别设置其格式和日志等级

将多个日志处理器添加到logger中

代码如下

# 文件名: mylogger.py

import logging

def get_logger(name):

logger = logging.getLogger(name)

logger.setLevel(logging.DEBUG) # 设置总日志等级

format = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y年%m月%d日 %H:%M:%S') # 日志格式

cli_handler = logging.StreamHandler() # 输出到屏幕的日志处理器

file_handler = logging.FileHandler(filename='run.log', mode='a', encoding='utf-8') # 输出到文件的日志处理器

cli_handler.setFormatter(format) # 设置屏幕日志格式

file_handler.setFormatter(format) # 设置文件日志格式

cli_handler.setLevel(logging.INFO) # 设置屏幕日志等级, 可以大于日志记录器设置的总日志等级

# file_hander.setLevel(logging.DEBUG) # 不设置默认使用logger的等级

logger.handlers.clear() # 清空已有处理器, 避免继承了其他logger的已有处理器

logger.addHandler(cli_handler) # 将屏幕日志处理器添加到logger

logger.addHandler(file_handler) # 将文件日志处理器添加到logger

return logger

使用方式为,导入本模块的get_logger方法,使用logger代替logging打印各种信息。

from mylogger import get_logger

logger = get_logger('mylogger')

logger.debug('调试级别的日志')

logger.info('信息基本的日志')

logger.warning('警告级别的日志')

logger.error('错误级别的日志')

logger.critical('严重错误级别的日志')

注意:由于logger具有子模块继承性,在项目中多个地方使用get_logger生成不同的logger对象时,有可能会继承其他logger的处理器。建议项目中使用同一个logger。或者对日志记录器使用单例模式。

在服务端项目中(如web项目),由于进程是长久运行,可以使用滚动日志处理器来分割日志文件。

python大型项目中的日志模块_Python中日志模块的使用相关推荐

  1. python开源项目框架二次开发_Python中三大框架各自的应用场景(DJango,flask,Tornado)...

    django:主要是用来搞快速开发的,他的亮点就是快速开发,节约成本,正常的并发量不过10000,如果要实现高并发的话,就要对django进行二次开发,比如把整个笨重的框架给拆掉,自己写socket实 ...

  2. python日志模块_Python之日志处理(logging模块)

    转载自:https://www.cnblogs.com/yyds/p/6901864.html 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logg ...

  3. python写日志文件_Python logging日志模块 配置文件方式

    在一些微服务或web服务中我们难免需要日志功能,用来记录一些用户的登录记录,操作记录,以及一些程序的崩溃定位,执行访问定位等等; Python内置 非常强大的日志模块 ==> logging 今 ...

  4. python中自带的模块_python中的模块详解

    概念 python中的模块是什么?简而言之,在python中,一个文件(以".py"为后缀名的文件)就叫做一个模块,每一个模块在python里都被看做是一个独立的文件.模块可以被项 ...

  5. python安装django模块_python中安装django模块的方法

    网上搜一下对应的版本号,版本号相对应. 安装django有两种方式: 1.pip安装 pip install django 这个方法我用的时候已经报错.貌似访问被阻挡.我一般都用第二种 2.下载压缩包 ...

  6. python日志处理_Python之日志处理(logging模块)

    转发:https://www.cnblogs.com/yyds/p/6901864.html 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 loggi ...

  7. python logging日志分割_python logging日志模块以及多进程日志

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python ...

  8. 如何下载python模块_python中模块包的离线下载教程

    1.简介 当我们进行Python项目的迁移时(例如迁移到另外一台服务器上),如果该服务器要求离线安装, 往往需要我们将项目中的所需模块包进行离线操作. 2.教程 2.1 首先安装pip2pi模块,它可 ...

  9. python中常用的序列化模块_Python 中的序列化模块

    封面图片来源:沙沙野 序列化模块前面讲到解码编码的时候提过,网络数据传输只能通过 bytes 类型.而文件写入内容(不是指存储)既可以是 bytes,也可以是 string.这些操作都可以使用 eva ...

最新文章

  1. 找Java培训机构有哪些评判标准
  2. 2019-01-02
  3. linux系统源配置(根据自己理解编写,不当之处,敬请指教)
  4. 关于一些对location认识的误区(转)
  5. 文件下载的文件名中文乱码
  6. 与服务器传文件格式,客户端如何向服务器传文件格式
  7. CCNA之网络地址转换(NAT)简介
  8. Verify_Execute 验证SQL语句执行结果
  9. C# WPF ASP.net 上传多文件和数据
  10. noip模拟赛 SAC E#1 - 一道中档题 Factorial
  11. Android中的传感器之---陀螺仪传感器
  12. 建筑设计全过程碳排放计算与案例分析
  13. 瞳孔特征值提取,blink frequency,fixation frequency,saccad extent, pupil diameter等
  14. 惯导标定国内外研究现状小结(删减版)
  15. 猎头如何做大单,赚大钱?
  16. caffe make runtest 错误
  17. 消息循环中的TranslateMessage函数和DispatchMessage函数
  18. 怎么做接口自动化的?
  19. THC温湿度测控系统---系统分析与设计
  20. Description: A component required a bean of type ‘com.jia.dao.UserDao‘ that

热门文章

  1. asp.net core 1.1 项目升级至 asp.net core 2.0 preview 2
  2. 分布式统一配置平台-Disconf.Net
  3. java多线程同时运行_Java实现的两个线程同时运行案例
  4. EditPlus 文件查找功能:在指定文件夹,用正则查寻包含指定内容的文件,指定文件类型,并排除特殊文件名文件
  5. Android Studio之导入安卓项目gradle编译出现问题分析日志思路
  6. LeetCode之Reverse Integer
  7. Android之Gradle Plugin Samples 之Gradle Library Projects
  8. 三、界面介绍(IVX快速手册)
  9. python opencv 图像切割_【OpenCV+Python】图像的基本操作与算术运算
  10. 利用Deep Reinforcement Learning训练王者荣耀超强AI