drpc: add Logger interface replacing Log callback and drpcdebug#57
Open
cthumuluru-crdb wants to merge 4 commits intocockroachdb:mainfrom
Open
drpc: add Logger interface replacing Log callback and drpcdebug#57cthumuluru-crdb wants to merge 4 commits intocockroachdb:mainfrom
cthumuluru-crdb wants to merge 4 commits intocockroachdb:mainfrom
Conversation
Today, DRPC has a fragile logging setup: the server takes a `Log func(error)` callback for error reporting, and a build-tag-gated `drpcdebug` package for operational tracing. The callback only supports errors (no levels), and the debug logging is compile-time only with zero production usage. Inspired by Pebble's Logger pattern, this commit introduces a proper Logger interface with four log levels: - Debugf: for verbose operational tracing (replaces drpcdebug in later commits) - Infof: for general operational messages - Errorf: for error conditions - Fatalf: for unrecoverable errors DefaultLogger logs Infof/Errorf/Fatalf to stderr via Go's stdlib log package, while Debugf is a no-op to keep production quiet by default. Consumers like CockroachDB can provide their own Logger implementation to route debug logs through verbose/conditional logging systems. InMemLogger captures all levels into an in-memory buffer for use in tests. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
The server's `Options.Log func(error)` was a limited error-only callback that required nil-checks at every callsite and offered no log-level differentiation. Replace it with the new `Logger` field, which defaults to `drpc.DefaultLogger` when nil. The two existing logging callsites in `Serve()` now use `Logger.Errorf`: - temporary accept errors (with retry) - client connection handler errors This is a breaking API change. CockroachDB is the only consumer and will be updated in a subsequent commit. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
273dbe9 to
dcb1977
Compare
…pcpool Thread the Logger interface through the entire DRPC stack so that all packages have access to structured logging: - drpcwire.Writer: add NewWriterWithLogger constructor, replace drpcdebug.Log calls with Logger.Debugf for buffer flush events. - drpcstream.Options: add Logger field, default to drpc.DefaultLogger. Replace drpcdebug.Log calls with Logger.Debugf for stream lifecycle events (HANDLE, SEND, FIN, FLUSH, CALL). - drpcmanager.Options: add Logger field, default to drpc.DefaultLogger. Replace drpcdebug.Log calls with Logger.Debugf for connection management events (WAIT, TERM, READ, STREAM, CANCEL, BUSY, UNFIN, CLEAN). Propagate Logger to Writer and Stream instances it creates. - drpcpool.Options: add Logger field, default to drpc.DefaultLogger. Replace drpcdebug.Log calls with Logger.Debugf for pool operations (CLOSE, TAKEN, PUT). - drpcserver: propagate its Logger to the managers it creates via ServeOne, ensuring the entire call stack shares the same logger. All packages now use Logger.Debugf instead of the build-tag-gated drpcdebug.Log. Since DefaultLogger.Debugf is a no-op, production behavior is unchanged. Custom Logger implementations (e.g. CockroachDB's) can route these to verbose/conditional logging. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
The drpcdebug package provided build-tag-gated debug logging that was activated only when building with `-tags=debug`. Investigation shows it was effectively dead code: - No CI configuration or Makefile ever enabled the debug build tag - No tests validated the debug-enabled code path - CockroachDB (the primary consumer) never used it - Last substantive change was in June 2021 - Only 4 callsites existed, all now replaced by Logger.Debugf All functionality has been migrated to the Logger interface introduced in the previous commits. The drpcdebug package is no longer imported anywhere and can be safely deleted. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
dcb1977 to
7bab156
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
DRPC's logging has two problems:
Options.Log func(error)is an error-only callback with no log-level differentiation, requiring nil-checks at every callsite.drpcdebugpackage provides build-tag-gated debug logging (-tags=debug) but is effectively dead code — no CI coverage, no tests, no active consumer. Last substantive change was in 2021.This PR replaces both with a structured
Loggerinterface (inspired by Pebble's logging pattern) and a new compile-time debug guard.Changes
drpc.LoggerinterfaceA four-method interface (
Debugf,Infof,Errorf,Fatalf) in the top-leveldrpcpackage, alongsideHandler,Conn,Transport, etc.DefaultLogger—Debugfis a no-op; other levels log to stderr.Suitable for production out of the box.
InMemLogger— captures all output in memory for use in tests.drpcserver: replaceLogcallbackOptions.Log func(error)is replaced withOptions.Logger. This is a breaking change — CockroachDB is the only consumer and is updated in a companion PR.Logger propagation
Loggeris threaded throughOptionsin every package that emits log messages:Each constructor defaults
opts.Loggertodrpc.DefaultLoggerif nil. No package stores a redundant copy — all access goes throughopts.Logger.drpcdebugpackage removedThe dead
drpcdebugpackage is deleted. Its build-tag guard concept is preserved in a simpler form (see below).Build-tag-gated debug logging
Debug log callsites sit on hot RPC paths (stream lifecycle, buffer flushes, packet reads). To guarantee zero cost in production, debug logging uses two layers of protection:
Compile-time constant —
drpc.DebugEnabledis aconst booldefined in a pair of build-tagged files (debug_on.go/debug_off.go). When the constant isfalse, the compiler eliminates guarded blocks entirely.Callback pattern — log helpers take
cb func() stringinstead of pre-formatted strings. Expensive formatting (fmt.Sprintf,.String()) is deferred and only evaluated when debug logging is compiled in.DebugEnabledgo buildfalsego build -tags=drpcdebugtrueInfof,Errorf, andFatalfare always active regardless of the build tag.Running tests with debug logging
Companion PR
cockroachdb/cockroach#169813 — implements
drpcLoggerrouting DRPC log output to CockroachDB's DEV channel and injects it into both server and client pool.