Log messages to email via Amazon SES
Rate limiting and bouncing are currently not supported.
If you are using Django then this is also possible using Django's AdminEmailHandler and django-ses which supports rate limiting via AWS_SES_AUTO_THROTTLE.
pip install ses-log-handler
If you using IAM roles to get credentials for AWS or have the correct environment variables defined (see Boto3 configuration guide) then you can simply set a sender
and recipients
addresses for the handler:
import logging
logger = logging.getLogger(__name__)
ses_handler = SESHandler(
sender='[email protected]',
recipients=['[email protected]'],
)
ses_handler.setLevel(logging.ERROR)
logger.addHandler(ses_handler)
There is an example of how to configure the log hander using dictConfig()
and fileConfig()
Note: It is advised you set the log level to either CRITICAL
or ERROR
. This will stop the reciver_mails from being spammed by logs and you incuring a large SES bill.
If you want to explicitly set the access, secret and region this can also be when instantiating the SESHandler
.
It also possible to force the subject line to be the same for each email
mail_handler = SESHandler(
sender='[email protected]',
recipients=('[email protected]'),
access_key='<access-key>',
secret_key='<secret-key>',
region='<region>',
subject='Error: Exception raised',
)
Required: Who the log email should be sent from. The domain should be added and configured as a verified sender domain
Required: A list of recipients who should receive the log emails.
If your SES account only has "sandbox" access (see SES dashboard) these email addresses must be added as verified sender email address
Optional: The AWS access key for a user who has access to send emails via SES.
It is best practices for managing AWS access keys use instance roles instead of passing access keys to your application.
If the access_key argument is not provided then the SESHandler (which uses boto3) will fall back to getting credentials from either the instance role or environment variables. See the boto3 credentials guide for more information.
Optional: The AWS secret key for a user who has access to send emails via SES.
It is best practices for managing AWS access keys use instance roles instead of passing access keys to your application.
If the access_key argument is not provided then the SESHandler (which uses boto3) will fall back to getting credentials from either the instance role or environment variables. See the boto3 credentials guide for more information.
Optional: The AWS region which should be used to send emails via SES
By default the region that your application is running in will be used
Optional: Force overrides the subject line to be the same for each email.
The default is <log_level>: <message>
The below examples both create a logging config which logs everything ERROR
and above to SES and anything WARNING
and below to the console.
import logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'general': {
'format': '%(asctime)s %(name)s.%(funcName)s %(levelname)s [%(lineno)d] %(message)s', # NOQA: E501
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'general',
'level': 'INFO',
},
'ses': {
'class': 'ses_log_handler.SESHandler',
'formatter': 'general',
'level': 'ERROR',
'sender': '[email protected]',
'recipients': ['[email protected]'],
},
},
'root': {
'level': 'INFO',
'handlers': ['ses', 'console'],
}
}
logging.config.dictConfig(LOGGING)
[loggers]
keys=root
[handlers]
keys=sesHandler,consoleHandler
[formatters]
keys=generalFormatter
[logger_root]
level=INFO
handlers=sesHandler,consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=generalFormatter
args=(sys.stdout,)
[handler_sesHandler]
class=ses_log_handler.SESHandler
level=ERROR
formatter=generalFormatter
args=['[email protected]', ['[email protected]']]
[formatter_generalFormatter]
format=%(asctime)s %(name)s.%(funcName)s %(levelname)s [%(lineno)d] %(message)s
Then to load this config you can use
import logging
logging.config.fileConfig(
'logging.conf',
disable_existing_loggers=False
)