From 4f34b6eaae017cab29483ce24409c110a67a22ed Mon Sep 17 00:00:00 2001 From: Josh Bonczkowski Date: Fri, 13 Mar 2026 12:09:15 -0400 Subject: [PATCH] Address reviewer feedback on New Relic integration. - Fix _record_error_metric to use app.record_custom_metric() instead of module-level newrelic.agent.record_custom_metric() so the call works outside of an active transaction context - Remove unreachable except ImportError block in _get_trace_context - Update stale "23 hours" comment to "27 hours" (matches 97200s threshold) - Remove commented-out debug code from _process_success - Fix docs typo: NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_SAMPLES_STOREDA -> NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_SAMPLES_STORED - Update TestRecordErrorMetric to verify app.record_custom_metric call Co-Authored-By: Claude Sonnet 4.6 --- docs/my-website/docs/observability/newrelic.md | 2 +- litellm/integrations/newrelic/newrelic.py | 17 ++++------------- .../integrations/newrelic/test_newrelic.py | 5 +++-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/docs/my-website/docs/observability/newrelic.md b/docs/my-website/docs/observability/newrelic.md index 90d818fd85d..d6ef5f0f740 100644 --- a/docs/my-website/docs/observability/newrelic.md +++ b/docs/my-website/docs/observability/newrelic.md @@ -78,5 +78,5 @@ The New Relic LiteLLM Extension will send telemetry to New Relic so that the mes ```shell NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_ATTRIBUTE_VALUE=4095 -NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_SAMPLES_STOREDA=100000 +NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_SAMPLES_STORED=100000 ``` diff --git a/litellm/integrations/newrelic/newrelic.py b/litellm/integrations/newrelic/newrelic.py index 6f2ac539b86..86fa648d164 100644 --- a/litellm/integrations/newrelic/newrelic.py +++ b/litellm/integrations/newrelic/newrelic.py @@ -265,11 +265,6 @@ class NewRelicLogger(CustomLogger): return trace_id, span_id - except ImportError: - verbose_logger.warning( - "New Relic Python agent not available." - ) - return None, None except Exception as e: verbose_logger.warning(f"Unable to get New Relic trace context: {e}") return None, None @@ -600,7 +595,9 @@ class NewRelicLogger(CustomLogger): """Record error metric to New Relic.""" try: import newrelic.agent - newrelic.agent.record_custom_metric("LLM/LiteLLM/Error", 1) + app = newrelic.agent.application() + if app: + app.record_custom_metric("LLM/LiteLLM/Error", 1) except Exception as e: verbose_logger.warning(f"Failed to record New Relic error metric: {e}") self.handle_callback_failure("newrelic") @@ -620,20 +617,14 @@ class NewRelicLogger(CustomLogger): if not self.enabled: return - # Check and emit periodic supportability metric if 23 hours have passed + # Check and emit periodic supportability metric if 27 hours have passed self._check_and_emit_periodic_metric() - # import pprint - # verbose_logger.info(f"newrelic._process_success called, kwargs=\n{pprint.pformat(kwargs)}, \nresponse_obj=\n{pprint.pformat(response_obj)}") - # Get trace context trace_id, span_id = self._get_trace_context(kwargs) if not trace_id: - # verbose_logger.debug("No trace_id available, skipping New Relic event recording.") return - # verbose_logger.info(f"Trace ID: {trace_id}, Span ID: {span_id or '(none)'}") - # Generate unique request ID for this request (used as Summary event id) request_id = str(uuid.uuid4()) diff --git a/tests/test_litellm/integrations/newrelic/test_newrelic.py b/tests/test_litellm/integrations/newrelic/test_newrelic.py index fce9db561e5..2c882083531 100644 --- a/tests/test_litellm/integrations/newrelic/test_newrelic.py +++ b/tests/test_litellm/integrations/newrelic/test_newrelic.py @@ -396,8 +396,9 @@ class TestProcessSuccess: class TestRecordErrorMetric: def test_calls_record_custom_metric(self): logger = make_logger() + mock_app = MagicMock() - with patch("newrelic.agent.record_custom_metric") as mock_metric: + with patch("newrelic.agent.application", return_value=mock_app): logger._record_error_metric() - mock_metric.assert_called_once_with("LLM/LiteLLM/Error", 1) + mock_app.record_custom_metric.assert_called_once_with("LLM/LiteLLM/Error", 1)