Logging request/response messages when using HttpClient
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The clean way to log HttpClient traffic in .NET is to place logging in a DelegatingHandler. That gives you one central point for requests, responses, timings, and failures instead of scattering logging code through every service method that makes an HTTP call.
Why a Handler Is the Right Place
HttpClient sends requests through a handler pipeline. A logging handler can:
- inspect the outgoing request
- call the inner handler
- inspect the response
- measure elapsed time
- log exceptions
That is much cleaner than adding ad hoc logging in every repository or service class that uses the client.
A Basic Logging Handler
Here is a minimal handler using ILogger:
This already captures the most useful operational data: method, URI, status code, duration, and failure details.
Register It With IHttpClientFactory
The handler is most useful when attached through IHttpClientFactory.
This keeps logging behavior consistent and avoids duplicating setup across manually created HttpClient instances.
Log Bodies Carefully
Request and response bodies can be useful during development, but they also create risk and overhead.
Only do this when it is truly needed. Logging bodies can:
- increase memory use
- slow the request path
- expose sensitive data
- cause trouble with very large payloads
In many production systems, body logging should be disabled or heavily constrained.
Redact Sensitive Data
HTTP logging becomes dangerous quickly if secrets are written to logs. Headers such as Authorization, cookies, tokens, or personal data in JSON payloads should be redacted.
Safe logging is as important as complete logging.
Distinguish Response Errors From Transport Failures
A 500 response is not the same as a timeout or DNS failure. Good logging keeps those cases separate:
- non-success HTTP responses still return an
HttpResponseMessage - transport or connection failures throw exceptions
That distinction matters when debugging service issues and when building alerts from logs.
Add Correlation Data
Outbound HTTP logs become much more useful when they carry correlation information such as:
- request ID
- target service name
- logical operation name
- elapsed time
This is especially helpful when one incoming request triggers several outbound HTTP calls. Without correlation, the logs are much harder to reconstruct into a useful timeline.
Common Pitfalls
The biggest mistake is logging in every API method instead of once in a handler. That duplicates code and usually misses cross-cutting behavior in the pipeline.
Another common issue is logging request and response bodies indiscriminately. That creates performance cost and privacy risk very quickly.
People also forget to redact secrets, especially authorization headers and tokens in payloads.
Finally, do not rely only on exceptions. Non-success status codes often carry the most important diagnostic information even when no exception is thrown.
Summary
- Use a
DelegatingHandlerto centralizeHttpClientrequest and response logging. - Register the handler through
IHttpClientFactoryfor consistent behavior. - Capture method, URI, status code, elapsed time, and failures as a baseline.
- Log bodies only when necessary, and redact sensitive data aggressively.
- Keep transport failures and HTTP response errors distinct in your logs.

