使用Lambda(运行时环境为Node.js 8.10)将消息发布到SNS并发送邮件

总结

若在 CloudWatch Logs 中包含特定字符串,有时希望自定义邮件正文并发送。为了备忘起见,我尝试通过部署 Zip 文件并从 Lambda 发布到 SNS 实现邮件发送。

环境

    • Amazon Linux

 

    • node v8.15.1

 

    npm v6.4.1

步骤

    1. 准备文件作为函数的ZIP包

$ cd /home/ec2-user/lambda
$ npm install aws-sdk
$ ls -al
总共 20
drwxrwxr-x 3 ec2-user ec2-user 4096 3月 4 18:11 .
drwx—— 10 ec2-user ec2-user 4096 3月 4 18:11 ..
-rw-rw-r— 1 ec2-user ec2-user 613 3月 4 17:57 hello_nodejs.js
drwxrwxr-x 17 ec2-user ec2-user 4096 3月 4 18:11 node_modules
-rw-rw-r— 1 ec2-user ec2-user 3420 3月 4 18:11 package-lock.json

$ npm install zlib
npm WARN 保存错误 ENOENT: 没有此文件或目录, open ‘/home/ec2-user/lambda/package.json’
npm WARN enoent ENOENT: 没有此文件或目录, open ‘/home/ec2-user/lambda/package.json’
npm WARN lambda 没有描述字段
npm WARN lambda 没有存储库字段
npm WARN lambda 没有 README 数据字段
npm WARN lambda 没有许可证字段
+ zlib@1.0.5
从 1 个贡献者处添加了 1 个软件包,并在 0.9 秒内审计了 38 个软件包
发现 0 个漏洞

$ zip -r ../hello_nodejs.zip .
$ zipinfo ../hello_nodejs.zip
档案: ../hello_nodejs.zip
Zip文件大小: 5438595 字节,条目数: 1416
…..省略…..

创建Lambda函数

$ aws lambda create-function \
–function-name hello_nodejs \
–zip-file fileb:///home/ec2-user/hello_nodejs.zip \
–role arn:aws:iam::accout_id:role/lambda_basic_execution \
–handler hello_nodejs.handler \
–runtime nodejs8.10

设置Lambda函数的执行角色
(假设角色已经添加了Lambda可以进行SNS发布的权限)

    $ aws lambda add-permission \
    --function-name "hello_nodejs" \
    --statement-id "hello_nodejs" \
    --principal "logs.ap-northeast-1.amazonaws.com" \
    --action "lambda:InvokeFunction" \
    --source-arn "arn:aws:logs:ap-northeast-1:accout_id:log-group:TestLambda_NodeJS:*" \
    --source-account "accout_id"

创建订阅过滤器

    $ aws logs put-subscription-filter \
    --log-group-name TestLambda_NodeJS \
    --filter-name demo \
    --filter-pattern "" \
    --destination-arn arn:aws:lambda:ap-northeast-1:accout_id:function:hello_nodejs

    $ aws logs describe-subscription-filters —log-group-name TestLambda_NodeJS

6. 发送日志并进行测试试试。

    $ aws logs put-log-events —log-group-name TestLambda_NodeJS —log-stream-name stream1 —log-events "[{\"timestamp\":xxxxxxxxxxxxx , \"message\": \"Simple Lambda Test-1\"},
    {\"timestamp\":xxxxxxxxxxxxx , \"message\": \"Simple Lambda Test-2\"}]"

你好_nodejs.js源代码

var aws = require('aws-sdk');

var sns = new aws.SNS({
   apiVersion: '2010-03-31',
   region: 'ap-northeast-1'
});

function timer(ms, name) {
  console.log(`name: ${name} start!`)
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), ms)
  })
}

exports.handler = async function(event, context) {
    console.log('publish start')
    await timer(1000, publish(event, context));

    function publish(event, context) {
        sns.publish({
            Message: 'Message',
            Subject: 'Message title ' ,
            TargetArn: 'arn:aws:sns:region:accountId:topicName'
            }, function(err, data) {
                if (err) {
                    console.log(err.stack);
                    return "failed publish".err.stack;
                }

                console.log('publish sent');
                console.log(data);
        });
    }

};