mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-17 18:52:30 -05:00
Removed all existing statsd logging and replaced with: - statsd decorator. Infers the stat name from the decorated function call. Delegates statsd call to statsd client. Calls incr and timing for each decorated method. This is applied to all tasks and all dao methods that touch the notifications/notification_history tables - statsd client changed to prefix all stats with "notification.api." - Relies on https://github.com/alphagov/notifications-utils/pull/61 for request logging. Once integrated we pass the statsd client to the logger, allowing us to statsd all API calls. This passes in the start time and the method to be called (NOT the url) onto the global flask object. We then construct statsd counters and timers in the following way notifications.api.POST.notifications.send_notification.200 This should allow us to aggregate to the level of - API or ADMIN - POST or GET etc - modules - methods - status codes Finally we count the callbacks received from 3rd parties to mapped status.
103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
from datetime import datetime, timedelta
|
|
|
|
from flask import current_app
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
|
|
from app import notify_celery
|
|
from app.clients import STATISTICS_FAILURE
|
|
from app.dao.invited_user_dao import delete_invitations_created_more_than_two_days_ago
|
|
from app.dao.notifications_dao import delete_notifications_created_more_than_a_week_ago, get_notifications, \
|
|
update_notification_status_by_id
|
|
from app.dao.users_dao import delete_codes_older_created_more_than_a_day_ago
|
|
from app.statsd_decorators import statsd
|
|
|
|
|
|
@notify_celery.task(name="delete-verify-codes")
|
|
@statsd(namespace="tasks")
|
|
def delete_verify_codes():
|
|
try:
|
|
start = datetime.utcnow()
|
|
deleted = delete_codes_older_created_more_than_a_day_ago()
|
|
current_app.logger.info(
|
|
"Delete job started {} finished {} deleted {} verify codes".format(start, datetime.utcnow(), deleted)
|
|
)
|
|
except SQLAlchemyError:
|
|
current_app.logger.info("Failed to delete verify codes")
|
|
raise
|
|
|
|
|
|
@notify_celery.task(name="delete-successful-notifications")
|
|
@statsd(namespace="tasks")
|
|
def delete_successful_notifications():
|
|
try:
|
|
start = datetime.utcnow()
|
|
deleted = delete_notifications_created_more_than_a_week_ago('delivered')
|
|
current_app.logger.info(
|
|
"Delete job started {} finished {} deleted {} successful notifications".format(
|
|
start,
|
|
datetime.utcnow(),
|
|
deleted
|
|
)
|
|
)
|
|
except SQLAlchemyError:
|
|
current_app.logger.info("Failed to delete successful notifications")
|
|
raise
|
|
|
|
|
|
@notify_celery.task(name="delete-failed-notifications")
|
|
@statsd(namespace="tasks")
|
|
def delete_failed_notifications():
|
|
try:
|
|
start = datetime.utcnow()
|
|
deleted = delete_notifications_created_more_than_a_week_ago('failed')
|
|
deleted += delete_notifications_created_more_than_a_week_ago('technical-failure')
|
|
deleted += delete_notifications_created_more_than_a_week_ago('temporary-failure')
|
|
deleted += delete_notifications_created_more_than_a_week_ago('permanent-failure')
|
|
current_app.logger.info(
|
|
"Delete job started {} finished {} deleted {} failed notifications".format(
|
|
start,
|
|
datetime.utcnow(),
|
|
deleted
|
|
)
|
|
)
|
|
except SQLAlchemyError:
|
|
current_app.logger.info("Failed to delete failed notifications")
|
|
raise
|
|
|
|
|
|
@notify_celery.task(name="delete-invitations")
|
|
@statsd(namespace="tasks")
|
|
def delete_invitations():
|
|
try:
|
|
start = datetime.utcnow()
|
|
deleted = delete_invitations_created_more_than_two_days_ago()
|
|
current_app.logger.info(
|
|
"Delete job started {} finished {} deleted {} invitations".format(start, datetime.utcnow(), deleted)
|
|
)
|
|
except SQLAlchemyError:
|
|
current_app.logger.info("Failed to delete invitations")
|
|
raise
|
|
|
|
|
|
@notify_celery.task(name='timeout-sending-notifications')
|
|
@statsd(namespace="tasks")
|
|
def timeout_notifications():
|
|
# TODO: optimize the query by adding the date where clause to this query.
|
|
notifications = get_notifications(filter_dict={'status': 'sending'})
|
|
now = datetime.utcnow()
|
|
for noti in notifications:
|
|
try:
|
|
if (now - noti.created_at) > timedelta(
|
|
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD')
|
|
):
|
|
# TODO: think about making this a bulk update rather than one at a time.
|
|
updated = update_notification_status_by_id(noti.id, 'temporary-failure', STATISTICS_FAILURE)
|
|
if updated:
|
|
current_app.logger.info(("Timeout period reached for notification ({})"
|
|
", status has been updated.").format(noti.id))
|
|
except Exception as e:
|
|
current_app.logger.exception(e)
|
|
current_app.logger.error((
|
|
"Exception raised trying to timeout notification ({})"
|
|
", skipping notification update.").format(noti.id))
|