Как отправлять SNS-сообщения от Lambda каждые 24 часа? - PullRequest
1 голос
/ 10 мая 2019

Я новичок в Lambda и пытаюсь написать функцию, которая будет отправлять электронную почту с объемным объемом через SNS каждые 24 часа. Эта лямбда-функция запускается по правилу IoT, и без 24-часового ограничения входящие сообщения будут заполнены электронными письмами. В CloudWatch похоже, что электронное письмо отправляется, даже если флаг email_sent равен 1. Так что это заставляет меня думать, что я неправильно структурировал свои скобки и скобки? Кто-нибудь видит что-то не так с этим кодом?


var email_sent = 0;  //Flag to determine if the email has been sent in the last 24 hours
var starttime = new Date();  //Date & time when the script starts running

....

exports.handler = (event, context, callback) => {
 console.log('Start time.', starttime);
 console.log('Email Sent Flag.', email_sent);
 console.log('Received event:', event.my_volume, ' mL Volume');  //Fluid volume
 var miliseconds = new Date() - starttime;  //Calculate the time that has passed
 console.log('Miliseconds.', miliseconds);
 console.log(miliseconds/1000 + " Seconds.");
 if (miliseconds => 86,400,000) {    //Has 24 hours passed?
     email_sent = 0;   //set the email flag back to zero if the time has passed
 }
 // create/get topic
 if (email_sent == 0) {  //if the email flag is not set, setup topic and send the email
 createTopic('aws-iot-button-sns-topic', (err, topicArn) => {
     if (err) {
         return callback(err);
     }
     console.log(`Publishing to topic ${topicArn}`);
     // publish message
     const params = {
         Message: `The fluid level is low on your system: ${event.my_volume} mL.`,
         Subject: `Low Fluid Level Alert - Knight`,
         TopicArn: topicArn,
     };

     // result will go to function callback
     SNS.publish(params, callback);
     console.log('SNS Published.');
     email_sent = 1;  // after email is sent, reset the flag
     starttime = new Date();  // reset the starttime after the email is sent
 }
 );
} 
};

Спасибо,

Steve

Ответы [ 2 ]

0 голосов
/ 12 мая 2019

Вот другой подход ...

  • Повысить температуру до Amazon CloudWatch Metrics (см. Ниже)
  • Создать Amazon CloudWatch будильник , чтобы срабатывать, когда температура опускается ниже заданного порога
  • Будильник может отправить сообщение на тему Amazon SNS
  • Люди могут подписаться на тему SNS для получения электронного письма при отправке сообщения

Это будет отправлять только одно сообщение, когда показатель упадет ниже порогового значения. Лямбда не требуется (возможно).

Я не совсем уверен в том, как отправлять показатели IoT в CloudWatch (я не очень знаком с IoT). Это может быть актуально: Метрики в реальном времени с AWS IoT Analytics и Amazon CloudWatch | Интернет вещей на AWS - Официальный блог

Или, в зависимости от вашей системы, которая измеряет температуру, вы можете просто отправить показатели прямо в CloudWatch вместо IoT.

Вот пример сообщения, отправленного Amazon CloudWatch в Amazon SNS, который затем будет отправлен всем подписчикам темы SNS:

From: AWS Notifications <no-reply@sns.amazonaws.com>
Date: Mon, 13 May 2019 at 08:03
Subject: ALARM: "Fluid Level alert" in Asia Pacific (Sydney)

You are receiving this email because your Amazon CloudWatch Alarm "Fluid Level alert" in the Asia Pacific (Sydney) region has entered the ALARM state, because "Threshold Crossed: 1 datapoint [10.5 (12/05/19 21:58:00)] was less than or equal to the threshold (15.0)." at "Sunday 12 May, 2019 22:03:17 UTC".

View this alarm in the AWS Management Console:
https://console.aws.amazon.com/cloudwatch/home?region=ap-southeast-2#s=Alarms&alarm=Fluid%20Level%20alert

Alarm Details:
- Name:                       Fluid Level alert
- Description:                Fluid level has dropped below 15
- State Change:               INSUFFICIENT_DATA -> ALARM
- Reason for State Change:    Threshold Crossed: 1 datapoint [10.5 (12/05/19 21:58:00)] was less than or equal to the threshold (15.0).
- Timestamp:                  Sunday 12 May, 2019 22:03:17 UTC

Threshold:
- The alarm is in the ALARM state when the metric is LessThanOrEqualToThreshold 15.0 for 300 seconds. 

Monitored Metric:
- MetricNamespace:                     Vat12
- MetricName:                          FluidLevel
- Dimensions:                          
- Period:                              300 seconds
- Statistic:                           Average
- Unit:                                not specified


State Change Actions:
- OK: 
- ALARM: [arn:aws:sns:ap-southeast-2::alertme]
- INSUFFICIENT_DATA: 
0 голосов
/ 11 мая 2019

Итак, я вижу две вещи, которые должны быть выполнены по-разному.

Во-первых, у вас есть это:

createTopic('aws-iot-button-sns-topic', (err, topicArn) => {

Прямо сейчас ваша функция создает ненужныетемы, не удаляя их, это проблема.Вместо этого вы должны создать тему SNS извне и ссылаться на нее здесь, используя либо переменные среды Lambda, либо жестко программируя тему SNS arn.Или сначала проверьте, существует ли уже тема с таким именем, и не создавайте ее, если она есть.

Во-вторых, Lambdas не работают дольше, чем 900 секунд (15 минут) , поэтому проверить, работает ли скрипт в течение> 24 часов, невозможно.

Вместо этого вам нужно создать триггер CloudWatch, который запускается каждые 24 часа с использованием cron ,Таким образом, ваша лямбда будет работать ровно один раз каждые 24 часа (или любое другое событие, которое вы настраиваете), и в коде вы просто должны отправить сообщение один раз.Тогда вам не нужно будет проверять, сколько времени и сколько вы уже отправили, поскольку вы знаете, что триггер события происходит только один раз, поэтому ваше сообщение отправляется один раз, а ваша лямбда прекращает выполнение сразу после этого.

Суть Lambdas в том, что они недолговечны и не имеют состояния, поэтому спроектируйте свой сервис соответствующим образом:)

Редактировать: После комментария я понимаю вариант использования подробнее ... в этом сценарии, где Lambda выполняетсяпо IoT я лично сохранял бы предыдущее время выполнения в хранилище параметров SSM или DynamoDB, а затем всякий раз, когда запускается Lambda, я получал значение, проверял, прошло ли 24 часа, и отправлял SNS, если он это делал.Вы должны будете сделать это, потому что Lambda не будет знать иначе, когда было время последнего выполнения (и убедитесь, что обновлялось только время последнего выполнения при успешном вызове публикации SNS, то есть вы уверены, что отправили сообщение в тот день)

...