github.com/cilium/cilium@v1.16.2/pkg/hubble/parser/seven/tracing.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package seven
     5  
     6  import (
     7  	"context"
     8  	"net/http"
     9  
    10  	"go.opentelemetry.io/otel/propagation"
    11  	"go.opentelemetry.io/otel/trace"
    12  
    13  	flowpb "github.com/cilium/cilium/api/v1/flow"
    14  	"github.com/cilium/cilium/pkg/proxy/accesslog"
    15  )
    16  
    17  // traceparentHeader is a HTTP header defined in the W3C Trace Context specification:
    18  // https://www.w3.org/TR/trace-context/
    19  // It identifies the incoming request in a tracing system and contains, among
    20  // other things, the trace ID.
    21  const traceparentHeader = "traceparent"
    22  
    23  func extractTraceContext(record *accesslog.LogRecord) *flowpb.TraceContext {
    24  	if record == nil {
    25  		return nil
    26  	}
    27  	switch {
    28  	case record.HTTP != nil:
    29  		traceID := traceIDFromHTTPHeader(record.HTTP.Headers)
    30  		if traceID == "" {
    31  			return nil
    32  		}
    33  		return &flowpb.TraceContext{
    34  			Parent: &flowpb.TraceParent{
    35  				TraceId: traceID,
    36  			},
    37  		}
    38  	case record.Kafka != nil:
    39  		// TODO
    40  		return nil
    41  	default:
    42  		return nil
    43  	}
    44  }
    45  
    46  func traceIDFromHTTPHeader(h http.Header) string {
    47  	if h.Get(traceparentHeader) == "" {
    48  		// return early if no trace parent header is present to avoid
    49  		// unnecessary processing and memory allocation
    50  		return ""
    51  	}
    52  
    53  	tc := propagation.TraceContext{}
    54  	sp := trace.SpanContextFromContext(
    55  		tc.Extract(
    56  			context.Background(),
    57  			propagation.HeaderCarrier(h),
    58  		),
    59  	)
    60  	if sp.HasTraceID() {
    61  		return sp.TraceID().String()
    62  	}
    63  	return ""
    64  }