【Python】—日志模块logging使用详解1
文章目录
- 1、日志级别
- 2、logging流程
- 3、几个重要的类
- 3.1 Logger类
- 1) 最常用的配置方法
- 2) 创建`Logger`对象`logging.getLogger([name])`
- 3.2 `Handler`类
- 3.3 `Filter`类
- 3.4 `Formatter`类
- 4. 使用示例
- 4.1 直接调用`logging`接口
- 4.2 使用`basicConfig()`函数
- 4.3 一步步配置`Logger`
- 4.4 通过`dictConfig`配置
- 4.4.1 `dictConfig()`
- 4.4.2 配置规则
- 4.4.3 配置示例
开发部署项目时,不可能将所有的信息都输出到控制台中,因此我们将这些信息记录到日志文件中,不仅方便查看程序运行的情况,也可以在项目出现故障时根据该运行时产生的日志快速定位问题。
Python
中提供了日志模块logging
,可以方便的记录日志信息。
本文主要分析了
logging
模块的相关知识及具体使用。
当前介绍该日志模块的文章有很多,之所以还要进行记录,一方面是因为没有看到系统的介绍,二是通过梳理此部分内容,做到不止会用,还明白内部函数调用。
1、日志级别
Python
标准库logging
用做记录日志,默认分为五种日志级别:
DEBUG(10)
:详细信息,调试问题时所需INFO(20)
:证明事情可按预期工作WARNING(30)
:有意外,将来可能发生问题,但依然可用ERROR(40)
:严重问题,程序不能执行一些功能CRITICAL(50)
:严重错误
我们自定义日志级别时注意不要和默认的日志级别数值型相同(这是什么意思呢),logging
执行时输出大于等于设置的值日级别的日志信息,如设置级别为INFO,则INFO, WARNING, ERROR, CRITICAL级别的日志都会输出。
5种等级分别对应5种日志打印方法:debug, info, warning, error, critical
。
默认的是WARNING
,即当等级大于等于WARNING
才被跟踪。
2、logging流程
官方的logging
模块工作流程图如下:
logging流程图
从上图中可以看到这几种python类型,Logger, LogRecord, Filter, Handler, Formatter
。
类型说明
Logger
:日志,暴露函数给应用程序,基于日志记录器和过滤器级别决定哪些日志有效。LogRecord
:日志记录器,将日志传到相应的处理器处理。Handler
:处理器,将(日志记录器产生的)日志记录发送至合适的目的地。Filter
:过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。Formatter
:格式化器,指明了最终输出中日志记录的布局。
基本流程:
- 判断
Logger
对象对于设置的级别是否可用,如果可用,则往下执行,否则,流程结束。 - 创建
LogRecord
对象,如果注册到Logger
对象中的Filter
对象过滤后返回False, 则不记录日志,流程结束,否则,向下执行。 LogRecord
对象将Handler
对象传入当前的Logger
对象,(图中子流程)如果Handler
对象的日志级别大于设置的日记级别,再判断注册到Handler
对象中的Filter
对象过滤后是否返回True而放行输出日志信息,否则不放行,流程结束。- 如果传入的
Handler
大于Logger
中设置的级别,也即Handler
有效,则往下执行,否则,流程结束。 - 判断这个
Logger
对象是否还有父Logger
对象,如果没有(代表当前Logger
对象是最顶层的Logger
对象root Logger
),流程结束。否则将Logger
对象设置为它的父Logger
对象,重复上面3,4两步,输出父类Logger
对象中的日志输出,直到是root Logger
对象。
3、几个重要的类
前面讲logging
流程的时候,提到几个概念:Logger
,Handler
,Filter
,Formatter
。
3.1 Logger类
Logger
对象有3个任务要做:
- 向应用程序代码暴露
info, debug
等方法,使应用程序可以在运行时记录日志消息 - 基于日志级别(默认的过滤设施)或
Filter
对象来决定要对哪些日志进行后续处理 - 将日志消息传送给所有感兴趣的日志
handlers
一个系统只有一个根Logger
对象,并且该对象不能被直接实例化。
通过调用
logging.getLogger(name)
函数创建Logger
类对象。
Logger
对象最常用的方法有两类:(1)配置方法,(2)消息发送方法
Logger
对象可以设置多个Handler
对象和Filter
对象,Handler
对象可以设置Formatter
对象。
Formatter
对象用来设置消息的具体输出格式。
1) 最常用的配置方法
方法 | 描述 |
---|---|
Logger.setLevel
|
设置日志器将会处理的日志消息的最低严重级别 |
Logger.addHandler()
|
为该Logger 对象添加一个handler 对象
|
Logger.removeHandler
|
为该Logger 对象移除一个handler 对象
|
Logger.addFilter()和Logger.removeFilter()
|
为该Logger 对象添加 和 移除一个filter 对象
|
logger
对象配置完成后,可使用下面的方法来创建日志记录:
Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), Logger.critical()
:创建一个与他们的方法名对应等级的日志记录Logger.exception()
:创建一个类似于Logger.error()
的日志消息Logger.log()
:需要获取一个明确的日志level参数来创建一个日志记录
1. 获取Logger
对象
通常是通过--logging.getLogger()
的方法。该方法有一个可选参数name
,该参数表示将要返回的日志器的名称标识,如果不提供该参数,则其值为root
。
若以相同的name
参数值多次调用getLogger()
方法,将会返回指向同一个Logger
对象的引用。
2. logger的层级结构与有效等级
logger
的名称是一个以'.'
分割的层级结构,每个'.'
后面的logger
都是’.'前面的logger的children
,例如,有一个名称为foo
的logger
,其它名称分别为foo.bar, foo.bar.baz
和foo.bam
都是foo
的后代。logger
有一个"有效等级(effective level
)"的概念。如果一个logger上没有被明确设置一个level,那么该logger就是使用它parent的level;如果它的parent
也没有明确设置level
则继续向上查找parent
的parent
的有效level
,依次类推,直到找到个一个明确设置了level
的祖先为止。需要说明的是,root logger
总是会有一个明确的level
设置(默认为WARNING
)。当决定是否去处理一个已发生的事件时,logger
的有效等级将会被用来决定是否将该事件传递给该logger
的handlers
进行处理。child loggers
在完成对日志消息的处理后,默认会将日志消息传递给与它们的祖先loggers
相关的handlers
。因此,我们不必为一个应用程序中所使用的所有loggers定义和配置handlers,只需要为一个顶层的logger
配置handlers
,然后按照需要创建child loggers就可足够了。我们也可以通过将一个logger的propagate属性设置为False来关闭这种传递机制。
2) 创建Logger
对象logging.getLogger([name])
日志记录的工作主要由Logger
对象来完成。前面讲到一个系统只有一个根Logger
对象,并且该对象不能被直接实例化。
需要通过logging.getLogger([name])
来获取Logger
对象。
在调用getLogger
时要提供Logger
的名称(多次使用相同名称来调用getLogger,返回的是同一个对象的引用。),Logger
实例之间有层次关系,这些关系通过Logger
名称来体现。
p = logging.getLogger(“root”)
c1 = logging.getLogger(“root.c1”)
c2 = logging.getLogger(“root.c2”)
例子中,p
是父logger
, c1,c2
分别是p的子logger
。c1, c2
将继承p
的设置。如果省略了name
参数, getLogger
将返回日志对象层次关系中的根Logger
。
每个Logger
对象都可以设置一个名字,如果设置logger = logging.getLogger(__name__)
,__name__
是Python
中的一个特殊内置变量,他代表当前模块的名称(默认为__main__
)。
该函数内部根据是否指定名称返回对应的Logger对象。
root = RootLogger(WARNING)
Logger.root = root
Logger.manager = Manager(Logger.root)def getLogger(name=None):"""Return a logger with the specified name, creating it if necessary.If no name is specified, return the root logger."""if name:return Logger.manager.getLogger(name)else:return root
示例:
import logging
logger = logging.getLogger('test')
logger.warning('this is a warning info')
# 输出
WARNING:test:this is a warning info
3.2 Handler
类
Handler
对象的作用是(基于日志消息的等级)将消息分发到handler
指定的位置(文件、网络、邮件等)。Logger
对象可以通过addHandler()
方法为自己添加handler
对象。
应用程序代码不应该直接实例化和使用
Handler
实例。因为Handler
是一个基类,只定义了所有handlers
都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。常用接口有:
setLevel()
setFormatter()
set_name()
常用的Handler
:
Handler | 描述 |
---|---|
logging.StreamHandler
|
将日志消息发送到输出到Stream ,如std.out, std.err 或任何file-like 对象。
|
logging.FileHandler
|
将日志消息发送到磁盘文件,默认情况下文件大小会无限增长 |
logging.handlers.RotatingFileHandler
|
将日志消息发送到磁盘文件,并支持日志文件按大小切割 |
logging.hanlders.TimedRotatingFileHandler
|
将日志消息发送到磁盘文件,并支持日志文件按时间切割 |
logging.handlers.HTTPHandler
|
将日志消息以GET 或POST 的方式发送给一个HTTP 服务器
|
logging.handlers.SMTPHandler
|
将日志消息发送给一个指定的email地址 |
logging.NullHandler
|
该Handler 实例会忽略error messages ,通常被想使用logging 的library 开发者使用来避免'No handlers could be found for logger XXX' 信息的出现。
|
类之间的继承关系如下:
示例:
import logginglogger = logging.getLogging() # 获取Logger对象
handler = logging.FileHandler('output.log', mode='a', encoding=None, delay=False)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S',style='%')
handler.setFormatter(formatter) # handler对象设置格式
handler.setLevel(logging.DEBUG)# handler设置日志级别logger.addHandler(handler) # 添加handler对象
3.3 Filter
类
Filter
实例用于执行日志记录的任意筛选。
Loggers
和Handlers
可以根据需要使用筛选器实例筛选记录.
logging
标准库只提供了一个base filter
,其构造函数__init__
接收name
,默认的行为是名为name
的logger
及其子logger
的消息能通过过滤器,其余的被过滤掉。
class Filter(object):"""Filter instances are used to perform arbitrary filtering of LogRecords."""def __init__(self, name=''):"""Initialize a filter.Initialize with the name of the logger which, together with itschildren, will have its events allowed through the filter. If noname is specified, allow every event."""self.name = nameself.nlen = len(name)
3.4 Formatter
类
Formatter
对象用于配置日志信息的最终顺序、结构和内容。与logging.Handler
基类不同的是,应用代码可以直接实例化Formatter
类。
Formatter
类的构造方法定义如下:
logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
该方法可接收3个可选参数:
fmt
:指定消息格式化字符串,如果不指定该参数则默认使用message
的原始值datefmt
:指定日期格式字符串,如果不指定,则默认使用"%Y-%m-%d %H:%M:%S"
style
:可取值为'%', '{'和'$'
,如果不指定,则默认使用'%'
格式 | 含义 |
---|---|
%(levelno)s
|
打印日志级别的数值 |
%(levelname)s
|
打印日志级别名称 |
%(pathname)s
|
打印当前执行程序的路径 |
%(filename)s
|
打印当前执行程序名 |
%(funcName)s
|
打印日志的当前函数 |
%(lineno)d
|
打印日志的当前行号 |
%(asctime)s
|
打印日志的时间 |
%(thread)d
|
打印线程ID |
%(message)s
|
打印日志信息 |
%(process)s
|
当前进程,进程ID |
%(module)s
|
调用日志输出函数的模块名,filename 的名称部分,不包含后缀
|
%(msecs)d
|
日志事件发生事件的毫秒部分。logging.basicConfig() 中用参数datefmt 将会去掉asctime 中产生的毫秒部分,可以用这个加上。
|
一般直接使用logging.Formatter(fmt, datefmt)
import logging
fmt = "%(asctime)s [%(filename)s:%(lineno)d] %(levelname)s: %(message)s"
datefmt="%Y-%m-%d %H:%M:%S"
logFormatter = logging.Formatter(fmt, datefmt)
4. 使用示例
该部分主要展示如何使用
logging
模块记录日志信息的使用方法。
默认的输出格式如下:
示例:
logging
模块如何使用呢?下面介绍几种常用的使用方式:
一是使用logging
的对外函数接口;二是使用basicConfig()
方法,该方法能够满足基本的使用需求;三是通过创建Logger
对象,可以进行更加复杂的处理。
4.1 直接调用logging
接口
最简单的使用方法,就是直接调用logging
标准库的接口,如logging.debug()
,logging.info()
等函数。
默认的日志级别是WARNING
,当等级大于等于WARNING
才被跟踪。
内部默认调用的是
root.log(level, mas)
函数
接口函数如下:
debug()
info()
warning()
error()
critical()
也可以直接使用同一接口logging.log()
,输入级别及具体信息。
log(level, msg)
:level
表示日志级别,输入日志级别对应的整数或代码,如下:CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
这些接口函数内部实际调用的都是Logger
类的对应函数。如果logger
没有handler
时,可默认调用basicConfig()
添加控制台handler
。
如,logging.info()
函数内部调用root.info()
函数,如下
def info(msg, *args, **kwargs):"""Log a message with severity 'INFO' on the root logger. If the logger hasno handlers, call basicConfig() to add a console handler with a pre-definedformat."""if len(root.handlers) == 0:basicConfig()root.info(msg, *args, **kwargs)
示例如下:
import logging
logging.warning('this is a warning info.')
logging.error('this is a error info.')
logging.debug('this is a debuginfo.')
# 输出
WARNING:root:this is a warning info.
ERROR:root:this is a error info.logging.log(20, 'this is a info msg.')
logging.log(30, 'this is a warn msg.')
# 输出:
WARNING:root:this is a warn msg.
记录具体异常信息
当发生异常时,直接使用无参数的debug(), info(), warning(), error(), critical()
方法并不能记录异常信息。
我们看一下各个接口的定义及参数:
# 普通接口
def warning(msg, *args, **kwargs)
# 内部调用如下函数:
self._log(WARNING, msg, args, **kwargs)# 统一接口
def log(level, msg, *args, **kwargs)
# 内部调用如下函数:
self._log(level, msg, args, **kwargs)# exception函数,参数中默认exc_info为True
def exception(msg, *args, exc_info=True, **kwargs):error(msg, *args, exc_info=exc_info, **kwargs)
# 内部调用如下函数:
self._log(ERROR, msg, args, **kwargs)
由上面代码可见,其内部都是调用函数Logger._log(level, msg, args, **kwargs)
。不同的是参数,如level
日志级别。
函数Logger._log()
的定义如下:
def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False)
可见,其除了level
, msg
以外,还有参数exc_info
。该参数用来控制是否打印具体信息。
函数exception()
就等于error(msg, exc_info=True)
因此:
记录异常信息的方法:
- 设置
exc_info
参数为True
,指示是否打印执行信息 - 或者使用
exception()
方法,同时记录当前的堆栈追踪(仅从异常处理程度调用此方法) - 还可以使用
log()
方法,但是要设置日志级别和exce_info
参数。
logger.log(level, msg, exc_info=True)
是各个接口函数的统一调用方式。
示例代码:
import logginglogging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
a = 5
b = 0
try:c = a / b
except Exception as e:# 下面三种方式三选一,推荐使用第一种logging.exception("Exception occurred")logging.error("Exception occurred", exc_info=True)logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)
输出文件test.log
的内容:
4.2 使用basicConfig()
函数
使用basicConfig()
方法就能够满足基本的使用需要,如果方法没有传入参数,会根据默认的配置创建Logger
对象,默认的日志级别被设置为 WARNING 。
默认的日志输出格式:
WARNING | root | message |
---|---|---|
日志级别 |
Logger 实例
|
日志信息 |
函数定义:
def basicConfig(**kwargs)
该函数可选的参数如下表所示:
参数名称 | 参数描述 |
---|---|
filename
|
日志输出到文件的文件名 |
filemode
|
文件模式,r[+] 、w[+] 、a[+]
|
format
|
日志输出的格式 |
datefmt
|
日志附带日期时间的格式 |
style
|
格式占位符,默认为“%” 和“{}”
|
level
|
设置日志输出级别 |
stream
|
定义输出流,用来初始化 StreamHandler 对象,不能和 filename 参数一起使用,否则会ValueError 异常
|
handles
|
定义处理器,用来创建Handler 对象,不能和filename,stream 参数一起使用,否则也会抛出ValueError 异常
|
stream
输出流不与filename
输出文件一起使用handler
处理器不与stream
输出流或filename
输出文件一起用- 即
stream
、filename
和handler
互相排斥- 若想将日志信息同时输出到文件和控制台,则需要使用
Logger
处理器增加对应的处理方法。
basicConfig()
方法可以实现将日志信息输出到文件中或者输出到定义的输出流中。
- 输出到文件中,可以通过
filename
参数,或者通过handler
处理器创建相应文件对象实现- 内部创建
FileHandle()
对象
- 内部创建
- 打印到输出流中,使用默认参数即可
- 内部创建
StreamHandler()
对象
- 内部创建
其中,format
指定输出的格式和内容,format
可以输出很多有用信息,具体格式见Formatter类
。
对 basicConfig()
的调用应该在 debug()
, info()
等的前面。因为它被设计为一次性的配置,只有第一次调用会进行操作,随后的调用不会产生有效操作。
该方法相当于显示调用basicConfig()
进行参数的配置,而直接调用logging.info()
接口函数,若没有handler
时,是隐式调用basicConfig()
的默认参数形式。
1)日志信息打印到输出流
import logging
# 直接调用basicConfig()函数,使用默认参数
logging.basicConfig()
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')# 输出:(默认级别是WARNING)
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message
2)格式化输出
格式化输出时间:
通过datefmt
参数可以格式化输出log
的时间。
常用的输出格式如下:
format = '%(asctime)s - %(filename)s[line:%(lineno)d]- %(levelname)s: %(message)s'
该格式可以输出日志的打印时间,输出模块及行号,日志级别和输出的日志内容。
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt = '%Y-%m-%d %I:%M:%S %p')
logging.warning('is when this event was occurred.')# 输出结果
2019-10-15 04:03:17 PM is when this event was occurred.
3) 将日志输出到指定文件
指定filename
, filemode
参数,可将日志内容输出到指定文件,示例代码如下:
import logginglogging.basicConfig(filename='test.log', filemode='w', format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
生成的日志文件test.log
,内容如下:
4.3 一步步配置Logger
basicConfig
函数提供了一种较为简便的使用日志的方式,如果想要获取更加复杂的使用,则需要自己一步步配置来实现。
配置逻辑:
- 一个
logger
对象可以添加多个handler
对象,通过addHandler()
函数 - 每个
handler
对象可以有一个Formatter
对象来指定格式,通过setFormatter()
函数 handler
和logger
对象都需要设置一个日志等级,通过setLevel()
函数- 根据需要
logger
和handler
对象可以添加多个Filter
对象,通过addFilter()
函数
示例:
import logginglogger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)handler = logging.FileHandler('output.log', mode='a', encoding=None, delay=False)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S',style='%')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
handler.set_name('output-log')logger.addHandler(handler)a=0
try:res = 100 / a
except:logger.error('Divisor is equal to 0.', exc_info=True)
将日志同时输出到屏幕和文件
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.DEBUG)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
handler.setFormatter(formatter)console = logging.StreamHandler()
console.setLevel(logging.INFO)logger.addHandler(handler)
logger.addHandler(console)logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
在log.txt
文件和控制台均可看到输出,控制台的输出,其中文件中内容(有格式)如下:
通过这段代码可以看出,logging
有一个日志处理的主对象(logger=logging.getLogger()
),其他的处理方法均是通过addHandler
添加进去。
4.4 通过dictConfig
配置
通过dictConfig
配置方法是通过python代码构建一个dict
对象,也可以通过JSON
或yaml
文件来进行配置。
这种方式使用起来更加灵活,强大。我们可以把很多的数据转换成自字典形式,然后将他们填充到一个配置字典中。
具体如何转换可以参考logging.config.py
文件。
4.4.1 dictConfig()
该函数可以从一个字典对象中获取日志配置信息,config
参数就是这个字典对象。
定义如下:
def dictConfig(config):"""Configure logging using a dictionary."""dictConfigClass(config).configure()
如使用YAML
格式的文件类配置(配置内容见下方示例),则使用示例:
import logging
import logging.config
import yamlwith open('logging.yml', 'r') as f_config:dict_cfg = yaml.load(f_config)
logging.config.dictConfig(dict_cfg)logger = logging.getLogger('console')
logger.debug('debug msg')
4.4.2 配置规则
key名称 | 描述 |
---|---|
version
|
必选项,整数值,表示配置格式版本,当前唯一可用值是1
|
formatters
|
可选项,其值是字典对象,该字典对象每个元素的key 为要定义的格式器名称,value 为格式器的配置信息组成的dict 。一般会配置format ,用于指定输出字符串的格式,datefmt 用于指定输出的时间字符串格式,默认为%Y-%m-%d %H:%M:%S 。
|
filters
|
可选项,其值是字典对象,该字典对象每个元素的key 为要定义的过滤器名称,value 为过滤器的配置信息组成的dict 。
|
handlers
|
可选项,其值是字典对象,该字典对象每个元素的key 为要定义的处理器名称,value 为处理器的配置信息组成的dict 。如class (必选项), formatter , filters 。其他配置信息将会传递给class 所指定的处理器类的构造函数。如使用logging.handlers.RotatingFileHandler ,使用maxBytes , backupCount 等参数。
|
loggers
|
可选项,其值是字典对象,该字典对象每个元素的key 为要定义的日志器名称,value 为日志器的配置信息组成的dict 。如level, handler, filter 等
|
root
|
可选项,这是root logger 的配置项,其值是字典对象。除非在定义其它logger 时明确指定propagate 值为no,否则root logger 定义的handlers 都会被作用到其它logger 上。
|
incremental
|
可选项,默认值为False 。该选项的意义在于,如果这里定义的对象已经存在,那么这里对这些对象的定义是否应用到已存在的对象上。值为False 表示,已存在的对象将会被重新定义。
|
具体配置结构如下所示:
version
: 必要参数,必须为1
incremental
:是否将此配置文件解释为现有配置的增量, 默认为False
disable_existing_loggers
:是否要禁用现有的非root logger
,默认为True
handlers
:字典形式class
:必须有,所使用的handler
类,如logging.handlers.RotatingFileHandler
level
:(可选),handler
的等级formatter
:(可选),当前handler
的formatter
的id
filters
:(可选),当前handler
的filters
的id
列表
loggers
:字典形式level
:(可选),logger
的等级propagate
:(可选):默认值为1,表示将消息传递给父logger
的handler
进行处理。filters
:(可选)handlers
:(可选) ,当前logger
的handlers
的id
列表qualname
:代码中使用logging.getLogger()
时,读取的就是qualname
这个选项。
root
:这是root logger
的配置项level
:日志等级handlers
:当前root logger
的handlers
的id
列表
4.4.3 配置示例
version:1
root:level:DEBUGhandlers:[filehandler, ]
loggers:console:level:WARNINGhandlers:[consolehandler,]propagate:1
handlers:filehandler:class:logging.FileHandlerfilename:logs/sys.loglevel:WARNINGformatter:fileformatterconsolehandler:class:logging.StreamHandlerstream:ext://sys.stdoutlevel:DEBUGformatter:consoleformatter
formatters:fileformatter:format:'%(asctime)s [%(name)s][%(levelname)s]:%(message)s'consoleformatter:format:'%(asctime)s[%(levelname)s]:%(message)s'
外部对象访问:外部对象是指不能直接进行访问,需要
import
导入的对象,这时候需要加一个ext://
前缀以便识别,然后系统就会import
这个前缀后面的内容。
参考资料:
Python日志库logging总结-可能是目前为止将logging库总结的最好的一篇文章
python基础学习十 logging模块详细使用【转载】 - louis_w - 博客园
Python之路(第十七篇)logging模块 - Nicholas- - 博客园
【Python】—日志模块logging使用详解1相关推荐
- Python日志模块logging高级用法
推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清华大学出版社,2020年6月第1次印刷,2021年12月第11次印刷,山东省一流 ...
- python logging模块的作用_【python】【logging】python日志模块logging常用功能
logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...
- python日志模块----logging
使用Python的logging模块能很好的帮我们完成程序的日志功能,其实它跟Java中的log4j有不少相似的地方.下面记录下今天学习到的logging的知识(因为有一些还没真正使用过,不知道是否说 ...
- python导入模块介绍_详解Python模块导入方法
python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...
- Python日志模块logging,这一篇就够了
橙好科技logging模块教程 文章目录 1-logging介绍 2-日志作用 3-日志配置basicConfig 3-日志级别level 4-日志格式format 4-输出日志到控制台 5-输出 ...
- python 日志模块 logging
如何使用python自带的 logging 模块实现日志功能 1.初始化一个logger对象 1)引入模块 import os import logging import sys 2)初始化变量,声明 ...
- Python:日志模块logging的应用
2019独角兽企业重金招聘Python工程师标准>>> 在Python中,上面以实现的和已经实现的,均可以使用logging模块迅速搞定,且仅仅只需要一个配置文件,两行代码,实现过程 ...
- Python Importlib模块与__import__详解
阅读目录 Importlib模块与__import__都可以通过过字符串来导入另外一个模块,但在用法上和本质上都有很大的不同. 以一个例子为证: 以下为我的工程目录结构: lib/test.py: - ...
- python argparse模块用法实例详解
转载自https://zhuanlan.zhihu.com/p/56922793 argsparse是python的命令行解析的标准模块,内置于python,不需要安装.这个库可以让我们直接在命令行中 ...
最新文章
- Spark之SQL解析(源码阅读十)
- Tensorflow:如何保存/恢复模型?
- drcom linux怎么运行,drcom for linux
- Al芯片前景看好,市场规模在2023年将达343亿美元
- QT入门语法——signal,slot
- 关于longlong与位运算
- 【SpringBoot零基础案例01】【IEDA 2021.1】如何创建一个SpringBoot框架web项目
- TCP发送接口(如send(),write()等)的返回值与成功发送到接收端的数据量无直接关系
- 2路由策略_route-map(执行路由策略)
- 【计算机网络复习 数据链路层】3.4.3 后退N帧协议(GBN)
- rman copy相关
- 【答辩问题】计算机专业本科毕业设计答辩问题
- 分享我用cnode社区api做微信小应用的入门过程
- Windows系统win10系统压缩解压软件推荐
- JS实现放大镜特效原理解析
- 如何使用奥特歌词制作双语LRC字幕
- 单芯片快速以太网MAC控制器DM9000介绍续
- matlab中taylor公式源代码,matlab实现两步taylor-galerkin算法
- 冒烟测试和回归测试的区别
- python地形图渲染_地形渲染之彩色地形图(Painted Relief Map)
热门文章
- 上下位机?透明传输?DTU相关小知识1分钟让你快速了解
- 烈焰服务器修改,烈焰服务器数据库设置
- css中hideFocus的用法(去除鼠标点击时的虚线)
- Bloom Filter原理及python实现
- php花边代码,用钩针锁个花边,简直美得不像话!100多款钩针花边,有图案图解(荐藏)...
- Python实现爬取移动端网页版微博用户信息及(部分)粉丝和(部分)关注信息(一)
- 15个实用实用正则(小哥进来看看?)
- PS设置并固定选区大小
- [IOS]How does uitableview cell remain highlighted?
- Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics)简训