github.com/blend/go-sdk@v1.20240719.1/tracing/r2trace/tracer.go (about) 1 /* 2 3 Copyright (c) 2024 - 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 opentracingExt "github.com/opentracing/opentracing-go/ext" 18 19 "github.com/blend/go-sdk/r2" 20 "github.com/blend/go-sdk/tracing" 21 ) 22 23 var ( 24 _ r2.Tracer = (*r2Tracer)(nil) 25 _ r2.TraceFinisher = (*r2TraceFinisher)(nil) 26 ) 27 28 // Tracer returns a request tracer that also injects span context into outgoing headers. 29 func Tracer(tracer opentracing.Tracer) r2.Tracer { 30 return &r2Tracer{tracer: tracer} 31 } 32 33 type r2Tracer struct { 34 tracer opentracing.Tracer 35 } 36 37 func (rt r2Tracer) Start(req *http.Request) r2.TraceFinisher { 38 startOptions := []opentracing.StartSpanOption{ 39 opentracingExt.SpanKindRPCClient, 40 opentracing.Tag{Key: tracing.TagKeySpanType, Value: tracing.SpanTypeHTTP}, 41 opentracing.Tag{Key: tracing.TagKeyResourceName, Value: r2.GetRawURLParameterized(req)}, 42 opentracing.Tag{Key: tracing.TagKeyHTTPMethod, Value: strings.ToUpper(req.Method)}, 43 opentracing.Tag{Key: tracing.TagKeyHTTPURL, Value: req.URL.String()}, 44 tracing.TagMeasured(), 45 opentracing.StartTime(time.Now().UTC()), 46 } 47 span, ctx := tracing.StartSpanFromContext(req.Context(), rt.tracer, tracing.OperationHTTPRequestOutgoing, startOptions...) 48 *req = *req.WithContext(ctx) 49 50 if req.Header == nil { 51 req.Header = make(http.Header) 52 } 53 _ = rt.tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header)) 54 return r2TraceFinisher{span: span} 55 } 56 57 type r2TraceFinisher struct { 58 span opentracing.Span 59 } 60 61 func (rtf r2TraceFinisher) Finish(req *http.Request, res *http.Response, ts time.Time, err error) { 62 if rtf.span == nil { 63 return 64 } 65 tracing.SpanError(rtf.span, err) 66 if res != nil { 67 rtf.span.SetTag(tracing.TagKeyHTTPCode, strconv.Itoa(res.StatusCode)) 68 } else { 69 rtf.span.SetTag(tracing.TagKeyHTTPCode, http.StatusInternalServerError) 70 } 71 rtf.span.Finish() 72 }