github.com/blend/go-sdk@v1.20220411.3/tracing/r2trace/tracer.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package r2trace
     9  
    10  import (
    11  	"net/http"
    12  	"strconv"
    13  	"strings"
    14  	"time"
    15  
    16  	opentracing "github.com/opentracing/opentracing-go"
    17  
    18  	"github.com/blend/go-sdk/r2"
    19  	"github.com/blend/go-sdk/tracing"
    20  )
    21  
    22  var (
    23  	_ r2.Tracer        = (*r2Tracer)(nil)
    24  	_ r2.TraceFinisher = (*r2TraceFinisher)(nil)
    25  )
    26  
    27  // Tracer returns a request tracer that also injects span context into outgoing headers.
    28  func Tracer(tracer opentracing.Tracer) r2.Tracer {
    29  	return &r2Tracer{tracer: tracer}
    30  }
    31  
    32  type r2Tracer struct {
    33  	tracer opentracing.Tracer
    34  }
    35  
    36  func (rt r2Tracer) Start(req *http.Request) r2.TraceFinisher {
    37  	startOptions := []opentracing.StartSpanOption{
    38  		opentracing.Tag{Key: tracing.TagKeySpanType, Value: tracing.SpanTypeHTTP},
    39  		opentracing.Tag{Key: tracing.TagKeyResourceName, Value: r2.GetRawURLParameterized(req)},
    40  		opentracing.Tag{Key: tracing.TagKeyHTTPMethod, Value: strings.ToUpper(req.Method)},
    41  		opentracing.Tag{Key: tracing.TagKeyHTTPURL, Value: req.URL.String()},
    42  		tracing.TagMeasured(),
    43  		opentracing.StartTime(time.Now().UTC()),
    44  	}
    45  	span, ctx := tracing.StartSpanFromContext(req.Context(), rt.tracer, tracing.OperationHTTPRequest, startOptions...)
    46  	*req = *req.WithContext(ctx)
    47  
    48  	if req.Header == nil {
    49  		req.Header = make(http.Header)
    50  	}
    51  	_ = rt.tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
    52  	return r2TraceFinisher{span: span}
    53  }
    54  
    55  type r2TraceFinisher struct {
    56  	span opentracing.Span
    57  }
    58  
    59  func (rtf r2TraceFinisher) Finish(req *http.Request, res *http.Response, ts time.Time, err error) {
    60  	if rtf.span == nil {
    61  		return
    62  	}
    63  	tracing.SpanError(rtf.span, err)
    64  	if res != nil {
    65  		rtf.span.SetTag(tracing.TagKeyHTTPCode, strconv.Itoa(res.StatusCode))
    66  	} else {
    67  		rtf.span.SetTag(tracing.TagKeyHTTPCode, http.StatusInternalServerError)
    68  	}
    69  	rtf.span.Finish()
    70  }