Skip to content

[duplicate-code] Duplicate Code Pattern: Markdown Logger Wrapper Functions #318

@github-actions

Description

@github-actions

🔍 Duplicate Code Pattern: Markdown Logger Wrapper Functions

Part of duplicate code analysis: #316

Summary

Four nearly identical wrapper functions (LogInfoMd, LogWarnMd, LogErrorMd, LogDebugMd) with the same structure in the markdown logger. Each function is 12-15 lines with identical logic except for the log level parameter, resulting in 48+ lines of duplicated code.

Duplication Details

Pattern: Markdown Logger Level Wrappers

  • Severity: MEDIUM
  • Occurrences: 4 identical functions
  • Total Duplicated Lines: 48+ lines (12-15 per function)
  • Location: internal/logger/markdown_logger.go (lines 153-206)

Code Sample:

// Pattern repeated for Info, Warn, Error, Debug levels:

func LogInfoMd(category, format string, args ...interface{}) {
    LogInfo(category, format, args...)  // Call regular logger
    globalMarkdownMu.RLock()
    defer globalMarkdownMu.RUnlock()
    if globalMarkdownLogger != nil {
        globalMarkdownLogger.Log(LogLevelInfo, category, format, args...)
    }
}

func LogWarnMd(category, format string, args ...interface{}) {
    LogWarn(category, format, args...)  // Call regular logger
    globalMarkdownMu.RLock()
    defer globalMarkdownMu.RUnlock()
    if globalMarkdownLogger != nil {
        globalMarkdownLogger.Log(LogLevelWarn, category, format, args...)
    }
}

// LogErrorMd and LogDebugMd follow identical pattern

Impact Analysis

  • Maintainability: Any change to wrapper logic (e.g., adding metrics, changing locking strategy) requires updating 4 identical functions
  • Bug Risk: HIGH - If a concurrency bug or logging issue is found, all 4 functions must be fixed identically
  • Code Bloat: 48 lines of nearly identical code in a critical logging subsystem
  • Cognitive Load: Developers must understand 4 separate functions that do essentially the same thing

Refactoring Recommendations

1. Extract Generic Helper Function (RECOMMENDED)

  • Approach: Create single function that accepts log level parameter
  • Implementation:
    // logToMarkdown is a helper that logs to both standard and markdown loggers
    func logToMarkdown(level LogLevel, category, format string, args ...interface{}) {
        // Call appropriate standard logger based on level
        switch level {
        case LogLevelInfo:
            LogInfo(category, format, args...)
        case LogLevelWarn:
            LogWarn(category, format, args...)
        case LogLevelError:
            LogError(category, format, args...)
        case LogLevelDebug:
            LogDebug(category, format, args...)
        }
        
        // Log to markdown if available
        globalMarkdownMu.RLock()
        defer globalMarkdownMu.RUnlock()
        if globalMarkdownLogger != nil {
            globalMarkdownLogger.Log(level, category, format, args...)
        }
    }
    
    // Public wrappers become one-liners:
    func LogInfoMd(category, format string, args ...interface{}) {
        logToMarkdown(LogLevelInfo, category, format, args...)
    }
    
    func LogWarnMd(category, format string, args ...interface{}) {
        logToMarkdown(LogLevelWarn, category, format, args...)
    }
    
    // Same for LogErrorMd, LogDebugMd
  • Estimated effort: 2 hours
  • Benefits:
    • Reduces code from 48+ lines to ~25 lines
    • Single implementation for all log levels
    • Easier to maintain and test
    • Clear separation of concerns

2. Alternative: Use Function Map

  • Approach: Map log levels to standard logger functions
  • Benefit: Even more compact, but slightly less readable
  • Estimated effort: 2 hours

Implementation Checklist

  • Review current usage of LogXxxMd functions
  • Create logToMarkdown helper function
  • Refactor 4 wrapper functions to use helper
  • Run existing tests to verify no regressions
  • Add unit test for the new helper function
  • Consider documenting this pattern in AGENTS.md
  • Update any documentation referencing these functions

Testing Considerations

  • Verify all 4 log levels work correctly with markdown logger
  • Test with and without global markdown logger initialized
  • Test concurrent access to ensure mutex behavior is preserved
  • Verify standard logger is still called for each level

Parent Issue

See parent analysis report: #316
Related to #316

AI generated by Duplicate Code Detector

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