如何通过AWS Lambda将CloudWatch告警状态上传至S3存储桶?
问题:将CloudWatch告警查询结果上传至S3存储桶
我已经实现了查询CloudWatch告警的代码,可在控制台按预期格式输出告警状态,现在希望将该输出作为文本文件上传至S3存储桶,请问如何实现?
已实现的CloudWatch告警查询代码
import { CloudWatchClient, DescribeAlarmsCommand } from "@aws-sdk/client-cloudwatch"; const REGION = "eu-west-2"; const cwclient = new CloudWatchClient({ region: REGION }); export const handler = async() => { const cwparams = {}; const cw = new DescribeAlarmsCommand(cwparams); try { const cwdata = await cwclient.send(cw); cwdata.MetricAlarms.forEach(function (item) { console.log('\n%j', {alarmname:item.AlarmName,alarmstate:item.StateValue}); }); } catch (error) { } };
代码输出
Function Logs START RequestId: xxxxxxxxxxxxxxxxxxx Version: $LATEST 2022-11-30T09:48:34.655Z xxxxxxxxxxxxxxxxxxx INFO {"alarmname":"my-alarm-1","alarmstate":"OK"} 2022-11-30T09:48:34.655Z xxxxxxxxxxxxxxxxxxx INFO {"alarmname":"my-alarm-2","alarmstate":"OK"} END RequestId: xxxxxxxxxxxxxxxxxxx
已测试的S3上传代码
我已查看S3 PutObjectCommand的SDK文档并测试了以下代码,可上传含文本内容的文件,但不确定如何将CloudWatch告警数据与该代码结合,使文本文件的Body为CloudWatch告警数据。
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; export const handler = async() => { const bucketName = "mybucket"; const keyName = "test.json"; const s3 = new S3Client({}); const s3putCommand = new PutObjectCommand({ Bucket: bucketName, Key: keyName, Body: "Hello" // 我希望此处为CloudWatch告警数据 }); try { await s3.send(s3putCommand); console.log('Successfully uploaded data to ' + bucketName + '/' + keyName); } catch (error) { } };
代码输出
Function Logs START RequestId: xxxxxxxxxxxxxxxxxxx Version: $LATEST 2022-11-30T09:56:45.585Z xxxxxxxxxxxxxxxxxxx INFO Successfully uploaded data to mybucket/test.json END RequestId: xxxxxxxxxxxxxxxxxxx
目标效果
我希望上传的test.json文件内容如下:
{"alarmname":"my-alarm-1","alarmstate":"OK"} {"alarmname":"my-alarm-2","alarmstate":"OK"}
解决方案
将两段代码整合,先获取CloudWatch告警数据并格式化为目标字符串,再将该字符串作为S3上传请求的Body参数即可。以下是整合后的完整代码:
import { CloudWatchClient, DescribeAlarmsCommand } from "@aws-sdk/client-cloudwatch"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; const REGION = "eu-west-2"; const bucketName = "mybucket"; const keyName = "test.json"; // 初始化CloudWatch和S3客户端 const cwclient = new CloudWatchClient({ region: REGION }); const s3 = new S3Client({}); export const handler = async() => { try { // 1. 获取CloudWatch告警数据 const cwparams = {}; const cwCommand = new DescribeAlarmsCommand(cwparams); const cwdata = await cwclient.send(cwCommand); // 2. 格式化告警数据为目标字符串 const alarmStrings = cwdata.MetricAlarms.map(item => JSON.stringify({alarmname: item.AlarmName, alarmstate: item.StateValue}) ); const bodyContent = alarmStrings.join(' '); // 3. 上传至S3 const s3putCommand = new PutObjectCommand({ Bucket: bucketName, Key: keyName, Body: bodyContent, ContentType: 'text/plain' // 可选,指定文件类型 }); await s3.send(s3putCommand); console.log('Successfully uploaded alarm data to ' + bucketName + '/' + keyName); console.log('Uploaded content:', bodyContent); } catch (error) { console.error('Error occurred:', error); } };
代码说明
- 先通过CloudWatch客户端获取告警数据,使用
map方法将每个告警对象转为JSON字符串 - 使用
join(' ')将所有JSON字符串用空格拼接,匹配你想要的文件格式 - 将拼接后的字符串作为
PutObjectCommand的Body参数,完成上传 - 添加了
ContentType参数(可选),明确文件类型为文本;如果后续需要按标准JSON解析,建议将格式调整为数组形式[{}, {}],并将ContentType改为application/json
内容的提问来源于stack exchange,提问作者jtwp
相关产品推荐
相关产品推荐

