Skip to content

[duplicate-code] Duplicate Code Pattern: Log Line Formatting in FileLogger and ServerFileLogger #1825

@github-actions

Description

@github-actions

Part of duplicate code analysis: #1824

Summary

The log line formatting logic (timestamp creation, message formatting, and log line construction) is duplicated identically across FileLogger.Log() and ServerFileLogger.Log(). Any change to the log format must be applied in both places, risking divergence.

Duplication Details

Pattern: Identical log line construction in two logger types

  • Severity: Medium
  • Occurrences: 2 identical blocks
  • Locations:
    • internal/logger/file_logger.go (lines ~81–98)
    • internal/logger/server_file_logger.go (lines ~98–125)

File 1 — file_logger.go:

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)
if fl.logFile != nil {
    if err := fl.logFile.Sync(); err != nil {
        log.Printf("WARNING: Failed to sync log file: %v", err)
    }
}

File 2 — server_file_logger.go:

timestamp := time.Now().UTC().Format(time.RFC3339)
message := fmt.Sprintf(format, args...)
logLine := fmt.Sprintf("[%s] [%s] [%s] %s", timestamp, level, category, message)
logger.Println(logLine)
sfl.mu.RLock()
if file, exists := sfl.files[serverID]; exists {
    if err := file.Sync(); err != nil {
        log.Printf("WARNING: Failed to sync log file for server %s: %v", serverID, err)
    }
}
sfl.mu.RUnlock()

Impact Analysis

  • Maintainability: Log format changes must be applied in 2 places; easy to miss one
  • Bug Risk: Low currently, but divergence is likely over time (e.g., adding log fields)
  • Code Bloat: Minor — ~6 duplicated lines

Refactoring Recommendations

  1. Extract shared formatting helpers in internal/logger/common.go or a new internal/logger/format.go:
    func formatLogLine(level LogLevel, category, format string, args ...interface{}) string {
        timestamp := time.Now().UTC().Format(time.RFC3339)
        message := fmt.Sprintf(format, args...)
        return fmt.Sprintf("[%s] [%s] [%s] %s", timestamp, level, category, message)
    }
    Then both loggers call formatLogLine(...) and just Println the result.

Implementation Checklist

  • Review duplication findings
  • Extract formatLogLine helper into internal/logger/common.go
  • Update FileLogger.Log() to use the helper
  • Update ServerFileLogger.Log() to use the helper
  • Run make test to verify no regressions
  • Run make agent-finished before completing

Parent Issue

See parent analysis report: #1824
Related to #1824

Generated by Duplicate Code Detector ·

  • expires on Mar 20, 2026, 2:58 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