diff --git a/relay/__init__.py b/relay/__init__.py index c90fbb2..fed32d8 100644 --- a/relay/__init__.py +++ b/relay/__init__.py @@ -28,3 +28,4 @@ from . import actor from . import webfinger from . import default from . import nodeinfo +from . import http_stats diff --git a/relay/http_debug.py b/relay/http_debug.py index 4bb87c3..e6e5ab4 100644 --- a/relay/http_debug.py +++ b/relay/http_debug.py @@ -1,12 +1,66 @@ import logging import aiohttp +import aiohttp.web + +from collections import defaultdict + + +STATS = { + 'requests': defaultdict(int), + 'response_codes': defaultdict(int), + 'response_codes_per_domain': defaultdict(lambda: defaultdict(int)), + 'delivery_codes': defaultdict(int), + 'delivery_codes_per_domain': defaultdict(lambda: defaultdict(int)), + 'exceptions': defaultdict(int), + 'exceptions_per_domain': defaultdict(lambda: defaultdict(int)), + 'delivery_exceptions': defaultdict(int), + 'delivery_exceptions_per_domain': defaultdict(lambda: defaultdict(int)) +} async def on_request_start(session, trace_config_ctx, params): + global STATS + logging.debug("HTTP START [%r], [%r]", session, params) + STATS['requests'][params.url.host] += 1 + + +async def on_request_end(session, trace_config_ctx, params): + global STATS + + logging.debug("HTTP END [%r], [%r]", session, params) + + host = params.url.host + status = params.response.status + + STATS['response_codes'][status] += 1 + STATS['response_codes_per_domain'][host][status] += 1 + + if params.method == 'POST': + STATS['delivery_codes'][status] += 1 + STATS['delivery_codes_per_domain'][host][status] += 1 + + +async def on_request_exception(session, trace_config_ctx, params): + global STATS + + logging.debug("HTTP EXCEPTION [%r], [%r]", session, params) + + host = params.url.host + exception = repr(params.exception) + + STATS['exceptions'][exception] += 1 + STATS['exceptions_per_domain'][host][exception] += 1 + + if params.method == 'POST': + STATS['delivery_exceptions'][exception] += 1 + STATS['delivery_exceptions_per_domain'][host][exception] += 1 + def http_debug(): trace_config = aiohttp.TraceConfig() trace_config.on_request_start.append(on_request_start) + trace_config.on_request_end.append(on_request_end) + trace_config.on_request_exception.append(on_request_exception) return trace_config diff --git a/relay/http_stats.py b/relay/http_stats.py new file mode 100644 index 0000000..09193c9 --- /dev/null +++ b/relay/http_stats.py @@ -0,0 +1,11 @@ +import aiohttp.web + +from . import app +from .http_debug import STATS + + +async def stats(request): + return aiohttp.web.json_response(STATS) + + +app.router.add_get('/stats', stats)