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 }