Python日志—Python日志模块logging介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python日志—Python日志模块logging介绍相关的知识,希望对你有一定的参考价值。

参考技术A 从事与软件相关工作的人,应该都听过“日志”一词。

日志就是跟踪软件运行时事件的方法,为了能够在程序运行过程中记录错误。

通过日志记录程序的运行,方便我们查询信息,以便追踪问题、进行维护和调试、还是数据分析。

并且各编程语言都形成了各自的日志体系和相应的框架。

日志的作用总结:

首先我们要树立一个观点,那就是“不是为了记录日志而记录日志,日志也不是随意记的”。要实现能够只通过日志文件还原整个程序执行的过程,达到能透明地看到程序里执行情况,每个线程每个过程到底执行结果的目的。日志就像飞机的黑匣子一样,应当能够复原异常的整个现场乃至细节。

在项目中,日志这个功能非常重要,我们要重视起来。

在Python中,使用logging模块来进行日志的处理。

logging是Python的内置模块,主要用于将日志信息进行格式化内容输出,可将格式化内容输出到文件,也可输出到屏幕。

我们在开发过程中,常用print()函数来进行调试,但是在实际应用的部署时,我们要将日志信息输出到文件中,方便后续查找以及备份。

在我们使用日志管理时,我们也可以将日志格式化成Json对象转存到ELK中方便图形化查看及管理。

logging模块将日志系统从高向低依次定义了四个类,分别是logger(日志器)、handler(处理器)、filter(过滤器)和formatter(格式器)。其中由日志器生成的实例将接管原本日志记录函数logging.log的功能。

说明:

我们先来思考下下面的两个问题:

在软件开发阶段或部署开发环境时,为了尽可能详细的查看应用程序的运行状态来保证上线后的稳定性,我们可能需要把该应用程序所有的运行日志全部记录下来进行分析,这是非常耗费机器性能的。

当应用程序正式发布或在生产环境部署应用程序时,我们通常只需要记录应用程序的异常信息、错误信息等,这样既可以减小服务器的I/O压力,也可以避免我们在排查故障时被淹没在日志的海洋里。

那么怎样才能在不改动应用程序代码的情况下,根据事件的重要性或者称之为等级,实现在不同的环境中,记录不同详细程度的日志呢?

这就是日志等级的作用了,我们通过配置文件指定我们需要的日志等级就可以了。

说明:

总结:

开发应用程序时或部署开发环境时,可以使用DEBUG或INFO级别的日志获取尽可能详细的日志信息,可以方便进行开发或部署调试。 应用上线或部署生产环境时,应用使用WARNING或ERROR或CRITICAL级别的日志,来降低机器的I/O压力和提高获取错误日志信息的效率。 日志级别的指定通常都是在应用程序的配置文件中进行指定的。 不同的应用程序所定义的日志等级会有所差别,根据实际需求来决定。

python----日志模块loggin的使用,按日志级别分类写入文件

1、日志的级别

日志一共分为5个等级,从低到高分别是:

级别说明
DEBUG 输出详细的运行情况,主要用于调试。
INFO 确认一切按预期运行,一般用于输出重要运行情况。
WARNING 系统运行时出现未知的事情(如:警告内存空间不足),但是软件还可以继续运行,可能以后运行时会出现问题。
ERROR 系统运行时发生了错误,但是还可以继续运行。
CRITICAL

一个严重的错误,表明程序本身可能无法继续运行。

 

 

 

 

 

 

 

 

这5个等级,也分别对应5种打印日志的方法:debug、info、warning、error、critical。默认的日志收集器是收集WARNING以上等级的日志。

2、日志文件分类存储代码,创建文件login_demo02.py

import logging
class log:
    def __init__(self):
        # 创建自己的日志收集器
        self.my_log = logging.getLogger("my_log")
        # 设置收集的日志等级,设置为DEBUG等级
        self.my_log.setLevel("DEBUG")
         # 日志输出渠道
        # 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
        self.l_s = logging.StreamHandler()
        self.l_s.setLevel("DEBUG")
        # 创构建一个日志输出渠道(输出到文件)
        l_f = logging.FileHandler("error.log",encoding=\'utf8\')
        l_f.setLevel("ERROR")#设置输出的日志等级为ERROR以上
        l_d=logging.FileHandler("debug.log",encoding=\'utf-8\')
        l_d.setLevel("DEBUG")#设置输出的日志等级为DEBUG以上
        cc=logging.FileHandler("info.log",encoding=\'utf-8\')
        cc.setLevel("INFO")#设置输出的日志等级为INFO以上
        #将日志输出渠道添加到日志收集器中
        self.my_log.addHandler(self.l_s)
        self.my_log.addHandler(l_f)
        self.my_log.addHandler(l_d)
        self.my_log.addHandler(cc)
        # 设置日志输出的格式
        # 可以通过logging.Formatter指定日志的输出格式,这个参数可以输出很多有用的信息,如下:
        # % (name)s: 收集器名称
        # % (levelno)s: 打印日志级别的数值
        # % (levelname)s: 打印日志级别名称
        # % (pathname)s: 打印当前执行程序的路径,其实就是sys.argv()
        # % (filename)s: 打印当前执行程序名
        # % (funcName)s: 打印日志的当前函数
        # % (lineno)d: 打印日志的当前行号
        # % (asctime)s: 打印日志的时间
        # % (thread) d: 打印线程ID 
        # % (threadName)s: 打印线程名称
        # % (process) d: 打印进程ID
        # % (message) s: 打印日志信息
        ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"#工作中常用的日志格式
        ft = logging.Formatter(ft)
        # 设置控制台和日志文件输出日志的格式
        self.l_s.setFormatter(ft)
        l_f.setFormatter(ft)
        l_d.setFormatter(ft)
        cc.setFormatter(ft)
if __name__ == \'__main__\': my_log=log().my_log ss="一条小日志" my_log.info(ss) my_log.debug(ss) my_log.error(ss)

运行结果如下:

 

 

 

 3、其他文件调用

from login_demo02 import *

my_log=log().my_log
cc="这是一条日志"
my_log.debug(cc)
my_log.info(cc)
my_log.error(cc)

运行结果:

 使用日志配置进行日志保存:

创建log.conf文件,内容如下:

[loggers]
keys=root,infoLogger

[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler

[logger_infoLogger]
handlers=consoleHandler,fileHandler
qualname=infoLogger
propagate=0

[handlers]
keys=consoleHandler,fileHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form01
args=(\'../log/infolog/info.log\', \'a\')

[formatters]
keys=form01,form02

[formatter_form01]
format=>%(asctime)s | %(levelname)s |%(filename)s.%(funcName)s-->line:%(lineno)d: %(message)s

[formatter_form02]
format=>%(asctime)s | %(levelname)s |%(filename)s.%(funcName)s-->line:%(lineno)d: %(message)s

代码如下:

import logging
from logging import config
class MyLog(object):
 def __init__(self):
  config.fileConfig(\'../config/log.conf\')
  self.logger = logging.getLogger()
 @property
 def my_logger(self):
  return self.logger
if __name__ == \'__main__\':
 log = MyLog()
 log.my_logger.info(\'it is my test log message info\')

 

 

 

 配置参考:https://www.jb51.net/article/190556.htm

以上是关于Python日志—Python日志模块logging介绍的主要内容,如果未能解决你的问题,请参考以下文章

Python日志模块之你还在用PRINT打印日志吗

Python日志模块之你还在用PRINT打印日志吗

Python基础语法 - logging

python文件操作

python logging 模块

python第二十天