Skip to content

Instantly share code, notes, and snippets.

@sjakthol
Created June 18, 2022 06:23
Show Gist options
  • Save sjakthol/a635e45b2da344b61db7d05bb6a0fbd3 to your computer and use it in GitHub Desktop.
Save sjakthol/a635e45b2da344b61db7d05bb6a0fbd3 to your computer and use it in GitHub Desktop.
Python code snippet for logging failed AWS API calls with boto3 / botocore
import logging
import boto3
def _log_botocore_errors(*_args, **kwargs):
"""Handler for botocore needs-retry events."""
# Arg parsing as per
# https://github.com/boto/botocore/blob/6451ae1fad57f4453af97649e7ed9192b0f623be/botocore/retries/standard.py#L106
attempt_number = kwargs["attempts"]
operation_model = kwargs["operation"]
operation_name = operation_model.name
response = kwargs["response"]
if response is None:
parsed_response = None
else:
_, parsed_response = response
caught_exception = kwargs["caught_exception"]
if parsed_response is None and caught_exception:
logging.warning(
"%s failed with exception (attempt %i)",
operation_name,
attempt_number,
exc_info=caught_exception,
)
return
if parsed_response is None:
# No response or exception?
return
error = parsed_response.get("Error", {})
if not error:
# All good
return
metadata = parsed_response.get("ResponseMetadata", {})
status_code = metadata.get("HTTPStatusCode")
code = error.get("Code")
message = error.get("Message")
logging.warning(
"%s error: %s - %s (status %s; attempt %i)",
operation_name,
code,
message,
status_code,
attempt_number,
)
def _register_error_logger_for_resource(resource):
"""Register error logger for botocore service resource.
Args:
resource: Service resource.
"""
_register_error_logger_for_client(resource.meta.client)
def _register_error_logger_for_client(client):
"""Register error logger for botocore client.
Args:
client: Client.
"""
client.meta.events.register(
"needs-retry", _log_botocore_errors
)
# Example usage
ddb_resource = boto3.resource("dynamodb")
ddb_client = boto3.client("dynamodb")
logging.basicConfig(level=logging.WARNING)
_register_error_logger_for_resource(ddb_resource)
_register_error_logger_for_client(ddb_client)
ddb_client.list_tables()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment