From c4120cff1b9bfc352683ba60e14bc477b1a041d5 Mon Sep 17 00:00:00 2001 From: Ben Kehoe Date: Mon, 2 Nov 2015 11:12:37 -0500 Subject: [PATCH 1/2] add debug logging of traceback on error --- cfnlambda.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cfnlambda.py b/cfnlambda.py index 9841b7e..410d132 100644 --- a/cfnlambda.py +++ b/cfnlambda.py @@ -19,6 +19,7 @@ from functools import wraps import boto3 from botocore.vendored import requests +import traceback logger = logging.getLogger(__name__) @@ -221,6 +222,7 @@ def handler_wrapper(event, context): (handler.__name__, e.message)) result = {'result': message} logger.error(message) + logger.debug(traceback.format_exc()) if event['RequestType'] == RequestType.DELETE: if status == Status.FAILED and hide_stack_delete_failure: From 2f24453a2525f47d9d84d565cf0ab2734be1ea22 Mon Sep 17 00:00:00 2001 From: Ben Kehoe Date: Tue, 3 Nov 2015 07:54:40 -0500 Subject: [PATCH 2/2] more informative logging, better return values --- cfnlambda.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/cfnlambda.py b/cfnlambda.py index 410d132..51c239f 100644 --- a/cfnlambda.py +++ b/cfnlambda.py @@ -20,6 +20,7 @@ import boto3 from botocore.vendored import requests import traceback +import httplib logger = logging.getLogger(__name__) @@ -93,7 +94,7 @@ def cfn_response(event, CloudWatch Logs log stream is used. Returns: - None + requests.Response object Raises: No exceptions raised @@ -121,12 +122,18 @@ def cfn_response(event, try: response = requests.put(event['ResponseURL'], data=response_body) - logger.debug("Status code: %s" % response.status_code) + body_text = "" + if response.status_code // 100 != 2: + body_text = "\n" + response.text + logger.debug("Status code: %s %s%s" % (response.status_code, httplib.responses[response.status_code], body_text)) + # logger.debug("Status message: %s" % response.status_message) # how do we get the status message? + return response except Exception as e: logger.error("send(..) failed executing https.request(..): %s" % e.message) + logger.debug(traceback.format_exc()) def handler_decorator(delete_logs=True, @@ -209,6 +216,7 @@ def handler_wrapper(event, context): logger.info('REQUEST RECEIVED: %s' % json.dumps(event)) logger.info('LambdaContext: %s' % json.dumps(vars(context), cls=PythonObjectEncoder)) + result = None try: result = handler(event, context) status = Status.SUCCESS if result else Status.FAILED @@ -224,6 +232,9 @@ def handler_wrapper(event, context): logger.error(message) logger.debug(traceback.format_exc()) + if not result: + result = {} + if event['RequestType'] == RequestType.DELETE: if status == Status.FAILED and hide_stack_delete_failure: message = ( @@ -232,7 +243,7 @@ def handler_wrapper(event, context): 'despite the fact that the stack status may be ' 'DELETE_COMPLETE.') logger.error(message) - result['result'] += ' %s' % message + result['result'] = result.get('result', '') + ' %s' % message status = Status.SUCCESS if status == Status.SUCCESS and delete_logs: @@ -245,6 +256,6 @@ def handler_wrapper(event, context): status, (result if type(result) is dict else {'result': result})) - return handler(event, context) + return result return handler_wrapper return inner_decorator