Browse Source

Redid function as a decorator.
Provided example code.
Updated documentation.

Fred Damstra 6 years ago
parent
commit
e5202333dd
4 changed files with 81 additions and 47 deletions
  1. 11 7
      README.md
  2. 14 0
      example.py
  3. 0 40
      lambda_function.py
  4. 56 0
      sns_error_notification.py

+ 11 - 7
README.md

@@ -1,12 +1,13 @@
-# aws_lambda_python_error_emailer
+# sns_error_notification
 
 
 ## Source
 ## Source
 The latest version of this code can be found at
 The latest version of this code can be found at
-https://github.com/fdamstra/aws_lambda_python_error_emailer
+https://github.com/fdamstra/sns_error_notification
 
 
 ## Description
 ## Description
-This is a simple template you can add to your existing AWS Lambda python code
-so that it will email you details on your exceptions and errors.
+This is a simple python decorate for the aws serverless (lambda) 
+functions to make it easy to add email notification (or other SNS
+handling) for errors and exceptions.
 
 
 You can use CloudWatch to alert on errors, but then you just know that
 You can use CloudWatch to alert on errors, but then you just know that
 something went wrong, not _what_ went wrong. 
 something went wrong, not _what_ went wrong. 
@@ -46,7 +47,10 @@ second.
 ## Set Up
 ## Set Up
 1. Configure an SNS topic.
 1. Configure an SNS topic.
 2. Subscribe to the SNS topic using your email address.
 2. Subscribe to the SNS topic using your email address.
-3. Verify your subscription.
-4. Rename your `lambda_handler` function.
-5. Add the code from `lambda_function.py` to your function and make it the new handler.
+3. Grant your lanbda function `sns:Publish` permission.
+4. Set the environment variable `sns_error_topic` to your SNS topic's arn.
+5. Add `from sns_error_notification import sns_error_notification` to your handler.
+6. Add the line `@sns_error_notification` directly before your handler function.
+
+See the example.py for an example.
 
 

+ 14 - 0
example.py

@@ -0,0 +1,14 @@
+#! /usr/bin/env python3
+from sns_error_notification import sns_error_notification
+
+def myfunc(a):
+    # Myfunc generates an exception
+    print(a[1])
+    return True
+
+@sns_error_notification
+def lambda_handler(event, context):
+    # Our lambda handler doesn't have any error.
+    myfunc(123)
+    return True
+

+ 0 - 40
lambda_function.py

@@ -1,40 +0,0 @@
-#! /usr/bin/env python3
-import boto3
-import json
-import traceback
-
-# Insert original code here:
-
-# Rename your original lambda_handler() to lambda_handler_noemail()
-def lambda_handler_noemail(event, context):
-    # if you start generating too many emails, you can always change
-    # the handler back to this.
-    return True
-
-# Make this your caller.
-def lambda_handler(event, context):
-    # Set this to an SNS topic you'd like to publish to.
-    sns_arn = 'arn:aws:sns:us-east-2:1234567890:lambda-errors',
-    try:
-        snsclient = boto3.client('sns')
-        return lambda_handler_unhandled(event, context)
-    except Exception as e:
-        subject = f'Execution Error in {context.function_name}'
-        estr = str(e)
-        tb = traceback.format_exc()
-        try:
-            event_dump = json.dumps(event, indent=2)
-        except:
-            event_dump = "ERROR"
-        try: 
-            context_dump = vars(context)
-        except:
-            context_dump = "ERROR"
-        message = f'Exception: {estr}\n\nTraceback: {tb}\n\nEvent: {event_dump}\n\nContext: {context_dump}\n'
-        # Only happens if there was an exception
-        snsclient.publish(
-            Subject=subject,
-            TopicArn=sns_arn,
-            Message=message
-        )
-        raise

+ 56 - 0
sns_error_notification.py

@@ -0,0 +1,56 @@
+#! /usr/bin/env python3
+''' sns_error_notification is intended as a wrapper around the `lambda_handler()`
+    function in an AWS serverless design. It catches errors and exceptions and
+    posts them to an sns queue, which can then be subscribed to for emails or
+    handled by another lambda function. 
+
+    To use:
+      1) Set the environment variable 'sns_error_topic' in your lambda
+         function to the arn of an SNS topic.
+      2) Ensure your lambda function has permission for `sns:Publish` to
+         the sns topic.
+      3) Import this function via 
+         `from sns_error_notification import sns_error_nofication`
+      4) Add `@sns_error_notification` directly before your lambda_handler
+         definition (`def lambda_handler(event, context):`)
+
+    WARNING: Could potentially generate a lot of email traffic on a high
+             volume function. Watch your execution errors metric in 
+             CloudWatch before deploying.
+
+    See https://github.com/fdamstra/sns_error_notification
+'''
+import boto3
+import json
+import os
+import traceback
+
+def sns_error_notification(function_name):
+    def wrapper(event, context):
+        try:
+            sns_arn = os.environ.get('sns_error_topic',
+              'Please set an environment variable "sns_error" topic')            
+            snsclient = boto3.client('sns')
+            function_name(event, context)
+        except Exception as e:
+            # First level error handling, send full details
+            subject = f'Execution Error in {context.function_name}'
+            estr = str(e)
+            tb = traceback.format_exc()
+            try:
+                event_dump = json.dumps(event, indent=2)
+            except:
+                event_dump = "ERROR"
+            try:
+                context_dump = vars(context)
+            except:
+                context_dump = "ERROR"
+            message = f'Exception:\n{estr}\n\nTraceback:\n{tb}\n\nEvent:\n{event_dump}\n\nContext:\n{context_dump}\n'
+            # Only happens if there was an exception
+            snsclient.publish(
+                TopicArn='arn:aws:sns:us-east-2:082012130604:lambda-errors',
+                Subject=subject,
+                Message=message
+            )
+            raise
+    return wrapper