Part of duplicate code analysis: #3685
Summary
The LogInfo / LogWarn / LogError / LogDebug level-dispatch quartet appears three times in the logger package, once per logging façade (file, markdown, per-server). Each set of four functions follows the same structural pattern: a public one-liner that calls a private logWithXxx helper at the appropriate level constant.
Duplication Details
Pattern: 4-function level-dispatch quartet (×3 façades)
- Severity: Medium
- Occurrences: 3 complete sets (12 functions total)
- Locations:
internal/logger/file_logger.go lines 122–140 — LogInfo / LogWarn / LogError / LogDebug calling logWithLevel
internal/logger/markdown_logger.go lines 197–214 — LogInfoMd / LogWarnMd / LogErrorMd / LogDebugMd calling logWithMarkdownLevel
internal/logger/server_file_logger.go lines 158–176 — LogInfoWithServer / LogWarnWithServer / LogErrorWithServer / LogDebugWithServer calling logWithLevelAndServer
- Code Sample (shape is identical across all three files):
// LogInfo logs an informational message
func LogInfo(category, format string, args ...interface{}) {
logWithLevel(LogLevelInfo, category, format, args...)
}
// LogWarn logs a warning message
func LogWarn(category, format string, args ...interface{}) {
logWithLevel(LogLevelWarn, category, format, args...)
}
// (LogError and LogDebug follow the same pattern)
Impact Analysis
- Maintainability: Adding a new
LogLevel constant requires updating the quartet in all three files. The existing logFuncs map (file_logger.go:147) partially mitigates this for the inner dispatch, but the public wrappers still need manual updates.
- Bug Risk: Low for existing levels; medium for new level additions (easy to miss one façade).
- Code Bloat: ~36 lines of structurally identical one-liner wrappers.
Refactoring Recommendations
-
Code-generate the wrappers using go generate + a small template. Each façade provides only its inner logWithXxx function; the four public wrappers are emitted by generate. This is the highest-fidelity option if new levels are anticipated.
-
Consolidate into a LogFacade struct with a single variadic Log(level, ...) method, replacing the four typed wrappers. Callers that currently rely on LogInfo(...) continue to work via thin aliases. This reduces the public surface while centralising level dispatch.
-
Accept the pattern (lowest effort) — logFuncs already prevents switch-on-level duplication inside each helper; the remaining four wrappers per façade are very small. Document explicitly that adding a LogLevel requires updating all three façades.
Implementation Checklist
Parent Issue
See parent analysis report: #3685
Related to #3685
Generated by Duplicate Code Detector · ● 1.6M · ◷
Part of duplicate code analysis: #3685
Summary
The
LogInfo / LogWarn / LogError / LogDebuglevel-dispatch quartet appears three times in the logger package, once per logging façade (file, markdown, per-server). Each set of four functions follows the same structural pattern: a public one-liner that calls a privatelogWithXxxhelper at the appropriate level constant.Duplication Details
Pattern: 4-function level-dispatch quartet (×3 façades)
internal/logger/file_logger.golines 122–140 —LogInfo / LogWarn / LogError / LogDebugcallinglogWithLevelinternal/logger/markdown_logger.golines 197–214 —LogInfoMd / LogWarnMd / LogErrorMd / LogDebugMdcallinglogWithMarkdownLevelinternal/logger/server_file_logger.golines 158–176 —LogInfoWithServer / LogWarnWithServer / LogErrorWithServer / LogDebugWithServercallinglogWithLevelAndServerImpact Analysis
LogLevelconstant requires updating the quartet in all three files. The existinglogFuncsmap (file_logger.go:147) partially mitigates this for the inner dispatch, but the public wrappers still need manual updates.Refactoring Recommendations
Code-generate the wrappers using
go generate+ a small template. Each façade provides only its innerlogWithXxxfunction; the four public wrappers are emitted bygenerate. This is the highest-fidelity option if new levels are anticipated.Consolidate into a
LogFacadestruct with a single variadicLog(level, ...)method, replacing the four typed wrappers. Callers that currently rely onLogInfo(...)continue to work via thin aliases. This reduces the public surface while centralising level dispatch.Accept the pattern (lowest effort) —
logFuncsalready prevents switch-on-level duplication inside each helper; the remaining four wrappers per façade are very small. Document explicitly that adding aLogLevelrequires updating all three façades.Implementation Checklist
make agent-finishedto verify no regressionsParent Issue
See parent analysis report: #3685
Related to #3685