如何实现AWS Glue作业失败时发送含CloudWatch日志的SNS邮件及前提
AWS Glue作业失败带CloudWatch日志截图通知实现方案
该需求完全可行。你之前使用CloudWatch Events直接触发SNS的方案仅能传递事件元数据(如作业状态、名称),无法生成并携带日志截图,需通过Lambda函数结合CloudWatch Logs、SES服务实现完整逻辑。
前置条件
- 已部署运行中的AWS Glue Python作业,且作业日志已默认输出至CloudWatch Logs
- 已在AWS SES中验证用于发送通知的发件邮箱/域名(需完成SES发件验证流程)
- 已创建具备以下权限的IAM角色:
glue:GetJobRuns:获取Glue作业的运行记录及日志位置logs:GetLogEvents:拉取CloudWatch日志内容ses:SendRawEmail:发送带附件的邮件lambda:InvokeFunction:允许CloudWatch Events触发Lambda
分步实现流程
1. 创建Lambda函数(核心处理逻辑)
Lambda负责捕获失败事件、拉取日志、生成截图、发送邮件:
- 进入Lambda控制台,新建Python 3.x运行时的函数,关联上述IAM角色
- 编写核心代码逻辑(示例框架):
import boto3 from PIL import Image, ImageDraw, ImageFont import io import base64 glue = boto3.client('glue') logs = boto3.client('logs') ses = boto3.client('ses') def lambda_handler(event, context): # 解析Glue失败事件 job_name = event['detail']['jobName'] run_id = event['detail']['runId'] # 获取作业日志信息 job_run = glue.get_job_run(JobName=job_name, RunId=run_id) log_group = job_run['JobRun']['LogGroupName'] log_stream = job_run['JobRun']['LogStreamName'] # 拉取最近100条失败日志 log_events = logs.get_log_events(logGroupName=log_group, logStreamName=log_stream, limit=100) log_content = "\n".join([event['message'] for event in log_events['events']]) # 生成日志截图(用Pillow将文本转为图片) image = Image.new('RGB', (800, 600), color='white') draw = ImageDraw.Draw(image) font = ImageFont.load_default() draw.text((10,10), log_content, fill='black', font=font) # 将图片转为字节流并编码为base64 img_byte_arr = io.BytesIO() image.save(img_byte_arr, format='PNG') img_base64 = base64.b64encode(img_byte_arr.getvalue()).decode('utf-8') # 构造带附件的邮件并发送 raw_email = f"""From: 通知邮箱 <your-verified-email@domain.com> To: 收件人 <recipient@domain.com> Subject: Glue作业 {job_name} 运行失败 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="boundary" --boundary Content-Type: text/plain; charset="UTF-8" 作业 {job_name} 运行失败,以下是最近的日志截图: --boundary Content-Type: image/png Content-Disposition: attachment; filename="glue-failure-log.png" Content-Transfer-Encoding: base64 {img_base64} --boundary-- """ ses.send_raw_email(RawMessage={'Data': raw_email}) return {'statusCode': 200, 'body': 'Notification sent successfully'}
2. 配置Lambda层(添加Pillow依赖)
Lambda默认环境无Pillow库,需创建Lambda层添加依赖:
- 本地安装对应Lambda运行时版本的Pillow:
pip install pillow -t python/lib/python3.x/site-packages/ - 将
python目录打包为zip文件,上传至Lambda层 - 将该层关联至目标Lambda函数
3. 配置CloudWatch Events规则触发Lambda
- 进入CloudWatch Events控制台,新建规则
- 事件源选择"服务名称"->"Glue",事件类型为"Glue作业状态更改",状态筛选为"FAILED"
- 目标选择之前创建的Lambda函数,完成规则配置
4. 测试验证
- 修改Glue Python脚本加入错误代码(如
raise Exception("Test failure")),手动触发作业运行 - 查看Lambda执行日志,确认日志拉取、图片生成、邮件发送流程正常
- 检查目标收件邮箱,确认收到带日志截图的失败通知
替代方案(生成CloudWatch控制台日志页面截图)
若需严格生成CloudWatch日志控制台页面的截图,可使用CloudWatch Synthetics Canary:
- 创建Synthetics Canary,编写Node.js脚本模拟访问目标日志页面(需配置IAM权限允许Canary访问AWS控制台)
- 当Glue作业失败时,触发Canary运行,将截图存储至S3
- 修改Lambda逻辑,从S3读取截图后通过SES发送邮件
内容的提问来源于stack exchange,提问作者RAHUL DHANOLA
相关产品推荐
相关产品推荐

