Skip to content

[duplicate-code] Duplicate Code Pattern: Structural Duplication in Tracing Span Factory Functions #7510

@github-actions

Description

@github-actions

Part of duplicate code analysis: #7509

Summary

The four Start*Span factory functions in internal/tracing/span_helpers.go share an identical structural skeleton — only the span name, log message, attributes, and span kind differ. This is 4 instances of the same ~10-line pattern, meeting the 3+ similar patterns threshold.

Duplication Details

Pattern: Repeated tracer.Start boilerplate across 4 span factory functions

  • Severity: Low
  • Occurrences: 4
  • Locations: internal/tracing/span_helpers.go (lines 36-86)
  • Code Sample:
// All four functions follow this identical skeleton:
func StartXxxSpan(ctx context.Context, tracer oteltrace.Tracer, <params>) (context.Context, oteltrace.Span) {
    logTracing.Printf("Starting X span: <fields>")
    return tracer.Start(ctx, "span.name",
        oteltrace.WithAttributes(<attrs>...),
        oteltrace.WithSpanKind(oteltrace.SpanKind<Kind>),
    )
}

Concrete instances:

  • StartToolCallSpan (line 36) – SpanKindInternal, 4 attributes
  • StartBackendExecuteSpan (line 51) – SpanKindClient, 2 attributes
  • StartDIFCPipelineSpan (line 64) – SpanKindInternal, 2 attributes
  • StartProxyForwardSpan (line 77) – SpanKindClient, 2 attributes

Impact Analysis

  • Maintainability: Every new span type requires copy-pasting the same structure; easy to omit the logTracing.Printf call or misconfigure SpanKind
  • Bug Risk: Low currently, but will increase as more span types are added
  • Code Bloat: ~40 lines that could be reduced to ~10 with a shared private helper

Refactoring Recommendations

  1. Extract a private startSpan helper

    // startSpan is the shared inner implementation used by all public Start*Span helpers.
    func startSpan(ctx context.Context, tracer oteltrace.Tracer, spanName string, kind oteltrace.SpanKind, attrs ...attribute.KeyValue) (context.Context, oteltrace.Span) {
        return tracer.Start(ctx, spanName,
            oteltrace.WithAttributes(attrs...),
            oteltrace.WithSpanKind(kind),
        )
    }

    Public wrappers then delegate to it, keeping their log lines and specific attribute construction.

  2. Location: internal/tracing/span_helpers.go

  3. Estimated effort: ~1 hour

  4. Benefits: New span types become one-liners; SpanKind is harder to misconfigure; consistent log format

Implementation Checklist

  • Add private startSpan helper in span_helpers.go
  • Refactor the four Start*Span functions to delegate to it
  • Verify existing tests still pass (make test)
  • No behavioural change expected

Parent Issue

See parent analysis report: #7509
Related to #7509

Generated by Duplicate Code Detector · 1.9K AIC · ⊞ 35.7K ·

  • expires on Jun 21, 2026, 3:49 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