Skip to content

[duplicate-code] Duplicate Code Pattern: Log Level Dispatch Quad-Functions in Logger Package #1883

@github-actions

Description

@github-actions

Part of duplicate code analysis: #1882

Summary

Four logger files (file_logger.go, server_file_logger.go, markdown_logger.go, rpc_logger.go) each independently implement near-identical sets of four public wrapper functions (Info/Warn/Error/Debug). Every new log level requires updating all four files identically.

Duplication Details

Pattern: Log Level Quad-Function Sets

  • Severity: High
  • Occurrences: 4 files × 4 wrappers = 16+ wrapper functions
  • Locations:
    • internal/logger/file_logger.go (LogInfo/Warn/Error/Debug → logWithLevel)
    • internal/logger/server_file_logger.go (LogInfoWithServer/… → logWithLevelAndServer)
    • internal/logger/markdown_logger.go (markdown variants)
    • internal/logger/rpc_logger.go (lines 62–135, RPC variants)

Code Sample (file_logger.go):

func LogInfo(category, format string, args ...any) {
    logWithLevel(LogLevelInfo, category, format, args...)
}
func LogWarn(category, format string, args ...any) {
    logWithLevel(LogLevelWarn, category, format, args...)
}
func LogError(category, format string, args ...any) {
    logWithLevel(LogLevelError, category, format, args...)
}
func LogDebug(category, format string, args ...any) {
    logWithLevel(LogLevelDebug, category, format, args...)
}

Same structure repeated in server_file_logger.go:

func LogInfoWithServer(serverID, category, format string, args ...any) {
    logWithLevelAndServer(serverID, LogLevelInfo, category, format, args...)
}
// ... Warn/Error/Debug variants identical

Impact Analysis

  • Maintainability: Adding a LogTrace level requires touching 4+ files with identical 1-liner changes
  • Bug Risk: Divergence risk — one file may gain a feature (e.g., rate limiting) that others miss
  • Code Bloat: ~40 lines of functionally identical wrapper boilerplate

Refactoring Recommendations

  1. Extract a shared dispatcher — introduce a dispatchLog(level LogLevel, category, format string, args ...any) function in a shared logger utility, then have each logger variant delegate to it with a logger-specific sink function.
  2. Use a logFuncs map — the logWithLevelAndServer already uses a logFuncs map; generalise this pattern as the single dispatch mechanism and eliminate per-level wrapper functions where possible.
  3. Code generation — if the 1-liner wrappers must be public API, use go generate with a template to produce them consistently.

Implementation Checklist

  • Audit all four logger files for the full quad-function sets
  • Design a shared dispatch signature compatible with all variants
  • Refactor one file at a time, running make test between each
  • Verify no public API signatures change (wrappers can remain as thin pass-throughs)
  • Update AGENTS.md logger section if naming conventions change

Parent Issue

See parent analysis report: #1882
Related to #1882

Generated by Duplicate Code Detector ·

  • expires on Mar 21, 2026, 2:57 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions