Skip to content

Refactor: Eliminate session-aware logging if/else duplication with helper functions#944

Draft
Claude wants to merge 2 commits intomainfrom
claude/refactor-session-logging-duplication
Draft

Refactor: Eliminate session-aware logging if/else duplication with helper functions#944
Claude wants to merge 2 commits intomainfrom
claude/refactor-session-logging-duplication

Conversation

@Claude
Copy link
Contributor

@Claude Claude AI commented Feb 14, 2026

Three logging functions in internal/launcher/log_helpers.go contained identical if/else branching to handle session-aware vs non-session logging, resulting in ~30 lines of duplicated conditional logic.

Changes

  • Added inline helper functions following the repository's pattern of placing helpers in the same file:

    • tripleLogInfoWithSession(): Encapsulates file/stdout/debug logging with session branching
    • debugLogWithSession(): Handles debug-only logging with session branching
  • Refactored 3 functions to use helpers, eliminating duplicate branching:

    • logLaunchStart()
    • logTimeoutError()
    • logLaunchSuccess()

Example

Before:

func (l *Launcher) logLaunchSuccess(serverID, sessionID string) {
    if sessionID != "" {
        logger.LogInfoWithServer(serverID, "backend", "Successfully launched... session=%s", serverID, sessionID)
        log.Printf("[LAUNCHER] Successfully launched: %s (session: %s)", serverID, sessionID)
        logLauncher.Printf("Session connection established: serverID=%s, sessionID=%s", serverID, sessionID)
    } else {
        logger.LogInfoWithServer(serverID, "backend", "Successfully launched: %s", serverID)
        log.Printf("[LAUNCHER] Successfully launched: %s", serverID)
        logLauncher.Printf("Connection established: serverID=%s", serverID)
    }
}

After:

func (l *Launcher) logLaunchSuccess(serverID, sessionID string) {
    tripleLogInfoWithSession(
        serverID, sessionID,
        "Successfully launched MCP backend server for session: server=%s, session=%s",
        "Successfully launched MCP backend server: %s",
        "Successfully launched: %s (session: %s)",
        "Successfully launched: %s",
        "Session connection established: serverID=%s, sessionID=%s",
        "Connection established: serverID=%s",
        []interface{}{serverID, sessionID},
        []interface{}{serverID},
        []interface{}{serverID, sessionID},
        []interface{}{serverID},
        []interface{}{serverID, sessionID},
        []interface{}{serverID},
    )
}

Log output remains identical. Session-aware branching logic is now centralized in reusable helpers.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build2301924257/b275/launcher.test /tmp/go-build2301924257/b275/launcher.test -test.testlogfile=/tmp/go-build2301924257/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 s#^versions/##; s#^v#node/v#; \#system# !d; 1_ nfig/composer/ve--abbrev-ref base64 -d ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet git /usr/bin/dirname --abbrev-ref HEAD x_amd64/link dirname (dns block)
    • Triggering command: /tmp/go-build2359477819/b275/launcher.test /tmp/go-build2359477819/b275/launcher.test -test.testlogfile=/tmp/go-build2359477819/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true NVM_DIR=/home/REDACTED/.nvm -v /usr/bin/gcc index($0, NVM/usr/libexec/docker/cli-plugins/docker-compose git de/node/bin/git gcc -###�� -x c (dns block)
    • Triggering command: /tmp/go-build4148141444/b275/launcher.test /tmp/go-build4148141444/b275/launcher.test -test.testlogfile=/tmp/go-build4148141444/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ; git /usr/bin/git --abbrev-ref HEAD cal/bin/git git rev-�� --abbrev-ref HEAD docker-buildx --abbrev-ref HEAD ache/uv/0.10.2/x86_64/git tf "%s%s", sep, $0; sep=RS } (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build2301924257/b260/config.test /tmp/go-build2301924257/b260/config.test -test.testlogfile=/tmp/go-build2301924257/b260/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD (dns block)
    • Triggering command: /tmp/go-build726308285/b264/config.test /tmp/go-build726308285/b264/config.test -test.testlogfile=/tmp/go-build726308285/b264/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.short=true /usr/bin/git base64 64/pkg/tool/linux_amd64/compile 64/pkg/tool/linusleep git /usr/bin/git 64/pkg/tool/linux_amd64/compile dock�� else if (a[i] --abbrev-ref git /usr/bin/grep --abbrev-ref HEAD /usr/bin/base64 tf "%s%s", sep, $0; sep=RS } (dns block)
    • Triggering command: /tmp/go-build758265063/b260/config.test /tmp/go-build758265063/b260/config.test -test.testlogfile=/tmp/go-build758265063/b260/testlog.txt -test.paniconexit0 -test.timeout=10m0s t \t base64 tnet/tools/git ache/go/1.25.7/xecho git /usr/bin/tail base64 -d it tail /usr/bin/tail 1 base64 /usr/bin/base64 tail (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build2301924257/b275/launcher.test /tmp/go-build2301924257/b275/launcher.test -test.testlogfile=/tmp/go-build2301924257/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 s#^versions/##; s#^v#node/v#; \#system# !d; 1_ nfig/composer/ve--abbrev-ref base64 -d ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet git /usr/bin/dirname --abbrev-ref HEAD x_amd64/link dirname (dns block)
    • Triggering command: /tmp/go-build2359477819/b275/launcher.test /tmp/go-build2359477819/b275/launcher.test -test.testlogfile=/tmp/go-build2359477819/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true NVM_DIR=/home/REDACTED/.nvm -v /usr/bin/gcc index($0, NVM/usr/libexec/docker/cli-plugins/docker-compose git de/node/bin/git gcc -###�� -x c (dns block)
    • Triggering command: /tmp/go-build4148141444/b275/launcher.test /tmp/go-build4148141444/b275/launcher.test -test.testlogfile=/tmp/go-build4148141444/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ; git /usr/bin/git --abbrev-ref HEAD cal/bin/git git rev-�� --abbrev-ref HEAD docker-buildx --abbrev-ref HEAD ache/uv/0.10.2/x86_64/git tf "%s%s", sep, $0; sep=RS } (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build2301924257/b275/launcher.test /tmp/go-build2301924257/b275/launcher.test -test.testlogfile=/tmp/go-build2301924257/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 s#^versions/##; s#^v#node/v#; \#system# !d; 1_ nfig/composer/ve--abbrev-ref base64 -d ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet git /usr/bin/dirname --abbrev-ref HEAD x_amd64/link dirname (dns block)
    • Triggering command: /tmp/go-build2359477819/b275/launcher.test /tmp/go-build2359477819/b275/launcher.test -test.testlogfile=/tmp/go-build2359477819/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true NVM_DIR=/home/REDACTED/.nvm -v /usr/bin/gcc index($0, NVM/usr/libexec/docker/cli-plugins/docker-compose git de/node/bin/git gcc -###�� -x c (dns block)
    • Triggering command: /tmp/go-build4148141444/b275/launcher.test /tmp/go-build4148141444/b275/launcher.test -test.testlogfile=/tmp/go-build4148141444/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ; git /usr/bin/git --abbrev-ref HEAD cal/bin/git git rev-�� --abbrev-ref HEAD docker-buildx --abbrev-ref HEAD ache/uv/0.10.2/x86_64/git tf "%s%s", sep, $0; sep=RS } (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build2301924257/b284/mcp.test /tmp/go-build2301924257/b284/mcp.test -test.testlogfile=/tmp/go-build2301924257/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD 64/pkg/tool/linux_amd64/link E=3 nwind-tables ache/Python/3.12--abbrev-ref 64/pkg/tool/linuHEAD -d ncher.test git ortcfg.link #; HEAD 86_64/git MCp-3kFl8D2k02Xijt/aVOK8Uts-pP0nQ-KRI0F/UWIyND62jcK9CRxbr1K5 (dns block)
    • Triggering command: /tmp/go-build726308285/b288/mcp.test /tmp/go-build726308285/b288/mcp.test -test.testlogfile=/tmp/go-build726308285/b288/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.short=true ache/go/1.25.7/x. sed /usr/sbin/bash s/^\([0-9]\)/v\1base64 m/nvm.sh /usr/bin/base64 bash /usr�� --version base64 /usr/bin/echo ache/go/1.25.7/x/usr/bin/runc.original sed it echo (dns block)
    • Triggering command: /tmp/go-build758265063/b284/mcp.test /tmp/go-build758265063/b284/mcp.test -test.testlogfile=/tmp/go-build758265063/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s rev-�� --abbrev-ref HEAD 2a51a1f2909b033e-d nner/.nvm git /usr/local/.ghcup/bin/git base64 -d de/node/bin/git git x_amd64/link --abbrev-ref HEAD duplication x_amd64/link (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>[duplicate-code] Session-Aware Logging Branching Duplication</issue_title>
<issue_description># 🔍 Duplicate Code Pattern: Session-Aware Logging Branching

Part of duplicate code analysis: #929

Summary

Multiple logging functions in internal/launcher/log_helpers.go contain identical if/else branching logic to handle sessionID-aware logging. This pattern appears in 3 functions with nearly identical structure, leading to ~45 lines of duplicated conditional logic.

Duplication Details

Pattern: Conditional Session Logging

  • Severity: High

  • Occurrences: 3 functions

  • Locations:

    • internal/launcher/log_helpers.go lines 31-44 (logLaunchStart)
    • internal/launcher/log_helpers.go lines 95-106 (logTimeoutError)
    • internal/launcher/log_helpers.go lines 109-119 (logLaunchSuccess)
  • Code Sample (from logLaunchStart):

    func (l *Launcher) logLaunchStart(serverID, sessionID string, serverCfg *config.ServerConfig, isDirectCommand bool) {
        if sessionID != "" {
            logger.LogInfoWithServer(serverID, "backend", "Launching MCP backend server for session: server=%s, session=%s, command=%s, args=%v", serverID, sessionID, serverCfg.Command, sanitize.SanitizeArgs(serverCfg.Args))
            log.Printf("[LAUNCHER] Starting MCP server for session: %s (session: %s)", serverID, sessionID)
            logLauncher.Printf("Launching new session server: serverID=%s, sessionID=%s, command=%s", serverID, sessionID, serverCfg.Command)
        } else {
            logger.LogInfoWithServer(serverID, "backend", "Launching MCP backend server: %s, command=%s, args=%v", serverID, serverCfg.Command, sanitize.SanitizeArgs(serverCfg.Args))
            log.Printf("[LAUNCHER] Starting MCP server: %s", serverID)
            logLauncher.Printf("Launching new server: serverID=%s, command=%s, inContainer=%v, isDirectCommand=%v",
                serverID, serverCfg.Command, l.runningInContainer, isDirectCommand)
        }
        log.Printf("[LAUNCHER] Command: %s", serverCfg.Command)
        log.Printf("[LAUNCHER] Args: %v", sanitize.SanitizeArgs(serverCfg.Args))
    }
  • Similar Pattern (from logLaunchSuccess):

    func (l *Launcher) logLaunchSuccess(serverID, sessionID string) {
        if sessionID != "" {
            logger.LogInfoWithServer(serverID, "backend", "Successfully launched MCP backend server for session: server=%s, session=%s", serverID, sessionID)
            log.Printf("[LAUNCHER] Successfully launched: %s (session: %s)", serverID, sessionID)
            logLauncher.Printf("Session connection established: serverID=%s, sessionID=%s", serverID, sessionID)
        } else {
            logger.LogInfoWithServer(serverID, "backend", "Successfully launched MCP backend server: %s", serverID)
            log.Printf("[LAUNCHER] Successfully launched: %s", serverID)
            logLauncher.Printf("Connection established: serverID=%s", serverID)
        }
    }

Impact Analysis

  • Maintainability: High impact - Changes to session handling must be replicated across 3 functions, increasing risk of inconsistent behavior
  • Bug Risk: Medium-High - If one function is updated for session handling but others aren't, logging behavior becomes inconsistent
  • Code Bloat: ~45 lines of duplicated branching logic
  • Testing Complexity: Each function requires separate test cases for session vs non-session scenarios

Refactoring Recommendations

Option 1: Extract Session-Aware Logging Helper (Recommended)

  • Extract common pattern to: internal/launcher/session_logger.go
  • Estimated effort: 2-3 hours
  • Benefits:
    • Single source of truth for session-aware logging
    • Consistent logging format across all launcher operations
    • Easier to modify logging behavior
  • Implementation:
    // sessionLogger wraps triple logging with session awareness
    type sessionLogger struct {
        serverID string
        sessionID string
    }
    
    func (sl *sessionLogger) logInfo(category, fileMsg, stdoutMsg, debugMsg string, args ...interface{}) {
        if sl.sessionID != "" {
            logger.LogInfoWithServer(sl.serverID, category, fileMsg+" for session: session="+sl.sessionID, args...)
            log.Printf(stdoutMsg+" (session: "+sl.sessionID+")", args...)
            logLauncher.Printf(debugMsg+", sessionID="+sl.sessionID, args...)
        } else {
            logger.LogInfoWithServer(sl.serverID, category, fileMsg, args...)
            log.Printf(stdoutMsg, args...)
            logLauncher.Printf(debugMsg, args...)
        }
    }

Option 2: Use sessionSuffix() More Consistently

  • Leverage existing sessionSuffix() helper more broadly
  • Estimated effort: 1-2 hours
  • Benefits: Simpler, less refactoring needed
  • Trade-off: Still requires manual if/else in some cases

Implementation Che...

…lper functions

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Refactor duplicate session-aware logging logic Refactor: Eliminate session-aware logging if/else duplication with helper functions Feb 14, 2026
@Claude Claude AI requested a review from lpcox February 14, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Session-Aware Logging Branching Duplication

2 participants