go.uber.org/yarpc@v1.72.1/api/transport/propagation.go (about)

     1  // Copyright (c) 2022 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package transport
    22  
    23  import (
    24  	"context"
    25  	"time"
    26  
    27  	"github.com/opentracing/opentracing-go"
    28  	"github.com/opentracing/opentracing-go/ext"
    29  	opentracinglog "github.com/opentracing/opentracing-go/log"
    30  )
    31  
    32  // CreateOpenTracingSpan creates a new context with a started span
    33  type CreateOpenTracingSpan struct {
    34  	Tracer        opentracing.Tracer
    35  	TransportName string
    36  	StartTime     time.Time
    37  	ExtraTags     opentracing.Tags
    38  }
    39  
    40  // Do creates a new context that has a reference to the started span.
    41  // This should be called before a Outbound makes a call
    42  func (c *CreateOpenTracingSpan) Do(
    43  	ctx context.Context,
    44  	req *Request,
    45  ) (context.Context, opentracing.Span) {
    46  	var parent opentracing.SpanContext
    47  	if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
    48  		parent = parentSpan.Context()
    49  	}
    50  
    51  	tags := opentracing.Tags{
    52  		"rpc.caller":    req.Caller,
    53  		"rpc.service":   req.Service,
    54  		"rpc.encoding":  req.Encoding,
    55  		"rpc.transport": c.TransportName,
    56  	}
    57  	for k, v := range c.ExtraTags {
    58  		tags[k] = v
    59  	}
    60  	span := c.Tracer.StartSpan(
    61  		req.Procedure,
    62  		opentracing.StartTime(c.StartTime),
    63  		opentracing.ChildOf(parent),
    64  		tags,
    65  	)
    66  	ext.PeerService.Set(span, req.Service)
    67  	ext.SpanKindRPCClient.Set(span)
    68  
    69  	ctx = opentracing.ContextWithSpan(ctx, span)
    70  	return ctx, span
    71  }
    72  
    73  // ExtractOpenTracingSpan derives a context and associated span
    74  type ExtractOpenTracingSpan struct {
    75  	ParentSpanContext opentracing.SpanContext
    76  	Tracer            opentracing.Tracer
    77  	TransportName     string
    78  	StartTime         time.Time
    79  	ExtraTags         opentracing.Tags
    80  }
    81  
    82  // Do derives a new context from SpanContext. The created context has a
    83  // reference to the started span. parentSpanCtx may be nil.
    84  // This should be called before a Inbound handles a request
    85  func (e *ExtractOpenTracingSpan) Do(
    86  	ctx context.Context,
    87  	req *Request,
    88  ) (context.Context, opentracing.Span) {
    89  	tags := opentracing.Tags{
    90  		"rpc.caller":    req.Caller,
    91  		"rpc.service":   req.Service,
    92  		"rpc.encoding":  req.Encoding,
    93  		"rpc.transport": e.TransportName,
    94  	}
    95  	for k, v := range e.ExtraTags {
    96  		tags[k] = v
    97  	}
    98  	span := e.Tracer.StartSpan(
    99  		req.Procedure,
   100  		opentracing.StartTime(e.StartTime),
   101  		tags,
   102  		// parentSpanCtx may be nil
   103  		// this implies ChildOf
   104  		ext.RPCServerOption(e.ParentSpanContext),
   105  	)
   106  	ext.PeerService.Set(span, req.Caller)
   107  	ext.SpanKindRPCServer.Set(span)
   108  
   109  	ctx = opentracing.ContextWithSpan(ctx, span)
   110  	return ctx, span
   111  }
   112  
   113  // UpdateSpanWithErr sets the error tag on a span, if an error is given.
   114  // Returns the given error
   115  func UpdateSpanWithErr(span opentracing.Span, err error) error {
   116  	if err != nil {
   117  		span.SetTag("error", true)
   118  		span.LogFields(opentracinglog.String("event", err.Error()))
   119  	}
   120  	return err
   121  }