Part of duplicate code analysis: #1882
Summary
The [TIMESTAMP] [LEVEL] [CATEGORY] MESSAGE log-line formatting block is copy-pasted verbatim in at least 3 logger files. A single-character format change (e.g., switching from RFC3339 to RFC3339Nano) requires editing multiple files.
Duplication Details
Pattern: Inline Log-Line Timestamp Construction
- Severity: Medium
- Occurrences: 5 instances across 3+ logger files
- Locations:
internal/logger/file_logger.go (lines ~85–89)
internal/logger/server_file_logger.go (lines ~111–115)
internal/logger/markdown_logger.go (similar block)
Exact duplicate (file_logger.go and server_file_logger.go are byte-for-byte identical for these 4 lines):
timestamp := time.Now().UTC().Format(time.RFC3339)
message := fmt.Sprintf(format, args...)
logLine := fmt.Sprintf("[%s] [%s] [%s] %s", timestamp, level, category, message)
fl.logger.Println(logLine) // server_file_logger: logger.Println(logLine)
Impact Analysis
- Maintainability: Format changes (timestamp precision, bracket style, JSON output) require multi-file edits
- Bug Risk: Low for now, but any drift (e.g., one file switching to UTC+local or adding a request-ID field) will silently produce inconsistent log formats
- Code Bloat: ~20–30 lines of duplicated formatting logic (small but exact)
Refactoring Recommendations
-
Extract FormatLogLine utility (quick win, ~30 min effort):
// internal/logger/format.go
func FormatLogLine(level, category, format string, args ...any) string {
timestamp := time.Now().UTC().Format(time.RFC3339)
message := fmt.Sprintf(format, args...)
return fmt.Sprintf("[%s] [%s] [%s] %s", timestamp, level, category, message)
}
Each logger's write path becomes:
fl.logger.Println(FormatLogLine(level, category, format, args...))
-
Consider timeutil package — internal/timeutil/ already exists; FormatLogLine or at minimum FormatTimestamp() could live there to avoid circular imports.
-
Single source of truth for log format — store the format string as a package-level constant so it can be changed in one place.
Implementation Checklist
Parent Issue
See parent analysis report: #1882
Related to #1882
Generated by Duplicate Code Detector · ◷
Part of duplicate code analysis: #1882
Summary
The
[TIMESTAMP] [LEVEL] [CATEGORY] MESSAGElog-line formatting block is copy-pasted verbatim in at least 3 logger files. A single-character format change (e.g., switching from RFC3339 to RFC3339Nano) requires editing multiple files.Duplication Details
Pattern: Inline Log-Line Timestamp Construction
internal/logger/file_logger.go(lines ~85–89)internal/logger/server_file_logger.go(lines ~111–115)internal/logger/markdown_logger.go(similar block)Exact duplicate (file_logger.go and server_file_logger.go are byte-for-byte identical for these 4 lines):
Impact Analysis
Refactoring Recommendations
Extract
FormatLogLineutility (quick win, ~30 min effort):Each logger's write path becomes:
Consider
timeutilpackage —internal/timeutil/already exists;FormatLogLineor at minimumFormatTimestamp()could live there to avoid circular imports.Single source of truth for log format — store the format string as a package-level constant so it can be changed in one place.
Implementation Checklist
internal/logger/format.gowithFormatLogLinehelperfile_logger.go,server_file_logger.go,markdown_logger.gomake testto verify no output format regressionsParent Issue
See parent analysis report: #1882
Related to #1882