1

python 日志管理

 1 year ago
source link: https://xujinzh.github.io/2023/01/19/python-logger/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

python 日志管理

2023-01-19technologypython

2 3.5k 3 分钟

程序运行的日志能够有效的帮助我们查看程序运行的情况。python 内置的日志模块是 logging,通过它能够有效的记录 python 程序运行的情况。

编写一个日志的例子,保存到 /workspace/proj-pf/common-scripts/monitor.py

import logging
import time
from datetime import datetime
from logging import handlers


class MyLogger(object):
# 5个日志级别
levels = {
"debug": logging.DEBUG,
"info": logging.INFO,
"warning": logging.WARNING,
"error": logging.ERROR,
"critical": logging.CRITICAL,
}

def __init__(
self,
log_name,
level="debug",
when="D",
max_backup=3,
formatter="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s",
):
formatter = logging.Formatter(formatter) # 日志输出格式

# 定义一个日志实例
self.logger = logging.getLogger() # 实例化一个日志(实例)
self.logger.setLevel(self.levels.get(level)) # 设置日志级别

# 定义控制台日志输出流
stream_handler = logging.StreamHandler() # 实例化一个输出日志到控制台的 handler
stream_handler.setFormatter(formatter) # 日志输出格式

# 定义文件日志输出流
file_handler = handlers.TimedRotatingFileHandler(
filename=log_name, when=when, backupCount=max_backup, encoding="utf-8"
) # 实例化一个输出日志到文件的 handler,以 when 为备份标识(D 天、H 小时、M 分、S 秒、W 每星期(interval==0时代表星期一)、midnight 每天凌晨),
# 最多存放备份 backupCount 个,超过的日志将会删除
file_handler.setFormatter(formatter) # 设置文件里写入的格式

# 把 handler 添加到日志实例中
self.logger.addHandler(stream_handler) # 把控制台输出流对象添加到 日志实例
self.logger.addHandler(file_handler) # 把文件输出流对象添加到 日志实例


def do(args, logger):
for j in args:
logger.info(f"j = {j}")


def main():
now = datetime.now().strftime("%Y%m%d-%H%M%S")
logger = MyLogger(log_name=f"run-{now}.log", level="debug").logger
i = 0
while i < 3:
logger.info(f"--- 监控到 i = {i} ---")
try:
do(range(2), logger)
except Exception as e:
# print(str(e))
logger.error(str(e))
i += 1
logger.info("Done!")


if __name__ == "__main__":
main()

执行该程序:

cd /workspace/proj-pf/common-scripts/
python monitor.py

控制台结果输出:

2023-01-19 15:49:09,026 - monitor.py[line:57] - INFO: --- 监控到 i = 0 ---
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 0
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 1
2023-01-19 15:49:09,026 - monitor.py[line:57] - INFO: --- 监控到 i = 1 ---
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 0
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 1
2023-01-19 15:49:09,026 - monitor.py[line:57] - INFO: --- 监控到 i = 2 ---
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 0
2023-01-19 15:49:09,026 - monitor.py[line:49] - INFO: j = 1
2023-01-19 15:49:09,026 - monitor.py[line:64] - INFO: Done!

同时,在目录 /workspace/proj-pf/common-scripts/ 下,有日志文件 run-20230119-154909.log 产生。对于监控程序,我们把 main 函数的 while 循环改为死循环,此时,生成的日志文件会最多包含 max_backup + 1 个,前 max_backup 个以我们设置的 when 标识,如: run-20230114-153542.log.2023-01-16, run-20230114-153542.log.2023-01-17, run-20230114-153542.log.2023-01-18 等。

字符串字段

输出的日志文件格式,可以根据需要自定义,常见字符段有:

字符段 格式(代码中输入该内容) 描述
asctime %(asctime)s 日志事件发生的时间–人类可读时间,如:2003-07-08 16:49:45,896
created %(created)f 日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值
relativeCreated %(relativeCreated)d 日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
msecs %(msecs)d 日志事件发生事件的毫秒部分
levelname %(levelname)s 该日志记录的文字形式的日志级别(’DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’)
levelno %(levelno)s 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
name %(name)s 所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger
message %(message)s 日志记录的文本内容,通过 msg % args计算得到的
pathname %(pathname)s 调用日志记录函数的源码文件的全路径
filename %(filename)s pathname的文件名部分,包含文件后缀
module %(module)s filename的名称部分,不包含后缀
lineno %(lineno)d 调用日志记录函数的源代码所在的行号
funcName %(funcName)s 调用日志记录函数的函数名
process %(process)d 进程ID
processName %(processName)s 进程名称,Python 3.1新增
thread %(thread)d 线程ID
threadName %(thread)s 线程名称

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK