Skip to content

[duplicate-code] Duplicate Code Pattern: Logger Level Wrapper Functions #4843

@github-actions

Description

@github-actions

Part of duplicate code analysis: #4842

Summary

After the file-splitting refactor, three logger files each define four nearly-identical thin-wrapper functions following the exact same structural pattern. While makeLevelLogger and makeServerLevelLogger already abstract the underlying dispatch logic, the public API wrapper layer still repeats ~12–18 lines per file across 3 files (~40 lines total).

Duplication Details

Pattern: 4-function level-wrapper block

  • Severity: Medium
  • Occurrences: 3 identical blocks (12 functions total)
  • Locations:
    • internal/logger/file_logger.go (lines 129–145) — LogInfo, LogWarn, LogError, LogDebug
    • internal/logger/markdown_logger.go (lines 197–215) — LogInfoMd, LogWarnMd, LogErrorMd, LogDebugMd
    • internal/logger/server_file_logger.go (lines 165–183) — LogInfoWithServer, LogWarnWithServer, LogErrorWithServer, LogDebugWithServer

Repeated structure (example from file_logger.go):

var (
    logInfo  = makeLevelLogger(logWithLevel, LogLevelInfo)
    logWarn  = makeLevelLogger(logWithLevel, LogLevelWarn)
    logError = makeLevelLogger(logWithLevel, LogLevelError)
    logDebug = makeLevelLogger(logWithLevel, LogLevelDebug)
)

// LogInfo logs an informational message.
func LogInfo(category, format string, args ...interface{}) {
    logInfo(category, format, args...)
}
// ... (3 more identical-structure functions)

Same block repeats in markdown_logger.go and server_file_logger.go with different names and dispatch functions.

Impact Analysis

  • Maintainability: Adding a new log level (e.g., LogTrace) requires adding 4 lines to 3 files (12 edits total) instead of one place.
  • Bug Risk: Low — the underlying makeLevelLogger factory and the logFuncs map are the single source of truth for dispatch. The wrappers are passive.
  • Code Bloat: ~40 lines of repeated boilerplate across logger files.

Refactoring Recommendations

  1. Accept as-is (recommended short-term)
    The var (logInfo = makeLevelLogger(...)) vars already abstract the logic. The thin wrappers are idiomatic Go API design providing named, documented public functions. Further reduction would harm API discoverability without meaningful maintainability gain.

  2. Consider code generation (longer-term)
    If log levels are frequently added/changed, a go:generate step could emit the wrapper blocks from a level list, ensuring all files stay in sync. Estimated effort: 2–4 hours.

Implementation Checklist

  • Review whether log levels are expected to grow
  • If yes, consider go:generate for wrapper blocks
  • If no, document the pattern so future contributors know it is intentional

Parent Issue

See parent analysis report: #4842
Related to #4842

Generated by Duplicate Code Detector · ● 2.6M ·

  • expires on May 7, 2026, 6:25 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions