Skip to content

chore: Log New Relic collector response headers at debug level.#3655

Open
jaffinito wants to merge 2 commits into
mainfrom
chore/response-header-logging
Open

chore: Log New Relic collector response headers at debug level.#3655
jaffinito wants to merge 2 commits into
mainfrom
chore/response-header-logging

Conversation

@jaffinito

@jaffinito jaffinito commented Jun 24, 2026

Copy link
Copy Markdown
Member

Description

What
Log the collector's HTTP response headers to the agent debug log, on both the success and error paths.

Why (NR-132421)
Only the response body was logged. Headers (cloudflare, request id, geo markers) are needed by support to diagnose 503s and Cloudflare failures.

How

  • Added IHttpResponse.GetHeaders(); implemented on HttpResponse (.NET Core) and WebRequestClientResponse (.NET Framework).
  • Exposed Headers on IHttpResponseMessageWrapper for the Core mock seam.
  • Added HttpResponseHeaderFormatter (pure helper) with IEnumerable<KeyValuePair<...>> and #if NETFRAMEWORK WebHeaderCollection overloads. Output: cf-ray=[abc-DFW]; x-request-id=[id-1], or (none).
  • HttpCollectorWire.SendData logs headers at debug on success and error paths, guarded by Log.IsDebugEnabled (GetHeaders builds its string eagerly).
  • Has some protection to prevent headers containing "auth", "token", or "key" from outputting their values to the logs.

Tests

  • HttpResponseHeaderFormatterTests, HttpResponseTests, WebRequestClientResponseTests, HttpCollectorWireTests (guard verified both ways).
  • Pass on net10.0 and net481.

Author Checklist

  • Unit tests, Integration tests, and Unbounded tests completed
  • Performance testing completed with satisfactory results (if required)

Reviewer Checklist

  • Perform code review
  • Pull request was adequately tested (new/existing tests, performance tests)

Fixes #112

@jaffinito jaffinito requested a review from a team as a code owner June 24, 2026 17:23
// Possibly combine these logs? makes parsing harder in tests...
Log.Debug("Request({0}): Invoked \"{1}\" with : {2}", requestGuid, method, serializedData);
Log.Debug("Request({0}): Invocation of \"{1}\" yielded response : {2}", requestGuid, method, responseContent);
if (Log.IsDebugEnabled)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not also put the two Log.Debug statements above this line inside the if block?

@jaffinito jaffinito Jun 24, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could have, but they don't need to be. My header line calls response.GetHeaders() — that executes regardless of log level (iterate headers, string.Join, allocate). Serilog/NoOp can drop the message, but it can't un-run the method that built the argument. The guard skips that work when Debug is off (the production default).

The existing lines pass serializedData / responseContent — strings that already exist. When Debug is off, the logger drops the message and those strings cost nothing extra.

@tippmar-nr

Copy link
Copy Markdown
Member

Are there likely to be any headers carrying sensitive data that we should avoid logging or obfuscate if we do log?

@jaffinito

Copy link
Copy Markdown
Member Author

In the request headers, definitely. In the response headers, I would not expect there to be sensitive data. I will do a quick google survey to see if anything comes up.

@jaffinito

Copy link
Copy Markdown
Member Author

I added some basic protection for headers that might have data we don't want in logs.

@tippmar-nr tippmar-nr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! LGTM

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.20690% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.00%. Comparing base (a25252e) to head (d907918).

Files with missing lines Patch % Lines
...ataTransport/Client/HttpResponseHeaderFormatter.cs 86.36% 2 Missing and 1 partial ⚠️
...DataTransport/Client/HttpResponseMessageWrapper.cs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3655   +/-   ##
=======================================
  Coverage   81.99%   82.00%           
=======================================
  Files         511      512    +1     
  Lines       34724    34753   +29     
  Branches     4134     4140    +6     
=======================================
+ Hits        28473    28500   +27     
+ Misses       5276     5275    -1     
- Partials      975      978    +3     
Flag Coverage Δ
Agent 82.95% <86.20%> (+<0.01%) ⬆️
Profiler 72.23% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ic/Agent/Core/DataTransport/Client/HttpResponse.cs 80.00% <100.00%> (+0.58%) ⬆️
...e/DataTransport/Client/WebRequestClientResponse.cs 91.42% <100.00%> (+0.25%) ⬆️
...elic/Agent/Core/DataTransport/HttpCollectorWire.cs 89.06% <100.00%> (+0.72%) ⬆️
...DataTransport/Client/HttpResponseMessageWrapper.cs 45.45% <0.00%> (-4.55%) ⬇️
...ataTransport/Client/HttpResponseHeaderFormatter.cs 86.36% <86.36%> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logging response headers from New Relic endpoint to DEBUG logs.

4 participants