mweagle / Sparta

go microservices, powered by AWS Lambda
https://gosparta.io
MIT License
716 stars 48 forks source link

Creating Lambda CloudWatch Alarms #52

Closed dhanson358 closed 7 years ago

dhanson358 commented 7 years ago

Not 100% sure this is the right place for this question, but I'm going to try anyway.

I'm creating a Lambda with Sparta and want to also create a corresponding CloudWatch Alarm to notify me if my new Lambda has an error count past a certain threshold.

I tried putting this in my Lambda decorator, but in that context I can only get the new Lambda's ARN using the GetAttr function. However, my CloudWatchMetricDimension doesn't seem to want the Lambda ARN, only the Lambda function name. I don't know this as far as I can tell.

Is there some way to know this at code-time? Obviously I'm setting the basename of the function myself, but the extra randomized data Sparta adds I'm not sure of.

For reference, this is the code I'm putting in my decorator now. It creates an alarm, but the alarm is pointing to the ARN of the Lambda function and never records any data.

    var alarmDimensions gocf.CloudWatchMetricDimensionList
    alarmDimension := gocf.CloudWatchMetricDimension{Name: gocf.String("Resource"), Value: gocf.GetAtt(lambdaResourceName, "Arn").String()} // seems like the "value" here is supposed to be the function name, and using the GetAtt for the ARN won't suffice
    alarmDimensions = []gocf.CloudWatchMetricDimension{alarmDimension}

    mqttLambdaAlarm := &gocf.CloudWatchAlarm{
        ActionsEnabled:     gocf.Bool(true),
        AlarmActions:       gocf.StringList(gocf.String(SNS_Notification)),
        AlarmName:          gocf.String("MQTTLambdaProductionAlarm"),
        ComparisonOperator: gocf.String("GreaterThanOrEqualToThreshold"),
        Dimensions:         &alarmDimensions,
        EvaluationPeriods:  gocf.String("1"),
        Period:             gocf.String("300"),
        MetricName:         gocf.String("Errors"),
        Namespace:          gocf.String("AWS/Lambda"),
        Statistic:          gocf.String("Sum"),
        Threshold:          gocf.String("3.0"),
        Unit:               gocf.String("Count"),
    }
    cfTemplate.AddResource("MQTTLambdaProductionAlarm", mqttLambdaAlarm)
mweagle commented 7 years ago

Yep - it's the right place. There is some sanitization done for the NodeJS/Python shim - is this what you need for the dimension? Have you tried:

gocf.Ref(lambdaResourceName).String()

(I'm not sure what that returns for a Lambda). If not, we will find a way to get that information plumbed through to support this (which is a good use case). Thanks.

dhanson358 commented 7 years ago

Excellent, that did it. I had to make sure my metric dimension name was right too. It's a bit tricky because you can enter wildly inaccurate data and CloudWatch doesn't throw errors, it just produces alarms that will never do anything... easy to get a false sense of security.

This is what worked for my alarm dimension:

alarmDimension := gocf.CloudWatchMetricDimension{Name: gocf.String("FunctionName"), Value: gocf.Ref(lambdaResourceName).String()}

I'd be happy to contribute back some documentation on setting up alarms for Lambda functions if you can point me to the right place. Seems like it would be (or should be) an incredibly common use-case.

Thanks for the help!

mweagle commented 7 years ago

Excellent - I'd like to uplevel the operations documentation, but for now maybe the best place is: https://github.com/mweagle/Sparta/blob/docs/content/docs/faq.md#operations

Appreciate the help! Once merged I'll push up the new site.

If you have hugo v0.20.x on the $PATH, you can preview the documentation site by checking out the docs branch and running make edit && opening http://localhost:1313.