You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本如何同时将stdout、stderr输出至文件与屏幕?

解决Python FTP文件传输的日志双输出与错误追踪问题

我来帮你实现这个需求——既要让日志同时显示在屏幕和文件,又要在成功/失败时分别生成对应日志,还得捕获完整的错误回溯信息。下面是完整的实现方案:

完整代码示例

import ftplib
import logging
import traceback
import sys
from datetime import datetime

def setup_logging():
    """配置日志:同时输出到屏幕和过程日志文件"""
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[
            logging.StreamHandler(sys.stdout),  # 屏幕输出
            logging.FileHandler('ftp_process.log', encoding='utf-8')  # 过程日志文件
        ]
    )

def write_status_log(success, host, local_file, remote_file, error_msg=None, traceback_str=None):
    """生成成功/失败状态日志文件"""
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    if success:
        with open('OK.log', 'w', encoding='utf-8') as f:
            f.write(f"=== 文件上传成功 ===\n")
            f.write(f"时间: {timestamp}\n")
            f.write(f"FTP服务器: {host}\n")
            f.write(f"本地文件路径: {local_file}\n")
            f.write(f"远程文件路径: {remote_file}\n")
        logging.info("状态日志已生成:OK.log")
    else:
        with open('error.log', 'w', encoding='utf-8') as f:
            f.write(f"=== 文件上传失败 ===\n")
            f.write(f"时间: {timestamp}\n")
            f.write(f"FTP服务器: {host}\n")
            f.write(f"本地文件路径: {local_file}\n")
            f.write(f"远程文件路径: {remote_file}\n")
            f.write(f"错误信息: {error_msg}\n")
            if traceback_str:
                f.write(f"\n完整错误回溯:\n{traceback_str}")
        logging.error("状态日志已生成:error.log")

def ftp_upload(host, username, password, local_file, remote_file):
    """核心FTP上传函数"""
    ftp_conn = None
    try:
        logging.info(f"开始连接FTP服务器: {host}")
        ftp_conn = ftplib.FTP(host)
        ftp_conn.login(username, password)
        logging.info(f"成功登录FTP服务器: {host}")
        
        # 开启被动模式(大多数场景需要)
        ftp_conn.set_pasv(True)
        
        logging.info(f"开始上传文件: {local_file} -> {remote_file}")
        with open(local_file, 'rb') as file_obj:
            # 使用storbinary传输二进制文件(如图片、压缩包),如果是文本文件可以用storlines
            ftp_conn.storbinary(f'STOR {remote_file}', file_obj)
        
        logging.info("文件上传完成!")
        write_status_log(True, host, local_file, remote_file)
        return True
    except Exception as e:
        tb_str = traceback.format_exc()
        error_msg = str(e)
        logging.error(f"上传失败: {error_msg}")
        logging.error(f"完整错误回溯:\n{tb_str}")
        write_status_log(False, host, local_file, remote_file, error_msg, tb_str)
        return False
    finally:
        if ftp_conn:
            try:
                ftp_conn.quit()
                logging.info("已断开FTP连接")
            except Exception as quit_err:
                logging.warning(f"断开FTP连接时出错: {str(quit_err)}")

if __name__ == "__main__":
    # 初始化日志配置
    setup_logging()
    
    # 替换成你的FTP参数
    FTP_HOST = "your-ftp-server.com"
    FTP_USER = "your-username"
    FTP_PASS = "your-password"
    LOCAL_FILE = "./test_upload.txt"
    REMOTE_FILE = "/remote/path/test_upload.txt"
    
    # 执行上传
    ftp_upload(FTP_HOST, FTP_USER, FTP_PASS, LOCAL_FILE, REMOTE_FILE)

代码功能说明

  1. 日志双输出

    • 通过setup_logging()函数配置logging模块,同时添加StreamHandler(屏幕输出)和FileHandler(写入ftp_process.log),确保所有操作日志既显示在控制台,又保存到过程日志文件。
  2. 成功/失败状态日志

    • 上传成功时自动生成OK.log,包含时间、服务器信息、文件路径等关键内容;
    • 上传失败时生成error.log,不仅记录错误信息,还会写入完整的Python错误回溯(traceback),方便排查问题。
  3. FTP传输细节

    • 开启了被动模式(set_pasv(True)),这是大多数FTP服务器的要求;
    • 使用storbinary传输二进制文件,如果你需要传输纯文本文件,可以替换为storlines;
    • 在finally块中确保FTP连接被正确关闭,避免资源泄漏。

注意事项

  • 参数替换:记得把代码中的FTP主机、用户名、密码、本地/远程文件路径替换成你自己的实际信息;
  • 日志覆盖:OK.log和error.log每次运行会覆盖之前的内容,如果需要追加日志,可以把open的模式从'w'改成'a';
  • 文件权限:确保脚本有读取本地文件和写入日志文件的权限;
  • 异常捕获:代码捕获了所有异常,如果你需要针对特定FTP错误(如登录失败、文件不存在)做特殊处理,可以单独捕获ftplib中的异常类(比如ftplib.error_perm)。

内容的提问来源于stack exchange,提问作者Hrvoje T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:00:35