程序运行的日志能够有效的帮助我们查看程序运行的情况。python 内置的日志模块是 logging,通过它能够有效的记录 python 程序运行的情况。
日志例子 编写一个日志的例子,保存到 /workspace/proj-pf/common-scripts/monitor.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 import loggingimport timefrom datetime import datetimefrom logging import handlersclass MyLogger (object ): 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() stream_handler.setFormatter(formatter) file_handler = handlers.TimedRotatingFileHandler( filename=log_name, when=when, backupCount=max_backup, encoding="utf-8" ) file_handler.setFormatter(formatter) 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: logger.error(str (e)) i += 1 logger.info("Done!" ) if __name__ == "__main__" : main()
执行该程序:
1 2 cd /workspace/proj-pf/common-scripts/ python monitor.py
控制台结果输出:
1 2 3 4 5 6 7 8 9 10 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
线程名称
参考文献
Python之日志处理(logging模块)
日志常用指引