AWS Lambda Python脚本:CloudWatch日志存文件发Slack报错求助
问题解决:Lambda脚本写入文件及Slack发送错误修复
错误原因
报错write() argument must be str, not dict是因为你试图把字典message直接写入文件,但文件的write()方法只接受字符串类型的参数,而message是包含text键的字典,你需要提取其中的字符串内容来写入。
修正后的完整代码
import boto3 import requests import json def lambda_handler(event, context): print(event) build_id = event['detail']['build-id'].split(':')[-1] logs_client = boto3.client('logs') log_group_name = "/aws/codebuild/" + event['detail']['project-name'] log_stream_name = build_id response = logs_client.get_log_events( logGroupName=log_group_name, logStreamName=log_stream_name, startFromHead=True ) # 构造日志文本内容 log_text = 'Logs for build {0}:\n'.format(build_id) for log_event in response['events']: log_text += log_event['message'] + '\n' slack_webhook_url = 'https://hooks.slack.com/services/123123123/123123123/123123123' # 写入日志到文件 file_path = "/tmp/codebuild-logs.txt" with open(file_path, "w") as a_file: a_file.write(log_text) # 重新打开文件准备发送(with块结束后文件已关闭,需重新打开) with open(file_path, "rb") as file_to_send: # 构造Slack文件上传参数 files = { 'file': (file_path, file_to_send, 'text/plain') } # 可选:添加文本说明 data = { 'initial_comment': f"CodeBuild Build {build_id} 日志文件", 'channels': '#your-channel-name' # 替换为你的Slack频道名 } response = requests.post(slack_webhook_url, files=files, data=data) if response.status_code == 200: return { 'statusCode': 200, 'body': 'Message and file are sent to Slack successfully.' } else: return { 'statusCode': response.status_code, 'body': f'Failed to send to Slack. Response: {response.text}' }
关键修改说明
- 单独提取日志字符串:把原来的
message字典拆成单独的log_text字符串,直接操作字符串更清晰,避免字典和字符串混淆。 - 正确写入文件:用
a_file.write(log_text)写入字符串,解决类型错误。 - 重新打开文件发送:
with代码块结束后文件会自动关闭,所以需要重新以二进制读模式(rb)打开文件,才能正确传给Slack的files参数。 - 规范Slack文件上传参数:
files字典的键用file是Slack的标准要求,值是包含文件名、文件对象、MIME类型的元组。- 添加
data参数可以指定初始评论和目标频道,让Slack通知更清晰。
额外注意事项
- 确保Lambda有足够的权限访问CloudWatch Logs和对外网络访问权限(发送请求到Slack)。
- 替换代码中的
#your-channel-name为实际的Slack频道名,或者去掉channels参数使用Webhook默认配置的频道。
内容的提问来源于stack exchange,提问作者Santosh
相关产品推荐
相关产品推荐

