Skip to content

logger: address CloseAllLoggers review comments — doc fix + tests#3770

Merged
lpcox merged 5 commits intomainfrom
copilot/fix-comments-in-review-thread
Apr 14, 2026
Merged

logger: address CloseAllLoggers review comments — doc fix + tests#3770
lpcox merged 5 commits intomainfrom
copilot/fix-comments-in-review-thread

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

Review comment on PR #3766 flagged two gaps in the CloseAllLoggers addition: the file-level comment implied CloseAllLoggers was internal-only (it isn't), and there were no tests locking in its "attempt all, return first error" semantics.

Changes

  • global_helpers.go — updated package-level doc comment to distinguish the unexported helpers (internal use only) from CloseAllLoggers (public entry point)

  • global_helpers_test.go — four new tests for CloseAllLoggers:

    • No loggers initialized → nil returned
    • All loggers close cleanly → all globals are nil afterward
    • First closer fails (pre-closed fd) → remaining closers still run, all globals nil
    • Two closers fail → error from the first closer is returned, not the second

The "all called even on failure" and "first error wins" properties are verified by pre-closing the underlying *os.File before calling CloseAllLoggers, which causes the targeted Close() to return a *os.PathError containing the logger's directory path — making the two errors distinguishable.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build22527721/b514/launcher.test /tmp/go-build22527721/b514/launcher.test -test.testlogfile=/tmp/go-build22527721/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s -W emplate/v3@v3.0.-errorsas emplate/v3@v3.0.-ifaceassert x_amd64/vet gci-lint failed /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet chr/testify/requ-atomic --64 x_amd64/vet -I g_.a -oCxtYgSg x_amd64/vet --gdwarf-5 5389254/b265/ -o x_amd64/vet (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build22527721/b496/config.test /tmp/go-build22527721/b496/config.test -test.testlogfile=/tmp/go-build22527721/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build22527721/b392/vet.cfg g_.a -I x_amd64/vet --gdwarf-5 /v1.37.0 -o x_amd64/vet -uns�� 1.80.0/internal/-errorsas 1.80.0/internal/-ifaceassert x_amd64/vet d -n 10 nal/detrand cal/bin/git x_amd64/vet (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build22527721/b514/launcher.test /tmp/go-build22527721/b514/launcher.test -test.testlogfile=/tmp/go-build22527721/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s -W emplate/v3@v3.0.-errorsas emplate/v3@v3.0.-ifaceassert x_amd64/vet gci-lint failed /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet chr/testify/requ-atomic --64 x_amd64/vet -I g_.a -oCxtYgSg x_amd64/vet --gdwarf-5 5389254/b265/ -o x_amd64/vet (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build22527721/b514/launcher.test /tmp/go-build22527721/b514/launcher.test -test.testlogfile=/tmp/go-build22527721/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s -W emplate/v3@v3.0.-errorsas emplate/v3@v3.0.-ifaceassert x_amd64/vet gci-lint failed /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet chr/testify/requ-atomic --64 x_amd64/vet -I g_.a -oCxtYgSg x_amd64/vet --gdwarf-5 5389254/b265/ -o x_amd64/vet (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build22527721/b523/mcp.test /tmp/go-build22527721/b523/mcp.test -test.testlogfile=/tmp/go-build22527721/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s -uns�� .cfg 5389254/b288/ 64/pkg/tool/linux_amd64/vet get --global x_amd64/compile 64/pkg/tool/linux_amd64/vet 5389�� .cfg /tmp/go-build98228851/b163/vet.c-ifaceassert x_amd64/vet get mcpg /opt/hostedtoolc(create|run) x_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

lpcox and others added 3 commits April 14, 2026 08:21
Extract lockable struct (embedded sync.Mutex + withLock helper) into
global_helpers.go and embed it in FileLogger, JSONLLogger, MarkdownLogger,
and ToolsLogger. This removes four identical withLock method definitions.

Also add CloseAllLoggers() convenience function that closes every global
logger in a single call.

Fixes #3685
Fixes #3735

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI and others added 2 commits April 14, 2026 15:46
…ot/fix-comments-in-review-thread

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix code based on review comments logger: address CloseAllLoggers review comments — doc fix + tests Apr 14, 2026
Copilot AI requested a review from lpcox April 14, 2026 15:55
@lpcox lpcox marked this pull request as ready for review April 14, 2026 15:57
Copilot AI review requested due to automatic review settings April 14, 2026 15:57
@lpcox lpcox merged commit 4f77b7d into main Apr 14, 2026
4 checks passed
@lpcox lpcox deleted the copilot/fix-comments-in-review-thread branch April 14, 2026 15:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the logger package documentation and adds tests to lock in CloseAllLoggers semantics, while also continuing the logger mutex/withLock deduplication via lockable embedding across logger types.

Changes:

  • Clarify global_helpers.go package docs to distinguish internal-only helpers vs the public CloseAllLoggers API.
  • Add global_helpers_test.go to assert CloseAllLoggers “attempt all closers” + “first error wins” behavior.
  • Refactor logger structs (File/JSONL/Markdown/Tools) to embed lockable and remove per-type mu/withLock boilerplate.
Show a summary per file
File Description
internal/logger/global_helpers.go Doc clarification + defines CloseAllLoggers and lockable helper.
internal/logger/global_helpers_test.go Adds test coverage for CloseAllLoggers semantics and global cleanup expectations.
internal/logger/file_logger.go Switches to embedded lockable instead of per-type mutex/withLock.
internal/logger/jsonl_logger.go Switches to embedded lockable instead of per-type mutex/withLock.
internal/logger/markdown_logger.go Switches to embedded lockable instead of per-type mutex/withLock.
internal/logger/tools_logger.go Switches to embedded lockable instead of per-type mutex/withLock.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 2

Comment on lines +11 to +33
// resetAllGlobalLoggers resets all global logger pointers to nil for test isolation.
// It acquires each logger's mutex before resetting to avoid races.
func resetAllGlobalLoggers(t *testing.T) {
t.Helper()
globalLoggerMu.Lock()
globalFileLogger = nil
globalLoggerMu.Unlock()

globalJSONLMu.Lock()
globalJSONLLogger = nil
globalJSONLMu.Unlock()

globalMarkdownMu.Lock()
globalMarkdownLogger = nil
globalMarkdownMu.Unlock()

globalToolsMu.Lock()
globalToolsLogger = nil
globalToolsMu.Unlock()

globalServerLoggerMu.Lock()
globalServerFileLogger = nil
globalServerLoggerMu.Unlock()
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

resetAllGlobalLoggers nils out the global logger pointers without closing any already-initialized loggers. If a previous test leaves a global logger open (or a new test is added that forgets to close), this helper will leak file descriptors and can make failures harder to debug. Consider calling CloseAllLoggers() (ignoring its error) before clearing pointers, and update the comment to reflect that it uses the global RWMutexes (not the per-logger mutexes).

Copilot uses AI. Check for mistakes.
Comment on lines 11 to 18
// FileLogger manages logging to a file with fallback to stdout
type FileLogger struct {
lockable
logFile *os.File
logger *log.Logger
mu sync.Mutex
logDir string
fileName string
useFallback bool
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

PR description says this follow-up only updates global_helpers.go docs + adds CloseAllLoggers tests, but this PR also changes FileLogger to embed lockable and removes the per-type mu/withLock boilerplate. Please either update the PR description to reflect these additional refactor changes or split them into a separate PR/commit so review intent matches the diff.

Copilot uses AI. Check for mistakes.
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.

3 participants