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
    """
posted @ 2024-07-11 18:00  派森马  阅读(0)  评论(0编辑  收藏  举报