github.com/blend/go-sdk@v1.20220411.3/tracing/webtrace/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 webtrace 9 10 import ( 11 "strconv" 12 "time" 13 14 opentracing "github.com/opentracing/opentracing-go" 15 16 "github.com/blend/go-sdk/tracing" 17 "github.com/blend/go-sdk/tracing/httptrace" 18 "github.com/blend/go-sdk/web" 19 ) 20 21 var ( 22 _ web.Tracer = (*webTracer)(nil) 23 _ web.TraceFinisher = (*webTraceFinisher)(nil) 24 _ web.ViewTracer = (*webTracer)(nil) 25 _ web.ViewTraceFinisher = (*webViewTraceFinisher)(nil) 26 ) 27 28 // Tracer returns a web tracer. 29 func Tracer(tracer opentracing.Tracer) web.Tracer { 30 return &webTracer{tracer: tracer} 31 } 32 33 type webTracer struct { 34 tracer opentracing.Tracer 35 } 36 37 func (wt webTracer) Start(ctx *web.Ctx) web.TraceFinisher { 38 var resource string 39 var extra []opentracing.StartSpanOption 40 if ctx.Route != nil { 41 resource = ctx.Route.String() 42 extra = append(extra, opentracing.Tag{Key: "http.route", Value: ctx.Route.String()}) 43 } else { 44 resource = ctx.Request.URL.Path 45 } 46 span, newReq := httptrace.StartHTTPSpan( 47 ctx.Context(), 48 wt.tracer, 49 ctx.Request, 50 resource, 51 ctx.RequestStarted, 52 extra..., 53 ) 54 ctx.Request = newReq 55 ctx.WithContext(newReq.Context()) 56 return &webTraceFinisher{span: span} 57 } 58 59 type webTraceFinisher struct { 60 span opentracing.Span 61 } 62 63 func (wtf webTraceFinisher) Finish(ctx *web.Ctx, err error) { 64 if wtf.span == nil { 65 return 66 } 67 tracing.SpanError(wtf.span, err) 68 wtf.span.SetTag(tracing.TagKeyHTTPCode, strconv.Itoa(ctx.Response.StatusCode())) 69 wtf.span.Finish() 70 } 71 72 func (wt webTracer) StartView(ctx *web.Ctx, vr *web.ViewResult) web.ViewTraceFinisher { 73 // set up basic start options (these are mostly tags). 74 startOptions := []opentracing.StartSpanOption{ 75 tracing.TagMeasured(), 76 opentracing.Tag{Key: tracing.TagKeyResourceName, Value: vr.ViewName}, 77 opentracing.Tag{Key: tracing.TagKeySpanType, Value: tracing.SpanTypeWeb}, 78 opentracing.StartTime(time.Now().UTC()), 79 } 80 // start the span. 81 span, _ := tracing.StartSpanFromContext(ctx.Context(), wt.tracer, tracing.OperationHTTPRender, startOptions...) 82 return &webViewTraceFinisher{span: span} 83 } 84 85 type webViewTraceFinisher struct { 86 span opentracing.Span 87 } 88 89 func (wvtf webViewTraceFinisher) FinishView(ctx *web.Ctx, vr *web.ViewResult, err error) { 90 if wvtf.span == nil { 91 return 92 } 93 tracing.SpanError(wvtf.span, err) 94 wvtf.span.Finish() 95 }