目录
python将控制台输出另存为日志文件
需求
在 pycharm 中或者说运行 python 程序时会使用 print 输出些过程信息、 traceback 异常信息 到控制台,但是程序运行结束后记录就没有了,所以想着每次运行将信息显示在控制台的同时记录到文件中。
方法一:使用 logger 类(推荐)
自定义创建 logger 类,结合 sys 进行记录控制台输出信息
demo.py
import sys import os import time # 控制台输出记录到文件 class logger(object): def __init__(self, file_name="default.log", stream=sys.stdout): self.terminal = stream self.log = open(file_name, "a") def write(self, message): self.terminal.write(message) self.log.write(message) def flush(self): pass if __name__ == '__main__': # 自定义目录存放日志文件 log_path = './logs/' if not os.path.exists(log_path): os.makedirs(log_path) # 日志文件名按照程序运行时间设置 log_file_name = log_path 'log-' time.strftime("%y%m%d-%h%m%s", time.localtime()) '.log' # 记录正常的 print 信息 sys.stdout = logger(log_file_name) # 记录 traceback 异常信息 sys.stderr = logger(log_file_name) print(5555) print(2/0)
./logs/log-20210103-140231.log
5555
traceback (most recent call last):
file "g:\codes\demo.py", line 33, in
print(2/0)
zerodivisionerror: division by zero
方法二:仅使用 sys
将所有输出全部直接保存到文件中,不再显示到控制台
demo.py
import sys log_print = open('defalust.log', 'w') sys.stdout = log_print sys.stderr = log_print if __name__ == '__main__': print(555) print(2/0)
default.log
555
traceback (most recent call last):
file "g:\codes\demo.py", line 9, in
print(2/0)
zerodivisionerror: division by zero
方法三:使用 logging 模块
功能更加全面,主要用于输出运行日志、设置输出日志的等级、日志保存路径等等
必须放到 try……catch…… 里面才能保存 traceback 的错误的信息,然后不能保存 print (如果要保存可以参考方法二,但是这样控制台就没有 print 了)
demo.py
import logging import os import time import traceback import sys # 创建一个 logger logger = logging.getlogger(__name__) # logger 的等级 logger.setlevel(level=logging.info) # 创建一个 handler,写入日志文件 log_path = './logs/' if not os.path.exists(log_path): os.makedirs(log_path) log_file_name = log_path 'log-' time.strftime("%y%m%d-%h%m%s", time.localtime()) '.log' logfile = log_file_name handler = logging.filehandler(logfile, mode='a ') # 输入到日志文件中的日志等级 handler.setlevel(logging.debug) # 设置 handler 中日志记录格式 formatter = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setformatter(formatter) # 将 handler 添加到 logger 里面 logger.addhandler(handler) # 将日志输出到控制台,默认 sys.stderr logger.addhandler(logging.streamhandler(sys.stdout)) logger.info("start print log") if __name__ == '__main__': try: print(5555555555) print(5/0) except exception as e: logger.error(str(traceback.format_exc()))
log-20210103-151751.log
2021-01-03 15:17:51,597 - __main__ - info - start print log
2021-01-03 15:17:51,597 - __main__ - error - traceback (most recent call last):
file "g:\codes\demo.py", line 34, in
print(5/0)
zerodivisionerror: division by zero
python记录日志,保存控制台输出
首先,保存控制台的信息不等于保存代码中的输出print的内容。控制台上的信息不仅仅只有代码中print的信息,区分控制台重定向和标准输出重定向。
1.仅保存代码中print的信息。即重定向标准输出。
定义日志类:
class logger(object): def __init__(self, filename='default.log', stream=sys.stdout): self.terminal = stream self.log = open(filename, 'a') def write(self, message): self.terminal.write(message) self.log.write(message) self.terminal.flush() # 不启动缓冲,实时输出 self.log.flush() def flush(self): pass
在main函数开头启动日志
sys.stdout = logger('./log.log', sys.stdout) sys.stderr = logger('./log.log', sys.stderr)
例子:
import tensorflow as tf import os, sys os.environ['tf_cpp_min_log_level'] = '3' os.environ["cuda_device_order"] = "pci_bus_id" os.environ["cuda_visible_devices"] = "2" class logger(object): def __init__(self, filename='default.log', stream=sys.stdout): self.terminal = stream self.log = open(filename, 'a') def write(self, message): self.terminal.write(message) self.log.write(message) self.terminal.flush() # 不启动缓冲,实时输出 self.log.flush() def flush(self): pass sys.stdout = logger('./log.log', sys.stdout) sys.stderr = logger('./log.log', sys.stderr) logit = tf.constant(1) tf_config = tf.configproto(log_device_placement=true) sess = tf.session(config=tf_config) print(sess.run(logit))
此时log.log中只有内容“1”,没有log_device的信息,因为其不属于stdout/stderr,尽管控制台上有这些信息,
2.保存控制台上的所有信息。即控制台重定向。
测试代码:
# 控制台重定向 import tensorflow as tf import os, time os.environ['tf_cpp_min_log_level'] = '3' os.environ["cuda_device_order"] = "pci_bus_id" os.environ["cuda_visible_devices"] = "-1" logit = tf.constant(1) tf_config = tf.configproto(log_device_placement=true) sess = tf.session(config=tf_config) print(sess.run(logit))
linux下:
python3 -u train.py >> ./log.log 2>&1
nohup python3 -u train.py >> ./log.log 2>&1 &,不挂起后台运行
windows下:
python -u test_gpu.py >> ./log.log 2>&1
start /min python -u test_gpu.py >> ./log.log 2>&1 &,这条命令多出了黑窗
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。