Fix code review findings: timestamps, error handling, tests, docs#56
Fix code review findings: timestamps, error handling, tests, docs#56
Conversation
Pull Request Test Coverage Report for Build 22087845807Details
💛 - Coveralls |
There was a problem hiding this comment.
Pull request overview
This PR addresses a set of issues found during a full-project code review, focusing on correctness (timestamps, writer lifecycle), improved error handling, more reliable tests, and updated documentation.
Changes:
- Fix Docker event timestamp handling (including
TimeNanofallback) and add guards/tests for edge cases in discovery. - Replace fatal exits in
makeLogWriterswith error returns; harden writer lifecycle (syslog double-close) and improve validation. - Reduce test flakiness by replacing
time.Sleepwithrequire.Eventually, and expand syslog + MixErr coverage; update README/godoc/CLAUDE docs accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/plans/completed/20260216-code-review-fixes.md | Adds a completed implementation plan/trace for the review-driven fixes. |
| app/syslog/syslog_unix.go | Clarifies GetWriter godoc re: syslog prefix usage. |
| app/main_test.go | Removes sleep-based waits; adds sentinel/eventually synchronization; adds new writer/syslog/MixErr tests. |
| app/main.go | Adds filter/destination validation; changes makeLogWriters to return errors; prevents syslog double-close via writeNopCloser. |
| app/logger/multiwriter.go | Fixes loop variable shadowing in Write/Close. |
| app/logger/logger_test.go | Replaces sleeps with require.Eventually to reduce flakiness. |
| app/logger/logger.go | Improves godoc for Go, Close, and Wait. |
| app/discovery/events_test.go | Adds timestamp validation and coverage for containers with no names + TimeNano fallback. |
| app/discovery/events.go | Fixes event listener typo; corrects timestamp calculation and adds guard for empty container names. |
| README.md | Adds missing CLI flags and documents additional mutual exclusivity rules; fixes one typo. |
| CLAUDE.md | Documents makeLogWriters signature change and the syslog no-double-close pattern; adds testing guidance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
README.md
Outdated
| - both `--exclude` and `--include` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--include` not allowed, and vise versa. | ||
| - both `--include` and `--include-pattern` flags are optional and mutually exclusive, i.e. if `--include` defined `--include-pattern` not allowed, and vise versa. | ||
| - both `--exclude` and `--exclude-pattern` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--exclude-pattern` not allowed, and vise versa. |
There was a problem hiding this comment.
The new README bullets use the misspelling "vise versa". Please change to "vice versa" for correct wording.
| - both `--exclude` and `--include` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--include` not allowed, and vise versa. | |
| - both `--include` and `--include-pattern` flags are optional and mutually exclusive, i.e. if `--include` defined `--include-pattern` not allowed, and vise versa. | |
| - both `--exclude` and `--exclude-pattern` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--exclude-pattern` not allowed, and vise versa. | |
| - both `--exclude` and `--include` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--include` not allowed, and vice versa. | |
| - both `--include` and `--include-pattern` flags are optional and mutually exclusive, i.e. if `--include` defined `--include-pattern` not allowed, and vice versa. | |
| - both `--exclude` and `--exclude-pattern` flags are optional and mutually exclusive, i.e. if `--exclude` defined `--exclude-pattern` not allowed, and vice versa. |
app/main_test.go
Outdated
| opts := cliOpts{EnableFiles: true, FilesLocation: "/dev/null/invalid/path"} | ||
| _, _, err := makeLogWriters(&opts, "container1", "gr1") |
There was a problem hiding this comment.
This test uses a hard-coded Unix-specific path ("/dev/null/invalid/path") to force a mkdir error. This is not portable (will behave differently on Windows) and can also risk creating real directories on some platforms. Prefer constructing a guaranteed-invalid path using t.TempDir() (e.g., create a file and attempt MkdirAll under it) so the failure is hermetic across OSes.
| opts := cliOpts{EnableFiles: true, FilesLocation: "/dev/null/invalid/path"} | |
| _, _, err := makeLogWriters(&opts, "container1", "gr1") | |
| tmpDir := t.TempDir() | |
| // create a regular file and then try to use a path under it as FilesLocation; | |
| // this is guaranteed to fail when attempting to create a directory. | |
| invalidParent := filepath.Join(tmpDir, "not-a-dir") | |
| err := os.WriteFile(invalidParent, []byte("x"), 0o600) | |
| require.NoError(t, err) | |
| opts := cliOpts{ | |
| EnableFiles: true, | |
| FilesLocation: filepath.Join(invalidParent, "subdir"), | |
| } | |
| _, _, err = makeLogWriters(&opts, "container1", "gr1") |
| func (e *EventNotif) activate(client DockerClient) { | ||
| dockerEventsCh := make(chan *docker.APIEvents) | ||
| if err := client.AddEventListener(dockerEventsCh); err != nil { | ||
| log.Fatalf("[ERROR] can't add even listener, %v", err) | ||
| log.Fatalf("[ERROR] can't add event listener, %v", err) | ||
| } |
There was a problem hiding this comment.
activate still uses log.Fatalf when AddEventListener fails, which will terminate the whole process from inside the discovery component and bypass caller error handling/cleanup. Since similar paths were changed to return errors elsewhere in this PR, consider propagating this failure back to the caller (e.g., have NewEventNotif/activate return an error or send an error event) instead of exiting.
- improve error handling and input validation in discovery, logger, and main - replace flaky time.Sleep patterns with channel-based synchronization in tests - add test coverage for edge cases and error paths - update README and CLAUDE.md documentation
a42752d to
1179b8c
Compare
Bug fixes:
events.go—Timewas divided by 1000 (already Unix seconds),TimeNanowas misused as sub-second offset instead of full nanosecond timestamp. Added fallback for older Docker API versions whereTimeNanomay be zerosyslogWriterwas added to both log and errMultiWriterslices, gettingClose()called twice. Fixed withwriteNopCloserwrapper on the err copyevents.goc.Namesslice inemitRunningContainers()Error handling improvements:
log.FatalfinmakeLogWriterswith proper error returns — signature changed to(logWriter, errWriter io.WriteCloser, err error), callers handle gracefullyIncludesPattern + ExcludesPattern,Includes + ExcludesPattern,IncludesPattern + Excludescombinations now rejectedcloseStreamWritershelper inrunEventLoopCode quality:
MultiWriter.WriteandClose— loop variablewshadowed receiverTest reliability:
time.Sleeppatterns withrequire.Eventuallyand channel-based synchronization acrossmain_test.goandlogger_test.goMixErrcoverage forrunEventLoopmakeLogWritersDocumentation:
--loc/LOG_FILES_LOC,--syslog-prefix/SYSLOG_PREFIX,--dbg/DEBUG--exclude/--exclude-patternmutual exclusivity note to READMEGetWriter,LogStreamer.Go(),Close(),Wait()makeLogWriterssignature change andwriteNopCloserpattern