From 8ae2ed51c621cb6a394703a00950122973ed536e Mon Sep 17 00:00:00 2001 From: Ciprian Hacman Date: Mon, 17 Aug 2026 16:20:27 +0300 Subject: [PATCH] fix: avoid retaining unused methods in debug logging Using text/template for the debug logs forces the Go linker to keep methods that programs importing linodego never use, which increases their binary size. Format the request and response logs with fmt.Sprintf instead. The output is unchanged, and the linker can drop the unused methods. Signed-off-by: Ciprian Hacman --- client.go | 65 ++++++++++++++++---------------------- request_log_template.tmpl | 8 ----- response_log_template.tmpl | 10 ------ 3 files changed, 28 insertions(+), 55 deletions(-) delete mode 100644 request_log_template.tmpl delete mode 100644 response_log_template.tmpl diff --git a/client.go b/client.go index 578e8b3d7..6e96081d8 100644 --- a/client.go +++ b/client.go @@ -5,7 +5,6 @@ import ( "context" "crypto/tls" "crypto/x509" - _ "embed" "encoding/json" "fmt" "io" @@ -22,7 +21,6 @@ import ( "strconv" "strings" "sync" - "text/template" "time" ) @@ -53,17 +51,29 @@ const ( APIDefaultCacheExpiration = time.Minute * 15 ) -// Embed the log template files -// -//go:embed request_log_template.tmpl -var requestTemplateStr string - -//go:embed response_log_template.tmpl -var responseTemplateStr string - -var ( - reqLogTemplate = template.Must(template.New("request").Parse(requestTemplateStr)) - respLogTemplate = template.Must(template.New("response").Parse(responseTemplateStr)) +// Debug log formats. These are deliberately plain fmt formats rather than text/template. +// Linking the template execution engine disables the Go linker's dead code elimination for +// methods in every consumer binary (see https://github.com/linode/linodego/issues/1022). +const ( + requestLogFormat = ` +============================================================================================ +~~~ REQUEST ~~~ +%v +HOST: %v +HEADERS: %v +BODY: %v +--------------------------------------------------------------------------------------------` + + responseLogFormat = ` +============================================================================================ +~~~ RESPONSE ~~~ +STATUS: %v +PROTO: %v +RECEIVED AT: %v +TIME DURATION: %v +HEADERS: %v +BODY: %v +--------------------------------------------------------------------------------------------` ) type RequestLog struct { @@ -737,17 +747,8 @@ func (c *Client) logRequest(req *http.Request) *http.Request { } } - var logBuf bytes.Buffer - - err := reqLogTemplate.Execute(&logBuf, map[string]any{ - "Request": reqLog.Request, - "Host": reqLog.Host, - "Headers": formatHeaders(reqLog.Headers), - "Body": body, - }) - if err == nil { - c.logger.Debugf(sanitizeLogValue(logBuf.String())) - } + c.logger.Debugf(sanitizeLogValue(fmt.Sprintf(requestLogFormat, + reqLog.Request, reqLog.Host, formatHeaders(reqLog.Headers), body))) return req } @@ -862,19 +863,9 @@ func (c *Client) logResponse(resp *http.Response, start, end time.Time) *http.Re } } - var logBuf bytes.Buffer - - err := respLogTemplate.Execute(&logBuf, map[string]any{ - "Status": respLog.Status, - "Proto": respLog.Proto, - "ReceivedAt": respLog.ReceivedAt, - "TimeDuration": respLog.TimeDuration, - "Headers": formatHeaders(redactHeaders(respLog.Headers)), - "Body": body, - }) - if err == nil { - c.logger.Debugf(sanitizeLogValue(logBuf.String())) - } + c.logger.Debugf(sanitizeLogValue(fmt.Sprintf(responseLogFormat, + respLog.Status, respLog.Proto, respLog.ReceivedAt, respLog.TimeDuration, + formatHeaders(redactHeaders(respLog.Headers)), body))) resp.Body = io.NopCloser(bytes.NewReader(respBody.Bytes())) diff --git a/request_log_template.tmpl b/request_log_template.tmpl deleted file mode 100644 index 250547bd8..000000000 --- a/request_log_template.tmpl +++ /dev/null @@ -1,8 +0,0 @@ - -============================================================================================ -~~~ REQUEST ~~~ -{{.Request}} -HOST: {{.Host}} -HEADERS: {{.Headers}} -BODY: {{.Body}} --------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/response_log_template.tmpl b/response_log_template.tmpl deleted file mode 100644 index 7bd5f38d8..000000000 --- a/response_log_template.tmpl +++ /dev/null @@ -1,10 +0,0 @@ - -============================================================================================ -~~~ RESPONSE ~~~ -STATUS: {{.Status}} -PROTO: {{.Proto}} -RECEIVED AT: {{.ReceivedAt}} -TIME DURATION: {{.TimeDuration}} -HEADERS: {{.Headers}} -BODY: {{.Body}} --------------------------------------------------------------------------------------------- \ No newline at end of file