-
Notifications
You must be signed in to change notification settings - Fork 7
Consolidate logger initialization to use generic helpers #815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
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 consolidates ServerFileLogger global lifecycle management to use the same generic init/close helpers as the other logger types, and adds/expands documentation describing logger initialization and fallback strategies.
Changes:
- Extend
closableLoggerto include*ServerFileLoggerand add generic-helper-backedinitGlobalServerFileLogger/closeGlobalServerFileLogger. - Replace
ServerFileLogger’s manual global close logic with the genericcloseGlobalLogger-based helper. - Add a detailed “Initialization Pattern for Logger Types” documentation section describing fallback behaviors.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| internal/logger/server_file_logger.go | Swaps manual global close logic for a helper (closeGlobalServerFileLogger). |
| internal/logger/global_helpers.go | Extends the generic global logger helpers to cover ServerFileLogger and adds type-specific wrapper helpers. |
| internal/logger/common.go | Adds long-form documentation for initialization patterns and fallback strategy guidance. |
Comments suppressed due to low confidence (2)
internal/logger/common.go:185
- In "Adding a New Logger Type", step 3 mandates using initLogger(), but this isn't applicable for logger types that don't follow the open-on-init pattern (as noted for ServerFileLogger). Consider adjusting the guidance to say "use initLogger() when the logger opens a file during initialization" and describe alternatives for on-demand loggers.
// 1. Implement Close() method following the Close Pattern (above)
// 2. Add type to closableLogger constraint in global_helpers.go
// 3. Use initLogger() for initialization with appropriate fallback strategy
// 4. Add initGlobal*Logger() and closeGlobal*Logger() helpers
internal/logger/common.go:303
- File handle may be writable as a result of data flow from a call to OpenFile and closing it may result in data loss upon failure, which is not handled explicitly.
file.Close()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // closableLogger is a constraint for types that have a Close method. | ||
| // This is satisfied by *FileLogger, *JSONLLogger, and *MarkdownLogger. | ||
| // This is satisfied by *FileLogger, *JSONLLogger, *MarkdownLogger, and *ServerFileLogger. | ||
| type closableLogger interface { | ||
| *FileLogger | *JSONLLogger | *MarkdownLogger | ||
| *FileLogger | *JSONLLogger | *MarkdownLogger | *ServerFileLogger | ||
| Close() error |
Copilot
AI
Feb 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file header comment still describes these helpers as managing global state for FileLogger/JSONLLogger/MarkdownLogger only, but this PR extends them to ServerFileLogger as well. Update the header comment to include ServerFileLogger so documentation matches current behavior.
| // All logger types use the initLogger() generic helper function for initialization: | ||
| // |
Copilot
AI
Feb 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation says "All logger types use the initLogger() generic helper" but later in the same section notes that ServerFileLogger does not use initLogger() (it creates files on-demand). Please reword this to avoid the contradiction (e.g., specify which logger types use initLogger()).
This issue also appears on line 182 of the same file.
ServerFileLoggerwas manually implementing global state management that other loggers already handled via generic helpers inglobal_helpers.go. This created 23 lines of duplicate code and made fallback behavior strategies unclear.Changes
Extended generic helpers to ServerFileLogger
*ServerFileLoggertoclosableLoggerconstraintinitGlobalServerFileLogger()andCloseServerFileLogger()with calls to genericinitGlobalLogger()andcloseGlobalLogger()Documented fallback strategies
Added 130-line "Initialization Pattern for Logger Types" section to
common.goexplaining when each logger uses fallbacks:FileLogger: stdout fallback for critical operational logsMarkdownLogger: silent fallback for optional preview logsJSONLLogger: strict error mode for structured dataServerFileLogger: unified logger fallback for per-server logsExample
Before (manual implementation):
After (using generic helper):
All loggers now use the same thread-safe initialization pattern. Documentation provides clear guidance for adding new logger types.
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/tmp/go-build2696183341/b271/launcher.test /tmp/go-build2696183341/b271/launcher.test -test.testlogfile=/tmp/go-build2696183341/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1636032/b166/_pkg_.a go x_amd64/compile(dns block)invalid-host-that-does-not-exist-12345.com/tmp/go-build2696183341/b259/config.test /tmp/go-build2696183341/b259/config.test -test.testlogfile=/tmp/go-build2696183341/b259/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1636032/b153/_pkg_.a .cfg x_amd64/vet(dns block)nonexistent.local/tmp/go-build2696183341/b271/launcher.test /tmp/go-build2696183341/b271/launcher.test -test.testlogfile=/tmp/go-build2696183341/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1636032/b166/_pkg_.a go x_amd64/compile(dns block)slow.example.com/tmp/go-build2696183341/b271/launcher.test /tmp/go-build2696183341/b271/launcher.test -test.testlogfile=/tmp/go-build2696183341/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1636032/b166/_pkg_.a go x_amd64/compile(dns block)this-host-does-not-exist-12345.com/tmp/go-build2696183341/b280/mcp.test /tmp/go-build2696183341/b280/mcp.test -test.testlogfile=/tmp/go-build2696183341/b280/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.6/x64/src/runtime/c-g .cfg x_amd64/vet(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
This section details on the original issue you should resolve
<issue_title>[duplicate-code] Duplicate Code Pattern: Logger Initialization Boilerplate</issue_title>
<issue_description># 🔍 Duplicate Code Pattern: Logger Initialization Boilerplate
Part of duplicate code analysis: #797
Summary
Four logger files (
file_logger.go,jsonl_logger.go,markdown_logger.go,server_file_logger.go) share nearly identical initialization patterns for file handling, error management, and global state setup. This creates significant maintenance overhead and increases the risk of inconsistent behavior across loggers.Duplication Details
Pattern: Logger Initialization Structure
internal/logger/file_logger.go(lines 28-60, 63-68)internal/logger/jsonl_logger.go(lines 38-66, 69-74)internal/logger/markdown_logger.go(lines 28-54, 72-89)internal/logger/server_file_logger.go(lines 70-114)Duplicated Components
1. File Initialization Pattern (~40 lines per logger)
Each logger implements nearly identical logic:
2. Close Method Pattern (~8 lines per logger)
3. Global Logger State Pattern (~12 lines per logger)
Code Sample: File Logger
Similar structures exist in all 4 logger files with only minor variations.
Impact Analysis
Maintainability
Bug Risk
common.gowithinitLogger()helper, but only partial consolidation occurredCode Bloat
Refactoring Recommendations
1. Extract Logger Factory Pattern
Effort: Medium (4-6 hours)
Create a generic logger factory that handles common initialization:
Benefits:
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.