Skip to content

perf: skip HTTP body reading when debug logging is disabled#1097

Open
fredericrous wants to merge 4 commits into
masterfrom
perf/skip-debug-body-reads
Open

perf: skip HTTP body reading when debug logging is disabled#1097
fredericrous wants to merge 4 commits into
masterfrom
perf/skip-debug-body-reads

Conversation

@fredericrous

Copy link
Copy Markdown
Collaborator

Summary

  • loggingRoundTripper was reading entire HTTP request/response bodies via io.ReadAll() on every round trip, even at the default Info log level
  • The expensive work (body read, string conversion, concatenation) happened before Debug() was called, so the logger's internal level check couldn't prevent it
  • Now makeLogClient skips wrapping the transport entirely when debug logging is not enabled — zero overhead in the common case
  • Stacked on perf: reuse HTTP client transport instead of cloning it #1095

Fixes #1096

Test plan

  • go build ./... compiles cleanly
  • go test ./... — all tests pass
  • Manual: verify LOG_LEVEL=debug still produces HTTP debug output
  • Manual: verify default log level no longer reads bodies (observable via reduced CPU/memory)

🤖 Generated with Claude Code

fredericrous and others added 2 commits February 9, 2026 21:47
makeLogClient() was creating a new http.Client with a cloned transport,
which gave it a separate connection pool. This meant TCP+TLS connections
were never reused between update cycles.

Now wraps the original client's transport with the logging round tripper
directly, preserving the connection pool and keep-alive behavior.

Fixes #1094

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The loggingRoundTripper was unconditionally reading entire HTTP
request/response bodies via io.ReadAll() on every round trip, even
at the default Info log level. The expensive work (body read, string
conversion, concatenation) happened before Debug() was called, so
the logger's internal level check couldn't prevent it.

Now makeLogClient skips wrapping the transport entirely when debug
logging is not enabled, eliminating all overhead in the common case.

Fixes #1096

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Base automatically changed from perf/fix-http-connection-pooling to master April 10, 2026 16:58

@qdm12 qdm12 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Rebase on master/merge on master

Comment thread internal/update/update.go Outdated
fredericrous and others added 2 commits April 10, 2026 23:46
Per review feedback: keep makeLogClient with its original signature
and conditionally invoke it in NewUpdater instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@qdm12 qdm12 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Noice 👍 Just minor enhancement

Comment thread cmd/ddns-updater/main.go
*config.Health.HealthchecksioUUID)

updater := update.NewUpdater(db, client, shoutrrrClient, logger, timeNow)
debugEnabled := strings.EqualFold(config.Logger.Level, "DEBUG")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

(and import the qdm12/log package in main.go)

Suggested change
debugEnabled := strings.EqualFold(config.Logger.Level, "DEBUG")
debugEnabled := config.Logger.Level == log.LevelDebug.String()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants