javascript CloudWatch到AWS Lambda到Slack Channel Alerts和Charts。通过SNS主题通过Lambda函数将CloudWatch警报发布到Slack通

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript CloudWatch到AWS Lambda到Slack Channel Alerts和Charts。通过SNS主题通过Lambda函数将CloudWatch警报发布到Slack通相关的知识,希望对你有一定的参考价值。

////// Save as index.js and upload it to Lambda as zip archive with node_modules directory. After:
////// npm install aws-cloudwatch-chart
////// npm install request
////// no need to upload aws-sdk module
////// Don't forget to change API keys here.

////// License: MIT


////// Docs:
////// https://github.com/jeka-kiselyov/aws-cloudwatch-chart
////// http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html
////// http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser-create-test-function-create-function.html

//////


exports.handler = function(event, context) {


	var request = require('request');
	var fs = require('fs');
    var AwsCloudWatchChart = require('aws-cloudwatch-chart');

    var config = {};
	config.slack = {
		token: 'xoxp-4234234-234234-234234234-257abf',
		channel: '#aws',
		initialComment: "EC2 CPU Usage %from_time% to %to_time% UTC",
		fileTitle: "EC2 CPU Usage %from_time% to %to_time% UTC"
	};
	config.aws = {
	    accessKeyId: "ASDASDSADSADASD",
	    secretAccessKey: "dsfsdfsdf/REWR/fdsdf/DFDSf34",
	    region: "us-east-1"
	};

	config.timeOffset = 1440;
	config.timePeriod = 60;
	config.graphSamples = 20;
	config.width = 1000;
	config.height = 250;

	if (typeof(event.Records) === 'undefined' || typeof(event.Records[0]) === 'undefined' || typeof(event.Records[0].Sns) === 'undefined')
		context.fail ('ERROR: requires SNS message');

	if (typeof(event.Records[0].Sns.Message) !== 'undefined' && typeof(event.Records[0].Sns.Message.Trigger) === 'undefined')
		event.Records[0].Sns.Message = JSON.parse(event.Records[0].Sns.Message);

	config.slack.initialComment = event.Records[0].Sns.Subject + "\n" + event.Records[0].Sns.Message.AlarmDescription;

	config.metrics = [];

	console.log('event.Records[0].Sns.Message:');
	console.log(event.Records[0].Sns.Message);


	if (typeof(event.Records[0].Sns.Message.Trigger) !== 'undefined' && typeof(event.Records[0].Sns.Message.Trigger.Dimensions) !== 'undefined')
	{
		if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/EC2' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUUtilization')
		{
			config.metrics.push({
		      InstanceId: event.Records[0].Sns.Message.Trigger.Dimensions[0].value,
		      title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" EC2 Max CPU Usage",
		      Namespace: event.Records[0].Sns.Message.Trigger.Namespace,
		      MetricName: event.Records[0].Sns.Message.Trigger.MetricName,
		      StatisticValues: "Maximum",
		      Unit: "Percent",
		      color: "af9cf4",
		      thickness: 2,
		      dashed: false
			});
		} else if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/RDS' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUUtilization') {
			config.metrics.push({
		      DBInstanceIdentifier: event.Records[0].Sns.Message.Trigger.Dimensions[0].value,
		      title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" DB Max CPU Usage",
		      Namespace: event.Records[0].Sns.Message.Trigger.Namespace,
		      MetricName: event.Records[0].Sns.Message.Trigger.MetricName,
		      StatisticValues: "Maximum",
		      Unit: "Percent",
		      color: "9caff4",
		      thickness: 2,
		      dashed: false
			});
		} else if (event.Records[0].Sns.Message.Trigger.Namespace == 'AWS/EC2' && event.Records[0].Sns.Message.Trigger.MetricName == 'CPUCreditBalance') {
			config.metrics.push({
		      InstanceId: event.Records[0].Sns.Message.Trigger.Dimensions[0].value,
		      title: event.Records[0].Sns.Message.Trigger.Dimensions[0].value+" CPU Credit Balance",
		      Namespace: event.Records[0].Sns.Message.Trigger.Namespace,
		      MetricName: event.Records[0].Sns.Message.Trigger.MetricName,
		      StatisticValues: "Maximum",
		      Unit: "Count",
		      color: "9caff4",
		      thickness: 2,
		      dashed: false
			});
		}		
	}

	var postSlackMessage = function(text, imageURL, callback)
	{
		var apiURL = "https://slack.com/api/chat.postMessage?token=" + encodeURIComponent(config.slack.token) + 
						"&text=" + encodeURIComponent("ALERT\n"+imageURL) + 
						"&username=" + encodeURIComponent('AWS') + 
						"&as_user=" + encodeURIComponent('false') + 
						"&icon_emoji=" + encodeURIComponent(':bell:') + 
						"&attachments=" + encodeURIComponent('[{"fallback": '+JSON.stringify(text)+',"text": '+JSON.stringify(text)+', "color": "danger"}]') + 
						"&channel=" + encodeURIComponent(config.slack.channel);

		var req = request.post(apiURL, callback);
	}

	if (config.metrics.length < 1) 
	{
		/// post 
		postSlackMessage(config.slack.initialComment, '', function() {
			context.done(null, 'Not AWS/EC2 CPUUtilization metric');				
		});

	} else {
	    var acs = new AwsCloudWatchChart(config);

		console.log('Start');

	    acs.getChart().then(function(chart){

	    	console.log('Got chart URL');
	    	console.log(chart.getURL());

	        chart.get().then(function(image){

		    	console.log('Got chart image');

				var fileTitle = config.slack.fileTitle.
								split('%from_time%').join(acs.getFromTimeString()).
								split('%to_time%').join(acs.getToTimeString());
				var initialComment = 	config.slack.initialComment.
										split('%from_time%').join(acs.getFromTimeString()).
										split('%to_time%').join(acs.getToTimeString());

				var apiURL = "https://slack.com/api/files.upload?token=" + encodeURIComponent(config.slack.token) + 
								"&filename=" + encodeURIComponent("image.png") + 
								"&title=" + encodeURIComponent(fileTitle) + 
								"&initial_comment=" + encodeURIComponent(initialComment);

		    	console.log('Sending file to Slack...');
		    	var callback = function (err, response, body) {
		    			var data = JSON.parse(body);
		    			var text = config.slack.initialComment;

						postSlackMessage(text, data.file.url, function() {
							context.done(null, "Done");			
						});
				}

				var req = request.post(apiURL, callback);
				var form = req.form();
				form.append('file', new Buffer(image), {contentType: 'image/png', filename: 'x.png', name: 'x.png'});
	        });
	    });

	}



};

以上是关于javascript CloudWatch到AWS Lambda到Slack Channel Alerts和Charts。通过SNS主题通过Lambda函数将CloudWatch警报发布到Slack通的主要内容,如果未能解决你的问题,请参考以下文章

无法将json文件上传到AWS CloudWatch

AWS Elastic Beanstalk:将容器日志流式传输到 CloudWatch 问题

AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?

是否有工具可以使用CloudWatch putMetric API将整个内容从AWS QLDB表发布到Cloudwatch?

将现有 AWS CloudWatch 警报导出到 CloudFormation 模板

AWS:将日志从 Amazon CloudWatch 导出到 Amazon Redshift