From b14e6e545ed6ed87f8f00d65f4c6469d6013098e Mon Sep 17 00:00:00 2001 From: Tim Ballard <1425377+timoballard@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:36:32 -0600 Subject: [PATCH] Decorator for generating New Relic timing metrics (#3464) * fiddling with nr metrics * more nr metric tinkering * actually profile search * rm unused * lint * move decorators to support app --- backend/audit/validators.py | 4 +++- backend/dissemination/views.py | 2 ++ backend/support/decorators.py | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 backend/support/decorators.py diff --git a/backend/audit/validators.py b/backend/audit/validators.py index 8bd43bd661..41bdfc9fc3 100644 --- a/backend/audit/validators.py +++ b/backend/audit/validators.py @@ -1,6 +1,7 @@ import os import json import logging + from jsonschema import Draft7Validator, FormatChecker, validate from jsonschema.exceptions import ValidationError as JSONSchemaValidationError @@ -12,7 +13,6 @@ from openpyxl import load_workbook from pypdf import PdfReader - from audit.intakelib import ( additional_ueis_named_ranges, additional_eins_named_ranges, @@ -33,6 +33,7 @@ SECONDARY_AUDITORS_TEMPLATE_DEFINITION, NOTES_TO_SEFA_TEMPLATE_DEFINITION, ) +from support.decorators import newrelic_timing_metric logger = logging.getLogger(__name__) @@ -392,6 +393,7 @@ def _scan_file(file): ) +@newrelic_timing_metric("validate_file_infection") def validate_file_infection(file): """Files must pass an AV scan""" logger.info(f"Attempting to scan file: {file}.") diff --git a/backend/dissemination/views.py b/backend/dissemination/views.py index 79bc293f98..f6a7f5f635 100644 --- a/backend/dissemination/views.py +++ b/backend/dissemination/views.py @@ -30,6 +30,7 @@ OneTimeAccess, ) from dissemination.summary_reports import generate_summary_report +from support.decorators import newrelic_timing_metric from users.permissions import can_read_tribal @@ -128,6 +129,7 @@ def get(self, request, *args, **kwargs): }, ) + @newrelic_timing_metric("search") def post(self, request, *args, **kwargs): """ When accessing the search page through post, run a search and display the results. diff --git a/backend/support/decorators.py b/backend/support/decorators.py new file mode 100644 index 0000000000..3cb6257736 --- /dev/null +++ b/backend/support/decorators.py @@ -0,0 +1,24 @@ +import functools +import logging +import time + +import newrelic.agent + +logger = logging.getLogger(__name__) + + +def newrelic_timing_metric(metric_name): + def inner(func): + @functools.wraps(func) + def wrapper_timer(*args, **kwargs): + start_time = time.perf_counter() + value = func(*args, **kwargs) + end_time = time.perf_counter() + run_time = end_time - start_time + logger.info(f"{metric_name} executed in {run_time:.4f} secs") + newrelic.agent.record_custom_metric(f"Custom/{metric_name}", run_time) + return value + + return wrapper_timer + + return inner