Python如何将控制台输出另存为日志文件

 更新时间:2023年05月08日 11:00:02   作者:渣渣的夏天  
这篇文章主要介绍了Python如何将控制台输出另存为日志文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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 <module>
    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 <module>
    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 <module>
    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 &,这条命令多出了黑窗

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python曲线拟合详解

    Python曲线拟合详解

    这篇文章主要介绍了关于python曲线拟合,scipy.optimize中,curve_fit函数可调用非线性最小二乘法进行函数拟合,文中有详细的代码作为参考,需要的朋友可以阅读参考
    2023-04-04
  • 如何用python合并多个excel文件

    如何用python合并多个excel文件

    这篇文章主要介绍了如何用python合并多个excel文件,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-03-03
  • jupyter notebook远程访问不了的问题解决方法

    jupyter notebook远程访问不了的问题解决方法

    这篇文章主要介绍了jupyter notebook远程访问不了的问题解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Python实现string字符串连接的方法总结【8种方式】

    Python实现string字符串连接的方法总结【8种方式】

    这篇文章主要介绍了Python实现string字符串连接的方法,结合实例形式总结分析了Python实现字符串连接的8种常见操作技巧,需要的朋友可以参考下
    2018-07-07
  • flask应用部署到服务器的方法

    flask应用部署到服务器的方法

    这篇文章主要介绍了flask应用部署到服务器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 详解pyinstaller selenium python3 chrome打包问题

    详解pyinstaller selenium python3 chrome打包问题

    这篇文章主要介绍了详解pyinstaller selenium python3 chrome打包问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Python导入或执行python源文件的3种方法

    Python导入或执行python源文件的3种方法

    这篇文章主要给大家介绍了关于Python导入或执行python源文件的3种方法,python源代码的文件以"py"为扩展名,由python.exe解释,可以在控制台下运行,需要的朋友可以参考下
    2023-08-08
  • Python pyecharts案例超市4年数据可视化分析

    Python pyecharts案例超市4年数据可视化分析

    这篇文章主要介绍了Python pyecharts案例超市4年数据可视化分析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • django框架CSRF防护原理与用法分析

    django框架CSRF防护原理与用法分析

    这篇文章主要介绍了django框架CSRF防护原理与用法,结合实例形式分析了Django框架CSRF防护的概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下
    2019-07-07
  • Python实现遍历数据库并获取key的值

    Python实现遍历数据库并获取key的值

    本文给大家分享的是Python实现遍历数据库并获取key的值的方法,主要是使用for循环来实现,有需要的小伙伴可以参考下。
    2015-05-05

最新评论