Skip to content

fix: avoid retaining unused methods in debug logging - #1023

Open
hakman wants to merge 1 commit into
linode:mainfrom
hakman:fmt-debug-logging
Open

fix: avoid retaining unused methods in debug logging#1023
hakman wants to merge 1 commit into
linode:mainfrom
hakman:fmt-debug-logging

Conversation

@hakman

@hakman hakman commented Aug 14, 2026

Copy link
Copy Markdown

📝 Description

What does this PR do and why is this change necessary?

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.

Fixes #1022

✔️ How to Test

What are the steps to reproduce the issue or verify the changes?
See #1022.

How do I run the relevant unit/integration tests?
n/a

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.

Fixes linode#1022
Copilot AI lite review requested due to automatic review settings August 14, 2026 16:12
@hakman
hakman requested review from a team as code owners August 14, 2026 16:12
@hakman
hakman requested review from mawilk90 and zliang-akamai and removed request for a team August 14, 2026 16:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes text/template usage from Client debug request/response logging to avoid pulling in reflection-based template execution that prevents the Go linker from dead-code-eliminating unused methods in downstream consumer binaries (per #1022).

Changes:

  • Replace embedded text/template request/response log rendering with fmt.Sprintf-based formatting in client.go.
  • Delete the now-unused request/response log template files.
  • Document (in-code) why templates are avoided for this logging path.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
client.go Replaces template-driven debug logging with fmt.Sprintf and introduces new request/response log format constants.
request_log_template.tmpl Removed (no longer used after switching away from templates).
response_log_template.tmpl Removed (no longer used after switching away from templates).
Suppressed comments (1)

client.go:71

  • The new responseLogFormat raw string also drops the prior " |" prefixes and will include source indentation (tabs/spaces) in the emitted log output. If the goal is byte-for-byte identical output vs the previous template-based format (per PR description), the format should preserve the exact leading characters and avoid indentation artifacts from raw string literals.
	responseLogFormat = `
============================================================================================
~~~ RESPONSE ~~~
STATUS: %v
PROTO: %v

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread client.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

hakman added a commit to hakman/kops that referenced this pull request Aug 14, 2026
linodego's debug logging renders embedded text/template files. Linking
the template execution engine disables the Go linker's dead code
elimination for methods in every consumer binary
(linode/linodego#1022).

Carry a trimmed copy of v2.4.1 under third_party/linodego with the
debug logs rendered by fmt instead, wired in with a go.mod replace
directive. Drop the fork and the replace once the upstream fix
(linode/linodego#1023) ships in a tagged release.
hakman added a commit to hakman/kops that referenced this pull request Aug 14, 2026
Carry a trimmed copy of github.com/linode/linodego/v2 v2.4.1 (root
package and the internal helpers kOps uses) under third_party/linodego,
wired in with a go.mod replace directive; the vendor tree is generated
from it. The code is unchanged.

This is preparation for making its debug logging safe for the Go
linker's method pruning, which the next commit does. Drop the fork and
the replace once the upstream fix (linode/linodego#1023) ships in a
tagged release.
hakman added a commit to hakman/kops that referenced this pull request Aug 14, 2026
Render the request/response debug logs with plain fmt format constants
instead of text/template, and drop the embedded .tmpl files. The
rendered output is byte-for-byte identical.

Linking the template execution engine disables the Go linker's dead
code elimination for methods in every consumer binary
(linode/linodego#1022). This mirrors the
upstream fix proposed in linode/linodego#1023.
hakman added a commit to hakman/kops that referenced this pull request Aug 14, 2026
Carry a trimmed copy of github.com/linode/linodego/v2 v2.4.1 (root
package and the internal helpers kOps uses) under third_party/linodego,
wired in with a go.mod replace directive; the vendor tree is generated
from it. The code is unchanged.

This is preparation for making its debug logging safe for the Go
linker's method pruning, which the next commit does. Drop the fork and
the replace once the upstream fix (linode/linodego#1023) ships in a
tagged release.
hakman added a commit to hakman/kops that referenced this pull request Aug 14, 2026
Render the request/response debug logs with plain fmt format constants
instead of text/template, and drop the embedded .tmpl files. The
rendered output is byte-for-byte identical, pinned by a test in the
fork module.

Linking the template execution engine disables the Go linker's dead
code elimination for methods in every consumer binary
(linode/linodego#1022). This mirrors the
upstream fix proposed in linode/linodego#1023.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops,
kops-controller and nodeup (nodeup bootstrap script, addon manifests,
kops toolbox template) to the third_party/forked/text/template fork.
TemplateFunctions.AddTo now takes the fork FuncMap type.

Once the vendored linodego dependency also stops rendering its debug
logging with text/template (linode/linodego#1023), no REFLECTMETHOD
symbol remains reachable and the linker prunes unused methods again.
Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and
-tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to
73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops, kops-controller and nodeup (nodeup bootstrap script, addon manifests, kops toolbox template) to the third_party/forked/text/template fork.

Because the fork FuncMap aliases the stdlib type, TemplateFunctions.AddTo retains exact method-signature identity. Tests pass a stdlib FuncMap through AddTo and execute it with the fork. The toolbox documentation and 1.37 release notes describe the intentional method-lookup incompatibility.

Once the vendored linodego dependency also stops rendering its debug logging with text/template (linode/linodego#1023), no REFLECTMETHOD symbol remains reachable and the linker prunes unused methods again. Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and -tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to 73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
hakman added a commit to hakman/kops that referenced this pull request Aug 15, 2026
Switch the production rendering paths reachable from kops, kops-controller and nodeup (nodeup bootstrap script, addon manifests, kops toolbox template) to the third_party/forked/text/template fork.

Because the fork FuncMap aliases the stdlib type, TemplateFunctions.AddTo retains exact method-signature identity. Tests pass a stdlib FuncMap through AddTo and execute it with the fork. The toolbox documentation and 1.37 release notes describe the intentional method-lookup incompatibility.

Once the vendored linodego dependency also stops rendering its debug logging with text/template (linode/linodego#1023), no REFLECTMETHOD symbol remains reachable and the linker prunes unused methods again. Measured on linux/arm64 with -trimpath, -ldflags="-s -w" and -tags=disable_grpc_modules,grpcnotrace: kops shrinks from 156.9 MB to 73.8 MB and kops-controller from 150.9 MB to 69.0 MB.
@zliang-akamai zliang-akamai added the community-contribution contributions from the community. label Aug 17, 2026
@zliang-akamai
zliang-akamai requested a review from a team August 17, 2026 00:15
@zliang-akamai
zliang-akamai requested review from jbilskiAkam and removed request for a team August 17, 2026 00:15
@zliang-akamai

Copy link
Copy Markdown
Member

This looks like a very helpful and impactful optimization. Thank you so much for your contribution!

@mawilk90
mawilk90 requested review from a team and jbilskiAkam and removed request for a team and jbilskiAkam August 17, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution contributions from the community.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: debug logging disables Go linker dead code elimination in consumers

4 participants