### Configure and Use httpretty Logger for HTTP Client Source: https://context7.com/henvic/httpretty/llms.txt Instantiate and configure the httpretty.Logger struct with desired fields for logging. Then, wrap the default HTTP client's transport with logger.RoundTripper to enable logging for all outgoing requests. This example demonstrates enabling time, TLS, headers, bodies, colors, alignment, and JSON formatting. ```go package main import ( "github.com/henvic/httpretty" "net/http" "os" "fmt" ) func main() { logger := &httpretty.Logger{ Time: true, // print request start time and duration TLS: true, // print TLS handshake / certificate details RequestHeader: true, // print outgoing request headers RequestBody: true, // print outgoing request body ResponseHeader: true, // print incoming response headers ResponseBody: true, // print incoming response body SkipSanitize: false, // sanitize Authorization headers (default) Colors: true, // ANSI terminal colors Align: true, // align header values into columns MaxRequestBody: 4096, // max bytes of request body to print MaxResponseBody: 4096, // max bytes of response body to print Formatters: []httpretty.Formatter{ &httpretty.JSONFormatter{}, // pretty-print application/json bodies }, } // Wire into the default HTTP client transport. http.DefaultClient.Transport = logger.RoundTripper(http.DefaultTransport) if _, err := http.Get("https://httpbin.org/get"); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Output (example): // * Request to https://httpbin.org/get // * Request at 2024-01-15 10:00:00.000000000 +0000 UTC // > GET /get HTTP/1.1 // > Host: httpbin.org // > User-Agent: Go-http-client/2.0 // > // * TLS connection using TLS 1.3 / TLS_AES_128_GCM_SHA256 // * Server certificate: // * subject: CN=httpbin.org // * ... // < HTTP/2.0 200 OK // < Content-Type: application/json // < // { // "url": "https://httpbin.org/get" // } // * Request took 312.456ms } ``` -------------------------------- ### SetOutput: Redirect Log Output to a Buffer Source: https://context7.com/henvic/httpretty/llms.txt Redirect httpretty's log output from os.Stdout to any io.Writer. This example demonstrates redirecting output to a bytes.Buffer, allowing captured logs to be inspected or processed programmatically. ```go package main import ( "bytes" "fmt" "net/http" "github.com/henvic/httpretty" ) func main() { var buf bytes.Buffer logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, } logger.SetOutput(&buf) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } client.Get("https://httpbin.org/get") // buf now contains the full log output as a string. fmt.Println("Captured log output:") fmt.Println(buf.String()) } ``` -------------------------------- ### Implement Custom XMLFormatter for Formatter Interface Source: https://context7.com/henvic/httpretty/llms.txt Implement the Formatter interface to create custom pretty-printers for specific content types like XML. The Match method determines if the formatter applies, and the Format method handles the pretty-printing logic. This example shows how to pretty-print XML using encoding/xml. ```go package main import ( "bytes" "encoding/xml" "io" "net/http" "github.com/henvic/httpretty" ) // XMLFormatter pretty-prints XML response bodies. type XMLFormatter struct{} func (f *XMLFormatter) Match(mediatype string) bool { return mediatype == "application/xml" || mediatype == "text/xml" } func (f *XMLFormatter) Format(w io.Writer, src []byte) error { var buf bytes.Buffer decoder := xml.NewDecoder(bytes.NewReader(src)) encoder := xml.NewEncoder(&buf) encoder.Indent("", " ") for { tok, err := decoder.Token() if err == io.EOF { break } if err != nil { return err } if err := encoder.EncodeToken(tok); err != nil { return err } } encoder.Flush() _, err := w.Write(buf.Bytes()) return err } func main() { logger := &httpretty.Logger{ ResponseHeader: true, ResponseBody: true, Colors: true, Formatters: []httpretty.Formatter{ &httpretty.JSONFormatter{}, // handles JSON &XMLFormatter{}, // handles XML }, } client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } client.Get("https://www.w3schools.com/xml/note.xml") // XML body is indented and printed, JSON bodies handled by JSONFormatter. } ``` -------------------------------- ### SetBodyFilter: Suppress Logging for Non-JSON Content Types Source: https://context7.com/henvic/httpretty/llms.txt Register a BodyFilter function to conditionally suppress logging of request or response bodies based on headers. This example skips logging for any content type that does not contain 'json'. ```go package main import ( "net/http" "strings" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, RequestBody: true, ResponseHeader: true, ResponseBody: true, Colors: true, } // Suppress body logging for non-JSON content types. logger.SetBodyFilter(func(h http.Header) (skip bool, err error) { contentType := h.Get("Content-Type") if contentType == "" { return false, nil } // Only print JSON bodies; skip everything else (HTML, images, etc.). if !strings.Contains(contentType, "json") { return true, nil } return false, nil }) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } client.Get("https://httpbin.org/json") // body printed (application/json) client.Get("https://httpbin.org/html") // body suppressed (text/html) } ``` -------------------------------- ### Configure httpretty Logger Source: https://github.com/henvic/httpretty/blob/main/README.md Set up a logger with various options for printing HTTP request details. Enable or disable specific fields like time, TLS, headers, and body. Colors can be enabled or disabled. Formatters can be provided, such as JSONFormatter. ```go logger := &httpretty.Logger{ Time: true, TLS: true, RequestHeader: true, RequestBody: true, ResponseHeader: true, ResponseBody: true, Colors: true, // erase line if you don't like colors Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}}, } ``` -------------------------------- ### Integrate httpretty Logger with a Dedicated HTTP Client Source: https://context7.com/henvic/httpretty/llms.txt Create a dedicated http.Client and set its Transport to the logger's RoundTripper. This approach is recommended over modifying http.DefaultClient. Configure basic logging for request/response headers and bodies, with JSON formatting and colors enabled. ```go package main import ( "fmt" "net/http" "os" "time" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, ResponseBody: true, Colors: true, Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}}, } // Use a dedicated *http.Client (recommended over mutating http.DefaultClient). client := &http.Client{ Timeout: 10 * time.Second, Transport: logger.RoundTripper(http.DefaultTransport), } resp, err := client.Get("https://httpbin.org/json") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer resp.Body.Close() fmt.Println("Status:", resp.Status) // The full request + response (including formatted JSON body) is already // printed to stdout by the logger before this line executes. } ``` -------------------------------- ### Manually Print Request and Response with httpretty Logger Source: https://context7.com/henvic/httpretty/llms.txt Use PrintRequest and PrintResponse to log requests and responses directly. PrintRequest respects active Filters but omits TLS details and timing. Ensure the Logger is configured with desired output options. ```go package main import ( "fmt" "net/http" "strings" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, RequestBody: true, ResponseHeader: true, ResponseBody: true, Colors: true, Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}}, } // Manually construct and print a request. body := strings.NewReader(`{"name":"Alice"}`) req, _ := http.NewRequest(http.MethodPost, "https://api.example.com/users", body) req.Header.Set("Content-Type", "application/json") logger.PrintRequest(req) // Manually construct and print a response. resp := &http.Response{ Proto: "HTTP/1.1", Status: "201 Created", StatusCode: 201, Header: http.Header{"Content-Type": []string{"application/json"}}, Body: http.NoBody, Request: req, } logger.PrintResponse(resp) fmt.Println("Done") // Output: // > POST /users HTTP/1.1 // > Content-Type: application/json // > Host: api.example.com // > // {"name":"Alice"} // < HTTP/1.1 201 Created // < Content-Type: application/json // < } ``` -------------------------------- ### Use httpretty on Server-Side Source: https://github.com/henvic/httpretty/blob/main/README.md Apply httpretty as middleware to an http.Handler, typically your main HTTP entrypoint like http.ServeMux, to log incoming requests. ```go logger.Middleware(mux) ``` -------------------------------- ### Use httpretty on Client-Side Source: https://github.com/henvic/httpretty/blob/main/README.md Integrate httpretty with a Go http.Client by setting its Transport. This allows httpretty to log all outgoing requests made by this client. Consider using a custom client to manage timeouts. ```go client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } ``` ```go http.DefaultClient.Transport = logger.RoundTripper(http.DefaultClient.Transport) ``` ```go if _, err := http.Get("https://www.google.com/"); err != nil { fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(1) } ``` -------------------------------- ### Log All Server-Side HTTP Requests with Middleware Source: https://context7.com/henvic/httpretty/llms.txt Wrap your http.Handler with httpretty.Logger.Middleware to log all incoming requests and outgoing responses, including headers and bodies. Ensure the logger is configured with desired fields like Time, TLS, RequestHeader, RequestBody, ResponseHeader, ResponseBody, and Colors. ```go package main import ( "fmt" "net/http" "os" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ Time: true, TLS: true, RequestHeader: true, RequestBody: true, ResponseHeader: true, ResponseBody: true, Colors: true, } mux := http.NewServeMux() mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintln(w, "Hello, world!") }) fmt.Println("Listening on :8080") // Wrap the entire mux with the logging middleware. if err := http.ListenAndServe(":8080", logger.Middleware(mux)); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Terminal output for each request: // * Request to http://localhost:8080/hello // * Request from 127.0.0.1:54321 // > GET /hello HTTP/1.1 // > Host: localhost:8080 // > // < HTTP/1.1 200 OK // < Content-Type: text/plain; charset=utf-8 // < // Hello, world! } ``` -------------------------------- ### SetFlusher: Configure Buffering Strategy for Concurrent Requests Source: https://context7.com/henvic/httpretty/llms.txt Control how httpretty writes output during concurrent requests using SetFlusher. The 'OnEnd' strategy buffers all output for a single request and flushes it atomically, ensuring cleaner logs when multiple goroutines make requests simultaneously. ```go package main import ( "net/http" "sync" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } // NoBuffer — write immediately; concurrent requests may interleave (default). // OnReady — buffer each section (headers, body) and flush when ready; less interleaving. // OnEnd — buffer everything, flush once per request; cleanest output for concurrent traffic. logger.SetFlusher(httpretty.OnEnd) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } var wg sync.WaitGroup urls := []string{ "https://httpbin.org/get", "https://httpbin.org/ip", "https://httpbin.org/uuid", } for _, u := range urls { wg.Add(1) go func(url string) { defer wg.Done() client.Get(url) // each request printed atomically thanks to OnEnd }(u) } wg.Wait() } ``` -------------------------------- ### Suppress Logging for Specific Requests via Context Source: https://context7.com/henvic/httpretty/llms.txt Use httpretty.WithHide(context.Background()) to create a context that suppresses logging for requests made with it. This is useful for internal or health-check traffic that should not clutter logs. The request will still be processed, but no httpretty output will be generated. ```go package main import ( "context" "fmt" "net/http" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } // This request WILL be logged. req1, _ := http.NewRequest(http.MethodGet, "https://httpbin.org/get", nil) client.Do(req1) // This request will NOT be logged — hidden via context. ctx := httpretty.WithHide(context.Background()) req2, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://httpbin.org/get", nil) resp, err := client.Do(req2) if err != nil { fmt.Println("error:", err) return } defer resp.Body.Close() fmt.Println("hidden request status:", resp.Status) // printed, but no httpretty output } ``` -------------------------------- ### Logger.SetOutput Source: https://context7.com/henvic/httpretty/llms.txt Redirects the logger's output from the default os.Stdout to any io.Writer. This is useful for writing logs to files, in-memory buffers, or structured logging systems. ```APIDOC ## `Logger.SetOutput` — Redirect Log Output By default, httpretty writes to `os.Stdout`. `SetOutput` redirects output to any `io.Writer` — useful for writing to a log file, an in-memory buffer during tests, or a structured logging pipeline. ### Example Usage: ```go var buf bytes.Buffer logger.SetOutput(&buf) // buf now contains the full log output as a string. fmt.Println(buf.String()) ``` ``` -------------------------------- ### Logger.Middleware Source: https://context7.com/henvic/httpretty/llms.txt Wraps an http.Handler to log incoming server requests and outgoing responses, including request and response bodies. ```APIDOC ## Logger.Middleware — Server-Side HTTP Middleware `Middleware` wraps any `http.Handler` to log every incoming server request and the corresponding outgoing response. It records the response body written by your handlers without interfering with normal response delivery. ### Usage ```go logger := &httpretty.Logger{ Time: true, TLS: true, RequestHeader: true, RequestBody: true, ResponseHeader: true, ResponseBody: true, Colors: true, } mux := http.NewServeMux() // ... register handlers ... // Wrap the entire mux with the logging middleware. http.ListenAndServe(":8080", logger.Middleware(mux)) ``` ### Example Terminal Output ``` * Request to http://localhost:8080/hello * Request from 127.0.0.1:54321 > GET /hello HTTP/1.1 > Host: localhost:8080 > < HTTP/1.1 200 OK < Content-Type: text/plain; charset=utf-8 < Hello, world! ``` ``` -------------------------------- ### Dynamically Filter HTTP Requests for Logging Source: https://context7.com/henvic/httpretty/llms.txt Implement custom logging logic using logger.SetFilter. This function allows you to skip logging specific requests based on criteria like HTTP method or URL path. Pass nil to logger.SetFilter to remove any active filter and resume full logging. ```go package main import ( "net/http" "strings" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } // Skip logging for non-GET requests and /health endpoints. logger.SetFilter(func(req *http.Request) (skip bool, err error) { if req.Method != http.MethodGet { return true, nil } if strings.HasPrefix(req.URL.Path, "/health") { return true, nil } return false, nil }) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } // Will be logged (GET, non-health path). client.Get("https://httpbin.org/get") // Will NOT be logged (health endpoint). client.Get("https://httpbin.org/health") // Clear the filter to resume full logging. logger.SetFilter(nil) } ``` -------------------------------- ### Logger.SetFlusher Source: https://context7.com/henvic/httpretty/llms.txt Controls the buffering strategy for log output, especially when multiple goroutines make concurrent requests. Options include immediate flushing (NoBuffer), flushing when sections are ready (OnReady), or flushing per request (OnEnd) for cleaner output. ```APIDOC ## `Logger.SetFlusher` — Buffering Strategy `SetFlusher` controls how the logger writes output when multiple goroutines make concurrent requests. The three strategies trade off between immediacy and output coherence. ### Strategies: - `httpretty.NoBuffer`: Write immediately; concurrent requests may interleave (default). - `httpretty.OnReady`: Buffer each section (headers, body) and flush when ready; less interleaving. - `httpretty.OnEnd`: Buffer everything, flush once per request; cleanest output for concurrent traffic. ### Example Usage: ```go logger.SetFlusher(httpretty.OnEnd) ``` ``` -------------------------------- ### Filter Requests with httpretty.WithHide Source: https://github.com/henvic/httpretty/blob/main/README.md Exclude specific requests from being logged by adding a context value using httpretty.WithHide before the request is processed by the logger's RoundTripper. ```go req = req.WithContext(httpretty.WithHide(ctx)) ``` -------------------------------- ### WithHide Source: https://context7.com/henvic/httpretty/llms.txt Attaches a hide marker to a context.Context to suppress logging for specific requests, useful for health checks or internal traffic. ```APIDOC ## WithHide — Per-Request Suppression via Context `WithHide` attaches a hide marker to a `context.Context`. Any request whose context carries this marker is silently passed through the transport or middleware without being logged — even when a logger is active. Useful for suppressing health-check or internal traffic. ### Usage ```go logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } // This request WILL be logged. req1, _ := http.NewRequest(http.MethodGet, "https://httpbin.org/get", nil) client.Do(req1) // This request will NOT be logged — hidden via context. ctx := httpretty.WithHide(context.Background()) req2, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://httpbin.org/get", nil) resp, err := client.Do(req2) // ... handle response ... ``` ### Example Output ``` hidden request status: 200 OK ``` (Note: No httpretty output will be shown for the hidden request.) ``` -------------------------------- ### Filter Requests with a Custom Function Source: https://github.com/henvic/httpretty/blob/main/README.md Define and set a custom filter function on the logger to conditionally skip logging requests based on criteria like HTTP method or URL path. ```go logger.SetFilter(func filteredURIs(req *http.Request) (bool, error) { if req.Method != http.MethodGet { return true, nil } if path := req.URL.Path; path == "/debug" || strings.HasPrefix(path, "/debug/") { return true, nil } return false }) ``` -------------------------------- ### Pretty-Print JSON Response Bodies with JSONFormatter Source: https://context7.com/henvic/httpretty/llms.txt Use JSONFormatter to automatically pretty-print JSON response bodies. It matches media types containing '/json' or '+json'. Ensure the Logger is configured with ResponseBody enabled and JSONFormatter in its Formatters list. ```go package main import ( "net/http" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ ResponseBody: true, Colors: true, Formatters: []httpretty.Formatter{ &httpretty.JSONFormatter{}, // matches application/json, application/vnd.api+json, etc. }, } client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } client.Get("https://httpbin.org/json") // Raw response body: {"slideshow":{"author":"Yours Truly",...}} // Printed as: // { // "slideshow": { // "author": "Yours Truly", // ... // } // } } ``` -------------------------------- ### Logger.SetFilter Source: https://context7.com/henvic/httpretty/llms.txt Registers a Filter function to dynamically skip logging for specific requests based on request properties. ```APIDOC ## Logger.SetFilter — Dynamic Request Filtering `SetFilter` registers a `Filter` function `func(req *http.Request) (skip bool, err error)`. It is called for every request; returning `skip=true` suppresses logging for that request. Pass `nil` to remove the filter. This method is concurrency-safe and can be called at any time during the lifecycle of the logger. ### Usage ```go logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } // Skip logging for non-GET requests and /health endpoints. logger.SetFilter(func(req *http.Request) (skip bool, err error) { if req.Method != http.MethodGet { return true, nil } if strings.HasPrefix(req.URL.Path, "/health") { return true, nil } return false, nil }) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } // Will be logged (GET, non-health path). client.Get("https://httpbin.org/get") // Will NOT be logged (health endpoint). client.Get("https://httpbin.org/health") // Clear the filter to resume full logging. logger.SetFilter(nil) ``` ``` -------------------------------- ### Logger.SkipHeader Source: https://context7.com/henvic/httpretty/llms.txt Excludes specified header names from all log output. Header names are matched case-insensitively. This is applied in addition to default credential masking. ```APIDOC ## `Logger.SkipHeader` — Redact Specific Headers `SkipHeader` takes a slice of header names and excludes them from all log output. Header names are matched case-insensitively using canonical MIME form. This is applied on top of the default sanitization that masks `Authorization` and similar credentials (controlled by `SkipSanitize`). ### Example Usage: ```go logger.SkipHeader([]string{ "Authorization", "X-Api-Key", "Cookie", "Set-Cookie", }) ``` ``` -------------------------------- ### SkipHeader: Redact Specific Headers from Log Output Source: https://context7.com/henvic/httpretty/llms.txt Exclude specific headers from all log output by providing a slice of header names to SkipHeader. Header names are matched case-insensitively. This is useful for redacting sensitive information like API keys or authorization tokens. ```go package main import ( "net/http" "github.com/henvic/httpretty" ) func main() { logger := &httpretty.Logger{ RequestHeader: true, ResponseHeader: true, Colors: true, } // Omit these headers from printed output entirely. logger.SkipHeader([]string{ "Authorization", "X-Api-Key", "Cookie", "Set-Cookie", }) client := &http.Client{ Transport: logger.RoundTripper(http.DefaultTransport), } req, _ := http.NewRequest(http.MethodGet, "https://httpbin.org/headers", nil) req.Header.Set("Authorization", "Bearer super-secret-token") req.Header.Set("X-Api-Key", "my-key-123") client.Do(req) // Authorization and X-Api-Key headers are absent from terminal output. } ``` -------------------------------- ### Logger.SetBodyFilter Source: https://context7.com/henvic/httpretty/llms.txt Registers a BodyFilter function to conditionally suppress logging of request or response bodies based on headers. This is useful for omitting large payloads or sensitive content types. ```APIDOC ## `Logger.SetBodyFilter` — Conditional Body Suppression `SetBodyFilter` registers a `BodyFilter` function `func(h http.Header) (skip bool, err error)`. It is called with the request or response headers before printing the body. Returning `skip=true` omits the body from the log output (the body is still delivered to the caller). Useful for skipping large binary payloads or sensitive content types. ### Example Usage: ```go logger.SetBodyFilter(func(h http.Header) (skip bool, err error) { contentType := h.Get("Content-Type") if contentType == "" { return false, nil } // Only print JSON bodies; skip everything else (HTML, images, etc.). if !strings.Contains(contentType, "json") { return true, nil } return false, nil }) ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.