Documentation
¶
Overview ¶
Package http provides an enhanced HTTP client with built-in support for authentication, retries, tracing, and middleware.
The client supports multiple authentication methods (Basic, Digest, NTLM, OAuth, AWS Sigv4), automatic retries with exponential backoff, request/response tracing, and a flexible middleware system.
Basic Usage:
client := http.NewClient()
resp, err := client.R(context.Background()).GET("https://api.example.com/data")
With Authentication:
client := http.NewClient().
Auth("username", "password").
Digest(true)
With AWS Sigv4 Authentication:
cfg, _ := awsconfig.LoadDefaultConfig(ctx)
client := http.NewClient().AWSAuthSigV4(cfg).AWSService("s3")
With Retries and Timeout:
client := http.NewClient(). Retry(3, time.Second, 2.0). Timeout(30 * time.Second)
With Request Tracing:
client := http.NewClient(). Trace(http.TraceAll) // Log full request/response details
The client can also be used as a standard http.RoundTripper:
httpClient := &http.Client{
Transport: http.NewClient().Auth("user", "pass").RoundTripper(),
}
Index ¶
- Constants
- Variables
- func Defensive(options DefensiveOptions) middlewares.Middleware
- func Error(span trace.Span, err error) bool
- func ToCurl(req *http.Request) string
- func WriteHARFile(collector *har.Collector, path string) error
- type AuthConfig
- type Client
- func (c *Client) AWSAuthSigV4(cfgs ...aws.Config) *Client
- func (c *Client) AWSEndpoint(endpoint string) *Client
- func (c *Client) AWSService(service string) *Client
- func (c *Client) Auth(username, password string) *Client
- func (c *Client) BaseURL(url string) *Client
- func (c *Client) CacheDNS(val bool) *Client
- func (c *Client) ConnectTimeout(timeout time.Duration) (*Client, error)
- func (c *Client) ConnectTo(host string) *Client
- func (c *Client) CurlLog() *Client
- func (c *Client) Digest(val bool) *Client
- func (c *Client) DisableKeepAlive(val bool) *Client
- func (c *Client) HAR(handler func(*har.Entry)) *Client
- func (c *Client) HARCollector(collector *har.Collector) *Client
- func (c *Client) HARWithConfig(config har.HARConfig, handler func(*har.Entry)) *Client
- func (c *Client) Header(key, val string) *Client
- func (c *Client) InsecureSkipVerify(val bool) *Client
- func (c *Client) NTLM(val bool) *Client
- func (c *Client) NTLMV2(val bool) *Client
- func (c *Client) OAuth(config middlewares.OauthConfig) *Client
- func (c *Client) Proxy(url string) *Client
- func (c *Client) R(ctx context.Context) *Request
- func (c *Client) RedirectPolicy(maxRedirects int) *Client
- func (c *Client) Retry(maxRetries uint, baseDuration time.Duration, exponent float64) *Client
- func (c *Client) RetryStrategy(fn RetryStrategy) *Client
- func (c *Client) RoundTrip(r *http.Request) (*http.Response, error)
- func (c *Client) RoundTripper() http.RoundTripper
- func (c *Client) TLSConfig(conf TLSConfig) (*Client, error)
- func (c *Client) Timeout(d time.Duration) *Client
- func (c *Client) Trace(config TraceConfig) *Client
- func (c *Client) TraceToStdout(config TraceConfig, verbose ...logger.Verbose) *Client
- func (c *Client) Use(middleware ...middlewares.Middleware) *Client
- func (c *Client) UserAgent(agent string) *Client
- func (c *Client) WithContext(ctx CommonsHTTPContext, feature string) *Client
- func (c *Client) WithHttpLogging(headerLevel, bodyLevel logger.LogLevel) *Client
- func (c *Client) WithLogger(l logger.Logger) *Client
- type CommonsHTTPContext
- type DefensiveOptions
- type HARLevel
- type OauthConfig
- type Request
- func (r *Request) Body(v any) error
- func (r *Request) Debug() string
- func (r *Request) Delete(url string) (*Response, error)
- func (r *Request) Do(method, reqURL string) (resp *Response, err error)
- func (r *Request) Get(url string) (*Response, error)
- func (r *Request) GetHeader(key string) string
- func (r *Request) GetHeaders() map[string]string
- func (r *Request) Header(key, value string) *Request
- func (r *Request) HeaderMap() map[string]string
- func (r *Request) Patch(url string, body any) (*Response, error)
- func (r *Request) Post(url string, body any) (*Response, error)
- func (r *Request) Put(url string, body any) (*Response, error)
- func (r *Request) QueryParam(key, value string) *Request
- func (r *Request) QueryParamAdd(key, value string) *Request
- func (r *Request) Retry(maxRetries uint, baseDuration time.Duration, exponent float64) *Request
- func (r *Request) RetryStrategy(fn RetryStrategy) *Request
- type Response
- func (h *Response) AsJSON() (map[string]any, error)
- func (h *Response) AsMap() (map[string]any, error)
- func (r *Response) AsString() (string, error)
- func (h *Response) Debug() string
- func (r *Response) GetHeaders() map[string]string
- func (h *Response) GetSSLAge() *time.Duration
- func (h *Response) HeaderMap() map[string]string
- func (r *Response) Into(dest any) error
- func (h *Response) IsJSON() bool
- func (r *Response) IsOK(responseCodes ...int) bool
- type RetryConfig
- type RetryStrategy
- type TLSConfig
- type TraceConfig
- type TraceLevelOption
Constants ¶
const MaxBufferSizeProperty = "http.request.maxBufferSize"
MaxBufferSizeProperty caps how many bytes of an io.Reader request body are buffered for retry replay. Bodies larger than this stream through once and cannot be retried. Set -P http.request.maxBufferSize=0 to disable the cap.
Variables ¶
var AuthStyleAutoDetect = middlewares.AuthStyleAutoDetect
var AuthStyleInHeader = middlewares.AuthStyleInHeader
var AuthStyleInParams = middlewares.AuthStyleInParams
var TraceAll = TraceConfig{ MaxBodyLength: 4096, Body: true, Response: true, QueryParam: true, FormParams: true, Headers: true, ResponseHeaders: true, TLS: true, Auth: true, }
var TraceHeaders = TraceConfig{ Body: false, Response: false, QueryParam: true, FormParams: true, Headers: true, ResponseHeaders: true, TLS: false, Auth: true, }
Functions ¶
func Defensive ¶ added in v1.59.0
func Defensive(options DefensiveOptions) middlewares.Middleware
Defensive returns transport middleware that restricts requests to the destination classes explicitly enabled by options. It must wrap an *http.Transport before middleware that hides the concrete transport.
func ToCurl ¶ added in v1.46.0
ToCurl converts an http.Request into an equivalent curl command string. Sensitive headers are redacted before the command is logged or displayed.
func WriteHARFile ¶ added in v1.52.0
WriteHARFile serializes collector.Entries() into a HAR 1.2 file at path. Designed for use from a context.AfterFunc hook owned by the caller — commons/http does not register any lifecycle itself, though har.Registry does it for property-driven capture.
Types ¶
type AuthConfig ¶ added in v1.13.0
type AuthConfig struct {
// Username for basic Auth
Username string
// Password for basic Auth
Password string
// Use digest access authentication
Digest bool
// Ntlm controls whether to use NTLM
Ntlm bool
// Ntlmv2 controls whether to use NTLMv2
Ntlmv2 bool
// AWS Sigv4 authentication
AWSCredentialsProvider aws.CredentialsProvider
AWSRegion string
AWSService string
AWSEndpoint string
}
func (*AuthConfig) IsEmpty ¶ added in v1.16.0
func (a *AuthConfig) IsEmpty() bool
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an enhanced HTTP client with built-in support for authentication, retries, tracing, and middleware. It provides a fluent API for configuring requests and can be used as a drop-in replacement for http.Client.
Example:
client := http.NewClient().
Auth("user", "pass").
Retry(3, time.Second, 2.0).
Trace(http.TraceHeaders).
Timeout(30 * time.Second)
resp, err := client.R(ctx).
GET("https://api.example.com/data")
func NewClient ¶
func NewClient() *Client
NewClient creates a new HTTP client with default settings. The client has a default timeout of 2 minutes and can be customized using the fluent API methods.
Example:
client := http.NewClient().
BaseURL("https://api.example.com").
Header("X-API-Key", "secret").
InsecureSkipVerify(true)
func NewDefensive ¶ added in v1.59.0
func NewDefensive() *Client
NewDefensive creates a client that can reach public HTTP(S) destinations only.
func (*Client) AWSAuthSigV4 ¶ added in v1.45.0
AWSAuthSigV4 configures AWS Signature Version 4 authentication. With no arguments, it loads the default AWS config (env vars, ~/.aws, IAM role, etc.). Pass an aws.Config to use specific credentials/region.
Example with defaults:
client.AWSAuthSigV4()
Example with explicit config:
cfg, _ := awsconfig.LoadDefaultConfig(ctx, awsconfig.WithRegion("us-east-1"))
client.AWSAuthSigV4(cfg)
func (*Client) AWSEndpoint ¶ added in v1.45.0
AWSEndpoint sets a custom AWS endpoint (e.g., for LocalStack testing).
func (*Client) AWSService ¶ added in v1.45.0
AWSService sets the AWS service name for SigV4 signing. If not set, the service is inferred from the request URL hostname.
func (*Client) Auth ¶ added in v1.13.0
Auth configures authentication credentials for the client. By default, this sets up HTTP Basic Authentication. Use Digest(), NTLM(), or NTLMV2() to switch authentication methods.
Example:
// Basic auth
client.Auth("username", "password")
// Digest auth
client.Auth("username", "password").Digest(true)
// NTLM auth with domain
client.Auth("DOMAIN\\username", "password").NTLM(true)
func (*Client) ConnectTimeout ¶ added in v1.56.0
ConnectTimeout limits the time spent establishing a network connection.
func (*Client) ConnectTo ¶ added in v1.13.0
ConnectTo overrides the target host:port for requests. This is useful for testing against specific IPs or when dealing with DNS issues. The original hostname is preserved in the Host header.
Example:
// Connect to a specific IP instead of using DNS
client.ConnectTo("192.168.1.100:8080")
// Test against localhost while preserving the original Host header
client.ConnectTo("localhost:3000")
func (*Client) DisableKeepAlive ¶ added in v1.13.0
DisableKeepAlives prevents reuse of TCP connections
func (*Client) HAR ¶ added in v1.47.0
HAR enables HAR capture with default config. handler is called with each request/response entry after the round-trip. HAR(nil) is a no-op.
func (*Client) HARCollector ¶ added in v1.47.0
HARCollector enables HAR capture using a Collector that accumulates all entries (including OAuth token fetches, redirect hops, and retry attempts).
func (*Client) HARWithConfig ¶ added in v1.47.0
HARWithConfig enables HAR capture with a custom HARConfig.
func (*Client) InsecureSkipVerify ¶ added in v1.13.0
InsecureSkipVerify disables TLS certificate verification. WARNING: This makes the client vulnerable to man-in-the-middle attacks. Only use in development or when connecting to services with self-signed certificates.
Example:
// Accept any certificate (dangerous!) client.InsecureSkipVerify(true)
func (*Client) OAuth ¶ added in v1.15.0
func (c *Client) OAuth(config middlewares.OauthConfig) *Client
OAuth configures OAuth 2.0 authentication for the client. Supports various OAuth flows including client credentials and authorization code.
Example:
client.OAuth(middlewares.OauthConfig{
ClientID: "client-id",
ClientSecret: "client-secret",
TokenURL: "https://auth.example.com/token",
Scopes: []string{"read", "write"},
})
func (*Client) R ¶ added in v1.13.0
R creates a new request with the given context. The request inherits all settings from the client (headers, auth, etc.) and can be further customized before execution.
Example:
resp, err := client.R(ctx).
Header("X-Request-ID", "123").
QueryParam("page", "1").
GET("/users")
func (*Client) RedirectPolicy ¶ added in v1.47.0
RedirectPolicy controls redirect following. maxRedirects=0 disables redirect following entirely. Values >0 limit the number of redirects.
func (*Client) Retry ¶ added in v1.13.0
Retry configures automatic retry behavior with exponential backoff. Failed requests will be retried up to maxRetries times, with delays calculated as baseDuration * (exponent ^ attemptNumber).
Only transport errors are retried, and only for idempotent methods: POST and PATCH are never replayed, since the server may have acted on the failed attempt. Retrying stops as soon as the request context is done, including during the backoff wait. Use RetryStrategy to retry POST/PATCH explicitly.
Parameters:
- maxRetries: Maximum number of retry attempts (0 disables retries)
- baseDuration: Initial delay between retries
- exponent: Multiplier for exponential backoff (typically 2.0)
Example:
// Retry up to 3 times with delays of 1s, 2s, 4s client.Retry(3, time.Second, 2.0)
func (*Client) RetryStrategy ¶ added in v1.52.0
func (c *Client) RetryStrategy(fn RetryStrategy) *Client
RetryStrategy installs a callback that decides whether each HTTP attempt should be retried. When set, it fully supersedes the legacy Retry() exponential-backoff loop and owns the retry policy (including the attempt cap). See the RetryStrategy type and the RetryOnStatus helper.
Example — retry on 429 and 5xx, honoring Retry-After:
client := http.NewClient().RetryStrategy(
http.RetryOnStatus(5, time.Second,
429, 502, 503, 504),
)
func (*Client) RoundTripper ¶ added in v1.40.2
func (c *Client) RoundTripper() http.RoundTripper
func (*Client) TLSConfig ¶ added in v1.22.2
TLSConfig configures advanced TLS settings including custom CAs, client certificates, and handshake timeout.
Example:
client.TLSConfig(TLSConfig{
CA: caPEM, // Custom CA certificate
Cert: clientCert, // Client certificate for mTLS
Key: clientKey, // Client private key
InsecureSkipVerify: false, // Verify server certificate
HandshakeTimeout: 10 * time.Second,
})
func (*Client) Timeout ¶ added in v1.13.0
Timeout specifies a time limit for requests made by this Client.
Default: 2 minutes
func (*Client) Trace ¶ added in v1.15.0
func (c *Client) Trace(config TraceConfig) *Client
Trace enables request/response tracing with customizable detail levels. Traced information is added to the context and can be retrieved by middleware.
Use predefined configs for common scenarios:
- TraceAll: Full details including headers, body, and TLS
- TraceHeaders: Headers and query params only (no body)
Example:
client.Trace(http.TraceConfig{
Headers: true,
ResponseHeaders: true,
Body: true,
Response: true,
MaxBodyLength: 1024, // Limit body size in traces
})
func (*Client) TraceToStdout ¶ added in v1.16.0
func (c *Client) TraceToStdout(config TraceConfig, verbose ...logger.Verbose) *Client
TraceToStdout installs the stdout trace middleware. Calling it a second time on the same Client merges the new config into the existing one instead of stacking a second middleware — this lets WithLogger (the -v ladder) and WithContext (-P http.log=) both contribute without doubling every traced request.
func (*Client) Use ¶ added in v1.13.0
func (c *Client) Use(middleware ...middlewares.Middleware) *Client
Use adds middleware to the client's transport chain. Middleware functions wrap the underlying RoundTripper and can modify requests/responses, add logging, implement caching, etc.
Middleware is applied in the order it was added.
Example:
client.Use(func(rt http.RoundTripper) http.RoundTripper {
return middlewares.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
req.Header.Set("X-Custom", "value")
return rt.RoundTrip(req)
})
})
func (*Client) WithContext ¶ added in v1.52.0
func (c *Client) WithContext(ctx CommonsHTTPContext, feature string) *Client
WithContext configures the client from a context-object's data accessors. The feature name lets implementations distinguish callers (e.g. "takealot" vs "xero") for per-feature property overrides.
Order of operations:
- WithLogger(ctx.GetLogger()) — installs the -v ladder trace.
- ctx.HTTPTraceConfig(feature) — if set, merges into the trace via TraceToStdout's dedupe path. Authorization is added to RedactedHeaders.
- ctx.HARFor(feature) — if a collector is returned, attaches it either as a full-body capture (HARFull) or as a metadata-only middleware (HARMetadata).
WithContext does NOT register any lifecycle hook — the context owns flushing (e.g. via context.AfterFunc on cancellation).
func (*Client) WithHttpLogging ¶ added in v1.40.2
WithHttpLogging enables HTTP request/response logging based on the provided log levels.
Parameters:
- headerLevel: The minimum log level required to log HTTP headers (e.g., logger.Debug)
- bodyLevel: The minimum log level required to log request/response bodies (e.g., logger.Trace)
Example:
client.WithHttpLogging(logger.Debug, logger.Trace)
This will log headers when debug logging is enabled (-v or -v 1) and bodies when trace logging is enabled (-vv or -v 2 or higher).
Note: When using with cobra commands, ensure UseCobraFlags is called in PersistentPreRun to properly parse -v N syntax.
func (*Client) WithLogger ¶ added in v1.52.0
WithLogger stores l as the client's logger AND, as a side effect, installs a stdout trace middleware whose config is derived from l.GetLevel() via TraceConfigForLogLevel. This makes -v / -vv "just work" by passing the application's standard logger:
NewClient().WithLogger(logger.StandardLogger())
The trace middleware is shared with WithContext (-P http.log=) via TraceToStdout's dedupe — calling both is safe and merges configs.
type CommonsHTTPContext ¶ added in v1.52.0
type CommonsHTTPContext interface {
GetLogger() logger.Logger
HTTPTraceConfig(feature string) (TraceConfig, bool)
HARFor(feature string) (collector *har.Collector, path string, level HARLevel)
}
CommonsHTTPContext is the narrow interface a context object implements to drive HTTP-client configuration. xerocli.Context (and could be duty/context.Context) satisfies it; commons/http does not require any other concrete dependency from the application.
HARFor returns the collector, the resolved file path, and the level. A nil collector signals "no HAR for this feature" (the client wires no HAR middleware in that case). Implementations are expected to handle per-path collector deduplication themselves so multiple clients sharing the same output file share one collector.
type DefensiveOptions ¶ added in v1.59.0
type DefensiveOptions struct {
Public bool
Private bool
Localhost bool
// Proxy enables proxy use and trusts the selected proxy to resolve and
// enforce hostname destinations. Direct connections and literal destination
// addresses remain subject to the configured address policy.
Proxy bool
Redirect bool
}
DefensiveOptions controls which network destinations a defensive client may reach.
type HARLevel ¶ added in v1.52.0
HARLevel selects what a HAR collector captures when attached via WithContext. Borrowed from duty/connection/common.go's Debug/Trace split — at Metadata, only request/response headers + timing are captured (no bodies, no body re-read cost). At Full, the standard collector middleware captures bodies too. The levels live in commons/har so the middleware, the property registry and this client all speak one enum; these names are kept for callers.
type OauthConfig ¶ added in v1.17.0
type OauthConfig = middlewares.OauthConfig
type Request ¶
type Request struct {
// contains filtered or unexported fields
}
Request represents an HTTP request that can be customized and executed. It provides a fluent API for setting headers, query parameters, body, and other options. Request instances should be created using Client.R(ctx).
func (*Request) Body ¶ added in v1.13.0
Body sets the request body. Accepts multiple types:
- io.Reader: Used directly as the body
- []byte: Wrapped in a bytes.Reader
- string: Converted to []byte and wrapped
- Any other type: JSON marshaled
Example:
// JSON body
req.Body(map[string]string{"key": "value"})
// String body
req.Body("raw text data")
// Reader body
req.Body(bytes.NewReader(data))
func (*Request) Do ¶ added in v1.13.0
Do performs an HTTP request with the specified method and URL.
func (*Request) Get ¶ added in v1.13.0
Get performs an HTTP GET request to the specified URL.
Example:
resp, err := client.R(ctx).Get("https://api.example.com/users")
if err != nil {
return err
}
defer resp.Body.Close()
func (*Request) GetHeaders ¶ added in v1.16.0
func (*Request) Header ¶ added in v1.13.0
Header sets a header for the request. Multiple calls with the same key will overwrite previous values.
Example:
resp, err := client.R(ctx).
Header("Authorization", "Bearer token").
Header("Content-Type", "application/json").
GET("/api/data")
func (*Request) Post ¶ added in v1.13.0
Post performs an HTTP POST request with the given body. The body can be a string, []byte, io.Reader, or any type that can be JSON marshaled.
Example:
user := map[string]string{"name": "John", "email": "john@example.com"}
resp, err := client.R(ctx).
Header("Content-Type", "application/json").
Post("https://api.example.com/users", user)
func (*Request) QueryParam ¶ added in v1.13.0
QueryParam sets a query parameter for the request. Multiple calls with the same key will overwrite previous values.
Example:
resp, err := client.R(ctx).
QueryParam("page", "1").
QueryParam("limit", "10").
GET("/api/users")
func (*Request) QueryParamAdd ¶ added in v1.31.24
QueryParamAdd adds a value to a query parameter. Unlike QueryParam, this allows multiple values for the same key.
Example:
// Results in: /api/search?tag=go&tag=http
resp, err := client.R(ctx).
QueryParamAdd("tag", "go").
QueryParamAdd("tag", "http").
GET("/api/search")
func (*Request) Retry ¶ added in v1.13.0
Retry configures retry behavior for this specific request, overriding the client's default retry configuration.
Only transport errors are retried, and only for idempotent methods: POST and PATCH are never replayed, since the server may have acted on the failed attempt. Retrying stops as soon as the request context is done, including during the backoff wait. Use RetryStrategy to retry POST/PATCH explicitly.
Parameters:
- maxRetries: Maximum number of retry attempts
- baseDuration: Initial delay between retries
- exponent: Multiplier for exponential backoff
Example:
// Retry this request up to 5 times
resp, err := client.R(ctx).
Retry(5, 500*time.Millisecond, 2.0).
GET("/flaky-endpoint")
func (*Request) RetryStrategy ¶ added in v1.52.0
func (r *Request) RetryStrategy(fn RetryStrategy) *Request
RetryStrategy installs a per-request retry callback, overriding any strategy configured on the client. See Client.RetryStrategy for the full contract; pass nil to clear an inherited strategy and fall back to the legacy Retry()/RetryConfig path for this request.
type Response ¶
type Response struct {
// The underlying http.Response is embed into Response.
*http.Response
// Request is the Response's related Request.
Request *Request
RawRequest *http.Request
}
Response extends the stdlib http.Response type and extends its functionality
func (*Response) GetHeaders ¶ added in v1.16.0
type RetryConfig ¶ added in v1.13.0
type RetryStrategy ¶ added in v1.52.0
RetryStrategy decides whether a completed HTTP attempt should be retried. It is called after every attempt with the response (may be nil on a transport error), the transport-level error (may be nil on a non-2xx HTTP response), and the zero-based attempt index.
Return (true, delay) to retry after sleeping delay. A non-positive delay retries immediately. Return (false, _) to stop and surface the underlying attempt result.
When set on a Client or Request via RetryStrategy(...), this callback fully supersedes the legacy RetryConfig-driven exponential-backoff loop: the strategy is responsible for its own attempt cap.
func RetryOnStatus ¶ added in v1.52.0
func RetryOnStatus(maxAttempts int, baseDelay time.Duration, statuses ...int) RetryStrategy
RetryOnStatus returns a RetryStrategy that retries on any of the given HTTP status codes (plus transport errors) up to maxAttempts total attempts, using exponential backoff starting at baseDelay (factor 2).
On a 429 response, a Retry-After header is honored over the computed delay. Both delta-seconds and HTTP-date forms are supported.
type TLSConfig ¶ added in v1.22.2
type TLSConfig struct {
// InsecureSkipVerify controls whether a client verifies the server's
// certificate chain and host name
InsecureSkipVerify bool
// HandshakeTimeout defaults to 10 seconds
HandshakeTimeout time.Duration
// PEM encoded certificate of the CA to verify the server certificate
CA string
// PEM encoded client certificate
Cert string
// PEM encoded client private key
Key string
}
type TraceConfig ¶ added in v1.15.0
type TraceConfig = middlewares.TraceConfig
func TraceConfigForLogLevel ¶ added in v1.53.0
func TraceConfigForLogLevel(level logger.LogLevel, options ...TraceLevelOption) (TraceConfig, bool)
TraceConfigForLogLevel maps a logger level to a TraceConfig for the stdout trace middleware. The ladder is relative to a configurable base level:
base + 0: access line only base + 1: query/form params + request/response headers base + 2: request bodies + concise TLS base + 3: response bodies
The default base is Debug and can be overridden with http.log.base-level, HTTP_LOG_BASE_LEVEL, or WithTraceBaseLevel.
type TraceLevelOption ¶ added in v1.53.0
type TraceLevelOption func(*traceLevelOptions)
TraceLevelOption configures how TraceConfigForLogLevel maps a commons logger level onto the HTTP trace ladder.
func WithTraceBaseLevel ¶ added in v1.53.0
func WithTraceBaseLevel(level logger.LogLevel) TraceLevelOption
WithTraceBaseLevel shifts the whole HTTP trace ladder to start at level. With the default base of Debug, -v logs a single access line; with an Info base, a normal info-level logger logs that access line and -v logs headers.