python模块之logging
logging模块主要是用于对日志文件进行处理的专用模块,实际工作中对于做运维的同学们来说是非常实用的。
下面就开始来看logging模块中都涉及了哪些方法,我也会用实际脚本来解释说明这些语法。everybody准备好了吗?我要开始传授你们这套降龙十八掌了。
基础的写日志的方法:
import logging
logging.debug('这是一条DEBUG日志信息')
logging.info('这是一条INFO日志信息')
logging.warning('这是一条WARNING日志信息')
logging.error('这是一条ERROR日志信息')
logging.critical('这是一条CRITICAL日志信息')
输出结果:
D:\python\python.exe D:/python/project/test_logging.py
WARNING:root:这是一条WARNING日志信息
ERROR:root:这是一条ERROR日志信息
CRITICAL:root:这是一条CRITICAL日志信息
Process finished with exit code 0
咦?发现什么问题了没有?我明明敲了5行代码,为什么只输出了3行呢?
记住:日志级别是debug < info < warning < error < critical,默认只输出warning及以上级别的日志信息。
那么问题来了,上面这段代码,我想让屏幕上输出所有的日志信息,应该怎么操作呢?
logging.basicConfig(**kwargs) -- 意味着可以字典方式传多个值
代码可以这么写:
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug('这是一条DEBUG日志信息')
logging.info('这是一条INFO日志信息')
logging.warning('这是一条WARNING日志信息')
logging.error('这是一条ERROR日志信息')
logging.critical('这是一条CRITICAL日志信息')
输出结果:
D:\python\python.exe D:/python/project/test_logging.py
DEBUG:root:这是一条DEBUG日志信息
INFO:root:这是一条INFO日志信息
WARNING:root:这是一条WARNING日志信息
ERROR:root:这是一条ERROR日志信息
CRITICAL:root:这是一条CRITICAL日志信息
Process finished with exit code 0
好吧,是不是很简单。现在我的需求又变了,不想把日志信息输出在屏幕上了,想直接写进日志文件中。
代码如下:
import logging
logging.basicConfig(
filename='logger.log',
filemode='w',
level=logging.DEBUG,
format='[%(lineno)d] %(asctime)s %(message)s '
)
logging.debug('这是一条DEBUG日志信息')
logging.info('这是一条INFO日志信息')
logging.warning('这是一条WARNING日志信息')
logging.error('这是一条ERROR日志信息')
logging.critical('这是一条CRITICAL日志信息')
屏幕输出结果:
D:\python\python.exe D:/python/project/test_logging.py
Process finished with exit code 0
写入日志文件内容:
[9] 2024-07-11 17:14:55,691 这是一条DEBUG日志信息
[10] 2024-07-11 17:14:55,691 这是一条INFO日志信息
[11] 2024-07-11 17:14:55,691 这是一条WARNING日志信息
[12] 2024-07-11 17:14:55,691 这是一条ERROR日志信息
[13] 2024-07-11 17:14:55,691 这是一条CRITICAL日志信息
你是不是以为这就结束了?哈哈,其实这不符合生产真实的场景,一般生产环境的程序都会是在记入日志的同时还要输出在屏幕下方。为了满足这个需求,前面的basicConfig方法就不够用了,那么这时候要用到对象的概念了,来吧,直接上代码:
#导入logging模块
import logging
#创建个logger对象
logger = logging.getLogger()
#定义logger的日志级别为DEBUG
logger.setLevel(logging.DEBUG)
#定义一个format格式
fmt = logging.Formatter("[%(lineno)d] %(asctime)s %(message)s")
#定义一个要写入的日志文件
file = "logger.log"
#定义写日志模式
filemode = 'w'
#定义写日志对象
fh = logging.FileHandler(file,filemode)
#定义屏幕输出对象
sh = logging.StreamHandler()
#让fh和sh两个对象拥有format格式化输出的功能
fh.setFormatter(fmt)
sh.setFormatter(fmt)
#定义fh和sh的日志级别
fh.setLevel(logging.DEBUG)
sh.setLevel(logging.INFO)
#把fh和sh传给logger对象
logger.addHandler(fh)
logger.addHandler(sh)
logger.debug('这是一条DEBUG日志信息')
logger.info('这是一条INFO日志信息')
logger.warning('这是一条WARNING日志信息')
logger.error('这是一条ERROR日志信息')
logger.critical('这是一条CRITICAL日志信息')
屏幕输出结果:
D:\python\python.exe D:/python/project/test_logging.py
[29] 2024-07-11 17:47:30,466 这是一条INFO日志信息
[30] 2024-07-11 17:47:30,466 这是一条WARNING日志信息
[31] 2024-07-11 17:47:30,466 这是一条ERROR日志信息
[32] 2024-07-11 17:47:30,466 这是一条CRITICAL日志信息
Process finished with exit code 0
写入日志文件内容:
[28] 2024-07-11 17:47:30,466 这是一条DEBUG日志信息
[29] 2024-07-11 17:47:30,466 这是一条INFO日志信息
[30] 2024-07-11 17:47:30,466 这是一条WARNING日志信息
[31] 2024-07-11 17:47:30,466 这是一条ERROR日志信息
[32] 2024-07-11 17:47:30,466 这是一条CRITICAL日志信息
上面的代码还可以继续优化下,写成函数便于调用。
优化后代码如下:
点击查看代码
def test_log():
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler(file,filemode)
sh = logging.StreamHandler()
fh.setFormatter(fmt)
sh.setFormatter(fmt)
fh.setLevel(logging.DEBUG)
sh.setLevel(logging.INFO)
logger.addHandler(fh)
logger.addHandler(sh)
logger.debug('这是一条DEBUG日志信息')
logger.info('这是一条INFO日志信息')
logger.warning('这是一条WARNING日志信息')
logger.error('这是一条ERROR日志信息')
logger.critical('这是一条CRITICAL日志信息')
if __name__ == '__main__':
import logging
logger = logging.getLogger()
fmt = logging.Formatter("[%(lineno)d] %(asctime)s %(message)s")
file = "logger.log"
filemode = 'w'
test_log()
下面是logging模块的各种方法,我就不再一一细说了,你们自己领悟吧!
def getLevelName(level):
"""
Return the textual representation of logging level 'level'.
If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
INFO, DEBUG) then you get the corresponding string. If you have
associated levels with names using addLevelName then the name you have
associated with 'level' is returned.
If a numeric value corresponding to one of the defined levels is passed
in, the corresponding string representation is returned.
Otherwise, the string "Level %s" % level is returned.
"""
def addLevelName(level, levelName):
"""
Associate 'levelName' with 'level'.
This is used when converting levels to text during message formatting.
"""
def getMessage(self):
"""
Return the message for this LogRecord.
Return the message for this LogRecord after merging any user-supplied
arguments with the message.
"""
def format(self, record):
"""
Format the specified record as text.
The record's attribute dictionary is used as the operand to a
string formatting operation which yields the returned string.
Before formatting the dictionary, a couple of preparatory steps
are carried out. The message attribute of the record is computed
using LogRecord.getMessage(). If the formatting string uses the
time (as determined by a call to usesTime(), formatTime() is
called to format the event time. If there is exception information,
it is formatted using formatException() and appended to the message.
"""
def setLevel(self, level):
"""
Set the logging level of this handler. level must be an int or a str.
"""
self.level = _checkLevel(level)
def setFormatter(self, fmt):
"""
Set the formatter for this handler.
"""
self.formatter = fmt
def flush(self):
"""
Ensure all logging output has been flushed.
This version does nothing and is intended to be implemented by
subclasses.
"""
pass
def close(self):
"""
Tidy up any resources used by the handler.
This version removes the handler from an internal map of handlers,
_handlers, which is used for handler lookup by name. Subclasses
should ensure that this gets called from overridden close()
methods.
"""
class StreamHandler(Handler):
"""
A handler class which writes logging records, appropriately formatted,
to a stream. Note that this class does not close the stream, as
sys.stdout or sys.stderr may be used.
"""
class FileHandler(StreamHandler):
"""
A handler class which writes formatted logging records to disk files.
"""
def __init__(self, filename, mode='a', encoding=None, delay=False):
"""
Open the specified file and use it as the stream for logging.
"""
def getLogger(self, name):
"""
Get a logger with the specified name (channel name), creating it
if it doesn't yet exist. This name is a dot-separated hierarchical
name, such as "a", "a.b", "a.b.c" or similar.
If a PlaceHolder existed for the specified name [i.e. the logger
didn't exist but a child of it did], replace it with the created
logger and fix up the parent/child references which pointed to the
placeholder to now point to the logger.
"""
def addHandler(self, hdlr):
"""
Add the specified handler to this logger.
"""
def basicConfig(**kwargs):
"""
Do basic configuration for the logging system.
This function does nothing if the root logger already has handlers
configured. It is a convenience method intended for use by simple scripts
to do one-shot configuration of the logging package.
The default behaviour is to create a StreamHandler which writes to
sys.stderr, set a formatter using the BASIC_FORMAT format string, and
add the handler to the root logger.
A number of optional keyword arguments may be specified, which can alter
the default behaviour.
filename Specifies that a FileHandler be created, using the specified
filename, rather than a StreamHandler.
filemode Specifies the mode to open the file, if filename is specified
(if filemode is unspecified, it defaults to 'a').
format Use the specified format string for the handler.
datefmt Use the specified date/time format.
style If a format string is specified, use this to specify the
type of format string (possible values '%', '{', '$', for
%-formatting, :meth:`str.format` and :class:`string.Template`
- defaults to '%').
level Set the root logger level to the specified level.
stream Use the specified stream to initialize the StreamHandler. Note
that this argument is incompatible with 'filename' - if both
are present, 'stream' is ignored.
handlers If specified, this should be an iterable of already created
handlers, which will be added to the root handler. Any handler
in the list which does not have a formatter assigned will be
assigned the formatter created in this function.
class Formatter(object):
"""
Formatter instances are used to convert a LogRecord to text.
Formatters need to know how a LogRecord is constructed. They are
responsible for converting a LogRecord to (usually) a string which can
be interpreted by either a human or an external system. The base Formatter
allows a formatting string to be specified. If none is supplied, the
default value of "%s(message)" is used.
The Formatter can be initialized with a format string which makes use of
knowledge of the LogRecord attributes - e.g. the default value mentioned
above makes use of the fact that the user's message and arguments are pre-
formatted into a LogRecord's message attribute. Currently, the useful
attributes in a LogRecord are described by:
%(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
"""
分类:
python笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫