...

Source file src/github.com/go-openapi/runtime/client/opentracing.go

Documentation: github.com/go-openapi/runtime/client

     1  package client
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/go-openapi/strfmt"
     8  	"github.com/opentracing/opentracing-go"
     9  	"github.com/opentracing/opentracing-go/ext"
    10  	"github.com/opentracing/opentracing-go/log"
    11  
    12  	"github.com/go-openapi/runtime"
    13  )
    14  
    15  type tracingTransport struct {
    16  	transport runtime.ClientTransport
    17  	host      string
    18  	opts      []opentracing.StartSpanOption
    19  }
    20  
    21  func newOpenTracingTransport(transport runtime.ClientTransport, host string, opts []opentracing.StartSpanOption,
    22  ) runtime.ClientTransport {
    23  	return &tracingTransport{
    24  		transport: transport,
    25  		host:      host,
    26  		opts:      opts,
    27  	}
    28  }
    29  
    30  func (t *tracingTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
    31  	if op.Context == nil {
    32  		return t.transport.Submit(op)
    33  	}
    34  
    35  	params := op.Params
    36  	reader := op.Reader
    37  
    38  	var span opentracing.Span
    39  	defer func() {
    40  		if span != nil {
    41  			span.Finish()
    42  		}
    43  	}()
    44  
    45  	op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
    46  		span = createClientSpan(op, req.GetHeaderParams(), t.host, t.opts)
    47  		return params.WriteToRequest(req, reg)
    48  	})
    49  
    50  	op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
    51  		if span != nil {
    52  			code := response.Code()
    53  			ext.HTTPStatusCode.Set(span, uint16(code))
    54  			if code >= 400 {
    55  				ext.Error.Set(span, true)
    56  			}
    57  		}
    58  		return reader.ReadResponse(response, consumer)
    59  	})
    60  
    61  	submit, err := t.transport.Submit(op)
    62  	if err != nil && span != nil {
    63  		ext.Error.Set(span, true)
    64  		span.LogFields(log.Error(err))
    65  	}
    66  	return submit, err
    67  }
    68  
    69  func createClientSpan(op *runtime.ClientOperation, header http.Header, host string,
    70  	opts []opentracing.StartSpanOption) opentracing.Span {
    71  	ctx := op.Context
    72  	span := opentracing.SpanFromContext(ctx)
    73  
    74  	if span != nil {
    75  		opts = append(opts, ext.SpanKindRPCClient)
    76  		span, _ = opentracing.StartSpanFromContextWithTracer(
    77  			ctx, span.Tracer(), operationName(op), opts...)
    78  
    79  		ext.Component.Set(span, "go-openapi")
    80  		ext.PeerHostname.Set(span, host)
    81  		span.SetTag("http.path", op.PathPattern)
    82  		ext.HTTPMethod.Set(span, op.Method)
    83  
    84  		_ = span.Tracer().Inject(
    85  			span.Context(),
    86  			opentracing.HTTPHeaders,
    87  			opentracing.HTTPHeadersCarrier(header))
    88  
    89  		return span
    90  	}
    91  	return nil
    92  }
    93  
    94  func operationName(op *runtime.ClientOperation) string {
    95  	if op.ID != "" {
    96  		return op.ID
    97  	}
    98  	return fmt.Sprintf("%s_%s", op.Method, op.PathPattern)
    99  }
   100  

View as plain text