douzhe3516 2018-09-21 16:10
浏览 137

通过Lambda传递Cloudwatch数据-Golang

I am trying to achieve the following:

  1. Lambda is triggered by a Cloudwatch alarm
  2. Lambda looks at the data received by Cloudwatch and makes a decision on what to do based on NewStateValue
  3. If needed, the Lambda will trigger another SNS that sends all the Cloudwatch data to OpsGenie

I am getting stuck at the third step. I can pass some data by manually specifying it, however, is there a function that will just pass all JSON received by the Lambda onto the next SNS?

I have got the JSON for SNS, CloudWatch Alarms and the Message section of the CloudWatch Alarm.

package main

import (
    "context"
    "fmt"
    "encoding/json"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/sns"
)

func handler(ctx context.Context, snsEvent events.SNSEvent) {
    for _, record := range snsEvent.Records {
        snsRecord := record.SNS

//To add in additional fields to publish to the logs add "snsRecord.'fieldname'"
        fmt.Printf("Message = %s 
", snsRecord.Subject) 
        var event CloudWatchAlarmMessage

        err := json.Unmarshal([]byte(snsRecord.Message), &event)
        if err != nil {
            fmt.Println("There is an error: " + err.Error())
        }
        fmt.Printf("Test Message = %s 
", event.NewStateValue)
        // if ( event.Sns.Message.NewStateValue == "ALARM") {
        if ( event.NewStateValue == "ALARM") {
            svc := sns.New(session.New())
// params will be sent to the publish call included here is the bare minimum params to send a message.
    params := &sns.PublishInput{
        Message: aws.String(event.OldStateValue),
        Subject: aws.String(event.NewStateValue),
        TopicArn: aws.String("my arn"), //Get this from the Topic in the AWS console.
    }

    resp, err := svc.Publish(params)   //Call to puclish the message

    if err != nil {                    //Check for errors
        // Print the error, cast err to awserr.Error to get the Code and
        // Message from an error.
        fmt.Println(err.Error())
        return
    }

    // Pretty-print the response data.
    fmt.Println(resp)
}
}


}
func main() {
    lambda.Start(handler)
}

I have attempted to use MessageStructure: aws.String("json"), but it seems to just result in cannot use snsRecord (type events.SNSEntity) as type *string in field value.

With my current set-up it successfully sends the NewStateValue and OldStateValue.

JSON Structures I currently have access to:

package main

type SNS struct {
    Type              string    `json:"Type"`
    MessageID         string    `json:"MessageId"`
    TopicArn          string    `json:"TopicArn"`
    Subject           string    `json:"Subject"`
    Message           string    `json:"Message"`
    Timestamp         string `json:"Timestamp"`
    SignatureVersion  string    `json:"SignatureVersion"`
    Signature         string    `json:"Signature"`
    SigningCertURL    string    `json:"SigningCertURL"`
    UnsubscribeURL    string    `json:"UnsubscribeURL"`
    MessageAttributes struct {
        Alias struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"alias"`
        Entity struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"entity"`
        Tags struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"tags"`
        EventType struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"eventType"`
        Recipients struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"recipients"`
        Teams struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"teams"`
        Actions struct {
            Type  string `json:"Type"`
            Value string `json:"Value"`
        } `json:"actions"`
    } `json:"MessageAttributes"`
}

package main

type CloudWatchAlarms struct {
        Records []struct {
                EventVersion         string `json:"EventVersion"`
                EventSubscriptionArn string `json:"EventSubscriptionArn"`
                EventSource          string `json:"EventSource"`
                Sns                  struct {
                        Signature         string `json:"Signature"`
                        MessageID         string `json:"MessageId"`
                        Type              string `json:"Type"`
                        TopicArn          string `json:"TopicArn"`
                        MessageAttributes struct {
                        } `json:"MessageAttributes"`
                        SignatureVersion string    `json:"SignatureVersion"`
                        Timestamp        string `json:"Timestamp"`
                        SigningCertURL   string    `json:"SigningCertUrl"`
                        Message          string    `json:"Message"`
                        UnsubscribeURL   string    `json:"UnsubscribeUrl"`
                        Subject          string    `json:"Subject"`
                } `json:"Sns"`
        } `json:"Records"`
}

package main

type CloudWatchAlarmMessage struct {
    AlarmName        string `json:"AlarmName"`
    AlarmDescription string `json:"AlarmDescription"`
    AWSAccountID     string `json:"AWSAccountId"`
    NewStateValue    string `json:"NewStateValue"`
    NewStateReason   string `json:"NewStateReason"`
    StateChangeTime  string `json:"StateChangeTime"`
    Region           string `json:"Region"`
    OldStateValue    string `json:"OldStateValue"`
    Trigger          struct {
        MetricName    string      `json:"MetricName"`
        Namespace     string      `json:"Namespace"`
        StatisticType string      `json:"StatisticType"`
        Statistic     string      `json:"Statistic"`
        Unit          interface{} `json:"Unit"`
        Dimensions    []struct {
            Name  string `json:"name"`
            Value string `json:"value"`
        } `json:"Dimensions"`
        Period                           int    `json:"Period"`
        EvaluationPeriods                int    `json:"EvaluationPeriods"`
        ComparisonOperator               string `json:"ComparisonOperator"`
        Threshold                        float64    `json:"Threshold"`
        TreatMissingData                 string `json:"TreatMissingData"`
        EvaluateLowSampleCountPercentile string `json:"EvaluateLowSampleCountPercentile"`
    } `json:"Trigger"`
}

If anyone has any insight it would be greatly appreciated.

Thanks.

  • 写回答

1条回答 默认 最新

  • dongzongxun8491 2018-09-29 22:48
    关注

    If I understood correctly your question, you're trying to catch a cloudwatch event and, if certain conditions are met, you want to send a message to a SNS. I belive the code below might be helpful, it's a lambda that's fired on a cloudwatch event that sends a message to sns when conditions met

    import(
      "context"
      "github.com/aws/aws-sdk-go/aws"
      "github.com/aws/aws-lambda-go/events"
      "github.com/aws/aws-lambda-go/lambda"
      "github.com/aws/aws-sdk-go/aws/session"
      "github.com/aws/aws-sdk-go/service/sns"
    )
    //React to cloudwatch events
    func handler(ctx context.Context, cloudWatchEvent events.CloudWatchEvent) error {
      //In case event met your conditions
      if string(cloudWatchEvent.Detail) == "Detail you expect to trigger sns" {
        //create session for sns service
        sess := session.New()
        //init sns service
        snsService := sns.New(sess)
        //publish message to sns
        snsService.Publish(&sns.PublishInput{
            Message:  aws.String("Your message"), //you can marshall the cloudwatch event here
            TopicArn: aws.String("your sns topic"),
        })
        //handle error/success here
        if err != nil {
            log.Print(err)
        } else {
            log.Printf("Message %s sent", output.MessageId)
        }
      }
      return nil
    }
    
    func main() {
      lambda.Start(handler)
    }
    

    Hope this gives you some help :)

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器