Documentation
¶
Overview ¶
Package client provides an *http.Client with structured logging and tracing built in.
Every exchange is logged through xlog and wrapped in a span, so outgoing calls show up in traces alongside the operation that made them. What may be written to those logs is the caller's decision: see sanitize.Sanitizer.
The zero-configuration client is not redaction-safe. NewClient() with no options logs URLs and headers verbatim, so any service whose requests carry credentials should pass WithSanitizer.
Index ¶
- func NewClient(opts ...Option) *http.Client
- type Option
- func WithBodyLogging() Option
- func WithCallerAfterDo(f func(context.Context, *http.Response)) Option
- func WithCallerBeforeDo(f func(context.Context, *http.Request)) Option
- func WithCustomRedirectFlow(redirectFlow func(*http.Request, []*http.Request) error) Option
- func WithSanitizer(s sanitize.Sanitizer) Option
- func WithTimeout(timeout time.Duration) Option
- func WithTransport(transport *http.Transport) Option
- func WithoutRedirect() Option
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Option ¶
Option configures the client returned by NewClient.
func WithBodyLogging ¶
func WithBodyLogging() Option
WithBodyLogging enables request and response body dumps at debug level, truncated to maxLoggedBodyBytes.
This is a local debugging tool and is deliberately awkward to reach for. Bodies are the one thing a sanitizer struggles to make safe: their shape is arbitrary, so a secret inside one is unrecognizable. Enabling this in code that ships means every payload the service exchanges lands in the log.
Consider forbidding it outside tests with a lint rule, e.g. golangci-lint's forbidigo.
func WithCallerAfterDo ¶
WithCallerAfterDo registers a hook run after a successful round-trip. It is not called when the round-trip fails.
A hook that reads resp.Body must restore it, or the caller will read an empty body.
func WithCallerBeforeDo ¶
WithCallerBeforeDo registers a hook run just before the request goes out. Use it to attach credentials or correlation headers:
WithCallerBeforeDo(func(_ context.Context, r *http.Request) {
r.Header.Set("Authorization", "Bearer "+token)
})
Hooks run before the request is logged, so anything they add is visible to the sanitizer — and therefore actually subject to redaction.
func WithCustomRedirectFlow ¶
WithCustomRedirectFlow installs a custom http.Client.CheckRedirect policy.
func WithSanitizer ¶
WithSanitizer installs the redaction policy used for every logged URL, header set and body. Without it the client uses sanitize.NoopSanitizer and logs everything verbatim, secrets included.
A nil sanitizer is ignored rather than installed: a client that logs raw credentials because a constructor argument was nil is worse than one that keeps whatever policy it already had.
func WithTimeout ¶
WithTimeout overrides the total request timeout. A non-positive value is ignored so a caller can pass an unset config field without accidentally disabling the default ceiling.
func WithTransport ¶
WithTransport replaces the underlying *http.Transport, keeping the logging round-tripper that wraps it. A nil value is ignored.
Note that options which reach into the logging round-tripper — WithCallerBeforeDo, WithCallerAfterDo, WithSanitizer, WithBodyLogging — look up that wrapper on the client. Replacing the whole c.Transport from outside (rather than through this option) removes it, and those options then become silent no-ops.
func WithoutRedirect ¶
func WithoutRedirect() Option
WithoutRedirect stops the client from following redirects, returning the redirect response itself instead.