如何修复使用boto3上传日志到S3时的Filename must be a string错误
问题修复方案
核心问题分析
- 你的
log()函数只打印文件路径,没有返回任何值,所以file_name和key实际都是None,而s3.upload_file要求第一个参数必须是字符串类型的文件路径,这直接导致了ValueError。 - 代码里有拼写错误:
s3.upoad_file应该是s3.upload_file。 - 原逻辑只尝试上传单个文件,但你有4个目标日志,需要遍历所有符合条件的文件逐个上传。
- 没必要用
global dir_path,os.walk的循环变量会覆盖全局的dir_path,反而容易引发路径混乱。
修复后的完整代码
import os import datetime as dt import boto3 # 获取当日日期字符串 date = dt.datetime.now().strftime("%Y%m%d") bucket_name = 'mybucket' log_dir = "/log" # 初始化S3客户端 s3 = boto3.client('s3') def get_today_logs(dir_path): """获取当日所有日志文件的完整路径""" today_logs = [] for root, _, files in os.walk(dir_path): for file in files: if date in file: full_path = os.path.join(root, file) today_logs.append(full_path) return today_logs # 获取所有当日日志文件 today_log_files = get_today_logs(log_dir) # 逐个上传到S3 for file_path in today_log_files: # 用文件名作为S3对象的key,也可以根据需求改成其他路径格式 s3_key = os.path.basename(file_path) try: s3.upload_file(file_path, bucket_name, s3_key) print(f"成功上传文件: {file_path} -> s3://{bucket_name}/{s3_key}") except Exception as e: print(f"上传失败 {file_path}: {str(e)}")
关键修改说明
- 重写了
get_today_logs函数,返回所有符合条件的日志文件路径列表,而不是只打印。 - 去掉了不必要的
global声明,避免路径变量被意外修改。 - 修复了
upload_file的拼写错误。 - 增加了循环遍历,批量上传所有当日日志文件,同时添加了异常捕获,方便排查单个文件的上传问题。
- S3的
key(即存储到桶里的文件名)这里用了os.path.basename(file_path),只保留文件名;如果需要保留原目录结构,可以直接用file_path.lstrip('/')作为key。
内容的提问来源于stack exchange,提问作者neeson.lee
相关产品推荐
相关产品推荐

