mirror of
https://github.com/GSA/notifications-api.git
synced 2026-06-22 06:01:04 -04: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.
124 lines
4.8 KiB
Python
124 lines
4.8 KiB
Python
import uuid
|
|
import os
|
|
|
|
from flask import request, url_for, g, current_app
|
|
from flask import Flask, _request_ctx_stack
|
|
from flask.ext.sqlalchemy import SQLAlchemy
|
|
from flask_marshmallow import Marshmallow
|
|
from monotonic import monotonic
|
|
from werkzeug.local import LocalProxy
|
|
from notifications_utils import logging
|
|
from app.celery.celery import NotifyCelery
|
|
from app.clients import Clients
|
|
from app.clients.sms.mmg import MMGClient
|
|
from app.clients.sms.firetext import FiretextClient
|
|
from app.clients.sms.loadtesting import LoadtestingClient
|
|
from app.clients.email.aws_ses import AwsSesClient
|
|
from app.clients.statsd.statsd_client import StatsdClient
|
|
from app.encryption import Encryption
|
|
|
|
|
|
DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
|
|
DATE_FORMAT = "%Y-%m-%d"
|
|
|
|
db = SQLAlchemy()
|
|
ma = Marshmallow()
|
|
notify_celery = NotifyCelery()
|
|
firetext_client = FiretextClient()
|
|
loadtest_client = LoadtestingClient()
|
|
mmg_client = MMGClient()
|
|
aws_ses_client = AwsSesClient()
|
|
encryption = Encryption()
|
|
statsd_client = StatsdClient()
|
|
|
|
clients = Clients()
|
|
|
|
api_user = LocalProxy(lambda: _request_ctx_stack.top.api_user)
|
|
|
|
|
|
def create_app(app_name=None):
|
|
application = Flask(__name__)
|
|
|
|
from config import configs
|
|
application.config.from_object(configs[os.environ['NOTIFY_ENVIRONMENT']])
|
|
|
|
if app_name:
|
|
application.config['NOTIFY_APP_NAME'] = app_name
|
|
|
|
init_app(application)
|
|
db.init_app(application)
|
|
ma.init_app(application)
|
|
statsd_client.init_app(application)
|
|
logging.init_app(application, statsd_client)
|
|
firetext_client.init_app(application, statsd_client=statsd_client)
|
|
loadtest_client.init_app(application, statsd_client=statsd_client)
|
|
mmg_client.init_app(application, statsd_client=statsd_client)
|
|
aws_ses_client.init_app(application.config['AWS_REGION'], statsd_client=statsd_client)
|
|
notify_celery.init_app(application)
|
|
encryption.init_app(application)
|
|
clients.init_app(sms_clients=[firetext_client, mmg_client, loadtest_client], email_clients=[aws_ses_client])
|
|
|
|
from app.service.rest import service as service_blueprint
|
|
from app.user.rest import user as user_blueprint
|
|
from app.template.rest import template as template_blueprint
|
|
from app.status.healthcheck import status as status_blueprint
|
|
from app.job.rest import job as job_blueprint
|
|
from app.notifications.rest import notifications as notifications_blueprint
|
|
from app.invite.rest import invite as invite_blueprint
|
|
from app.accept_invite.rest import accept_invite
|
|
from app.notifications_statistics.rest import notifications_statistics as notifications_statistics_blueprint
|
|
from app.template_statistics.rest import template_statistics as template_statistics_blueprint
|
|
from app.events.rest import events as events_blueprint
|
|
from app.provider_details.rest import provider_details as provider_details_blueprint
|
|
from app.spec.rest import spec as spec_blueprint
|
|
|
|
application.register_blueprint(service_blueprint, url_prefix='/service')
|
|
application.register_blueprint(user_blueprint, url_prefix='/user')
|
|
application.register_blueprint(template_blueprint)
|
|
application.register_blueprint(status_blueprint)
|
|
application.register_blueprint(notifications_blueprint)
|
|
application.register_blueprint(job_blueprint)
|
|
application.register_blueprint(invite_blueprint)
|
|
application.register_blueprint(accept_invite, url_prefix='/invite')
|
|
application.register_blueprint(notifications_statistics_blueprint)
|
|
application.register_blueprint(template_statistics_blueprint)
|
|
application.register_blueprint(events_blueprint)
|
|
application.register_blueprint(provider_details_blueprint, url_prefix='/provider-details')
|
|
application.register_blueprint(spec_blueprint, url_prefix='/spec')
|
|
|
|
return application
|
|
|
|
|
|
def init_app(app):
|
|
@app.before_request
|
|
def required_authentication():
|
|
no_auth_req = [
|
|
url_for('status.show_status'),
|
|
url_for('notifications.process_ses_response'),
|
|
url_for('notifications.process_firetext_response'),
|
|
url_for('notifications.process_mmg_response'),
|
|
url_for('status.show_delivery_status'),
|
|
url_for('spec.get_spec')
|
|
]
|
|
if request.path not in no_auth_req:
|
|
from app.authentication import auth
|
|
error = auth.requires_auth()
|
|
if error:
|
|
return error
|
|
|
|
@app.before_request
|
|
def record_request_details():
|
|
g.start = monotonic()
|
|
g.endpoint = request.endpoint
|
|
|
|
@app.after_request
|
|
def after_request(response):
|
|
response.headers.add('Access-Control-Allow-Origin', '*')
|
|
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
|
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
|
|
return response
|
|
|
|
|
|
def create_uuid():
|
|
return str(uuid.uuid4())
|