前言
许多程序都有需要记录日志的需求,在运维工作中,记录并查看日志是一项重要的工作,甚至有相关的岗位专用管理日志,可见程序的记录的日志的重要性,在python运行中,有正常的访问日志,还可能有错误日志,警告日志等,所以python提供了一个logging模块,专门用于处理日志,可以定制化你的日志需求。
日志级别
级别 | 意义 |
---|---|
debug() | 诊断级别,最详细的记录 |
info() | 信息级别 |
warning() | 警告 |
error() | 错误 |
critical() | 严重 |
基本用法
import logging
logging.warning("Last login: Tue Jun 9 08:35:15 2020 from 10.224.71.5")
logging.critical("Last login: Tue Jun 9 08:35:15 2020 from 10.224.71.5")
"""
WARNING:root:Last login: Tue Jun 9 08:35:15 2020 from 10.224.71.5
CRITICAL:root:Last login: Tue Jun 9 08:35:15 2020 from 10.224.71.5
"""
五个级别简单用法–直接输出
import logging
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
"""
WARNING:root:Warning Message
ERROR:root:Error Message
CRITICAL:root:Critical Message
"""
初步结论
- 默认情况下,输出方式为标准输出(输出到屏幕)
- 默认情况下,只显示级别大于warnning的级别的日志。
- 默认情况下,输出的格式为“级别:日志消息”
高级用法
自定义配置日志级别–logging.basicConfig(level=logging.DEBUG)
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
"""
DEBUG:root:Debug Message
INFO:root:Info Message
WARNING:root:Warning Message
ERROR:root:Error Message
CRITICAL:root:Critical Message
"""
结论
当定义的级别为DEBUG时,只要比DEBUG级别更高的级别的日志均会输出。
自定义配置日志格式
import logging
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s"
)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
"""
2020-06-09 20:53:18,548 test.py[line:6] DEBUG Debug Message
2020-06-09 20:53:18,548 test.py[line:7] INFO Info Message
2020-06-09 20:53:18,548 test.py[line:8] WARNING Warning Message
2020-06-09 20:53:18,548 test.py[line:9] ERROR Error Message
2020-06-09 20:53:18,548 test.py[line:10] CRITICAL Critical Message
"""
自定义配置日志输出位置
import logging
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
filename="test.log"
)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
基本结论
无屏幕输出,直接输出到文件中,在本示例中,并未加文件路径,所以会直接在程序运行目录中进行输出文件
其它自定义
日志时间格式自定义
import logging
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
#filename="test.log",
datefmt="%a, %d %b %Y %H:%M:%S"
)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
日志文件读写模式自定义
“w”模式-覆盖写模式
import logging
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
filename="test.log",
datefmt="%a, %d %b %Y %H:%M:%S",
filemode="w"
)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
结论:覆盖写,每次都把内容全部删除后从文件最开始写
“a”模式-追加写模式
import logging
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
filename="test.log",
datefmt="%a, %d %b %Y %H:%M:%S",
filemode="a"
)
logging.debug("Debug Message")
logging.info("Info Message")
logging.warning("Warning Message")
logging.error("Error Message")
logging.critical("Critical Message")
结论:追加写,写入日志文件前,把光标定位到文件最尾部,然后再写,不断的往文件后追加日志条目。
logging.basicConfig()的可用参数
参数 | 意义 |
---|---|
filename | 用指定文件名创建FileHandler,这样日志会被存储在指定的文件中 |
filemode | 文件的打开方式,在指定了filename时使用这个参数,默认值为“a”,还可以指定为“w” |
format | 指定handler使用的日志显示格式 |
datefmt | 指定日期显示格式 |
level | 设置rootlogger的日志级别 |
stream | 用指定的stream创建StreamHandler.可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr,同时列出了filename和stream两个参数,则stream参数会被忽略 |
format参数中可用的格式
参数 | 意义 |
---|---|
%(name) | Logger的名称 |
%(levelno)s | 数字形式的日志级别 |
%(levelname)s | 文本形式的日志级别 |
%(pathname)s | 调用日志输出函数的模块的完整路径名,可以没有 |
%(filename)s | 调用日志输出函数的模块的文件名 |
%(module)s | 调用日志输出函数的模块名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 调用日志输出函数的语句所在的代码行 |
%(created)f | 当前时间,用UNIX标准的表示时间浮点数表示 |
%(relativeCreated)d | 输出日志信息时,自Logger创建以来的毫秒数 |
%(asctime)s | 字符串形式的当前时间。默认格式是“2003-07-08 20:20:20.300”,逗号后面是毫秒。 |
%(thread)d | 线程ID。可以没有 |
%(threadName)s | 线程名。可以没有 |
%(processs)d | 进程ID,可能没有 |
%(message)s | 用户输出的消息 |
logger
从上述例子中可以了解到
logging.debug()
logging.info()
logging.warning()
logging.error()
logging.critical()
这几个用于记录不同级别的日志信息
logging.basicConfig()
用默认的日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到rootlogger(根Logger)中。这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)
查看getLogger对象
import logging
print(logging.getLogger())
"""
<RootLogger root (WARNING)>
"""
可以看到为RootLogger
自定义Logger(即记录到文件,又屏幕输出)
import logging
logger = logging.getLogger("testlog")
print(logger)
#创建两个handler,一个用记将日志记录到文件的handler,另外一个用于流式输出的handler(输出给控制台)
filehandler = logging.FileHandler(r"D:\temp\file.log")
streamhandler = logging.StreamHandler()
#定义日志记录的格式
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#设置handler的日志记录格式。
filehandler.setFormatter(formatter)
streamhandler.setFormatter(formatter)
#最后添加这两个handler
logger.addHandler(filehandler)
logger.addHandler(streamhandler)
logger.setLevel(logging.DEBUG)
#定义日志输出
logger.debug("DEBUG Message")
logger.info("info Message")
logger.warning("warnning Message")
logger.error("error Message")
logger.critical("critical Message")
"""
<Logger testlog (WARNING)>
2020-06-11 16:51:43,212 - testlog - DEBUG - DEBUG Message
2020-06-11 16:51:43,212 - testlog - INFO - info Message
2020-06-11 16:51:43,212 - testlog - WARNING - warnning Message
2020-06-11 16:51:43,212 - testlog - ERROR - error Message
2020-06-11 16:51:43,212 - testlog - CRITICAL - critical Message
"""