github.com/iotexproject/iotex-core@v1.14.1-rc1/pkg/tracer/tracer.go (about)

     1  package tracer
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"go.opentelemetry.io/otel"
     7  	"go.opentelemetry.io/otel/attribute"
     8  	"go.opentelemetry.io/otel/exporters/jaeger"
     9  	"go.opentelemetry.io/otel/sdk/resource"
    10  	tracesdk "go.opentelemetry.io/otel/sdk/trace"
    11  	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
    12  
    13  	"github.com/iotexproject/iotex-core/pkg/version"
    14  )
    15  
    16  const (
    17  	_service = "iotex-tracer"
    18  )
    19  
    20  // Config is the config for tracer
    21  type Config struct {
    22  	// ServiceName customize service name
    23  	ServiceName string `yaml:"serviceName"`
    24  	// EndPoint the jaeger endpoint
    25  	EndPoint string `yaml:"endpoint"`
    26  	// InstanceID MUST be unique for each instance of the same
    27  	InstanceID string `yaml:"instanceID"`
    28  	//SamplingRatio customize sampling ratio
    29  	//ratio >= 1 will always sample (default),< 0 are treated as zero will no sample
    30  	// if you set this to .5, half of traces will be sampled
    31  	SamplingRatio string `yaml:"samplingRatio"`
    32  }
    33  
    34  // Option the tracer provider option
    35  type Option func(ops *optionParams) error
    36  
    37  type optionParams struct {
    38  	serviceName   string
    39  	endpoint      string //the jaeger endpoint
    40  	instanceID    string //Note: MUST be unique for each instance of the same
    41  	samplingRatio string
    42  }
    43  
    44  // WithServiceName defines service name
    45  func WithServiceName(name string) Option {
    46  	return func(ops *optionParams) error {
    47  		ops.serviceName = name
    48  		return nil
    49  	}
    50  }
    51  
    52  // WithEndpoint defines the full URL to the Jaeger HTTP Thrift collector
    53  func WithEndpoint(endpoint string) Option {
    54  	return func(ops *optionParams) error {
    55  		ops.endpoint = endpoint
    56  		return nil
    57  	}
    58  }
    59  
    60  // WithInstanceID defines the instance id
    61  func WithInstanceID(instanceID string) Option {
    62  	return func(ops *optionParams) error {
    63  		ops.instanceID = instanceID
    64  		return nil
    65  	}
    66  }
    67  
    68  // WithSamplingRatio defines the sampling ratio
    69  func WithSamplingRatio(samplingRatio string) Option {
    70  	return func(ops *optionParams) error {
    71  		ops.samplingRatio = samplingRatio
    72  		return nil
    73  	}
    74  }
    75  
    76  // NewProvider create an instance of tracer provider
    77  func NewProvider(opts ...Option) (*tracesdk.TracerProvider, error) {
    78  	var (
    79  		err                           error
    80  		ops                           optionParams
    81  		trackerTracerProviderOption   []tracesdk.TracerProviderOption
    82  		jaegerCollectorEndpointOption []jaeger.CollectorEndpointOption
    83  	)
    84  	for _, opt := range opts {
    85  		if err = opt(&ops); err != nil {
    86  			return nil, err
    87  		}
    88  	}
    89  	if ops.endpoint != "" {
    90  		jaegerCollectorEndpointOption = append(jaegerCollectorEndpointOption, jaeger.WithEndpoint(ops.endpoint))
    91  	} else {
    92  		//skipped tracing when endpoint no set
    93  		return nil, nil
    94  	}
    95  	if ops.serviceName == "" {
    96  		ops.serviceName = _service
    97  	}
    98  	if ops.samplingRatio != "" {
    99  		ratio, err := strconv.ParseFloat(ops.samplingRatio, 64)
   100  		if err != nil {
   101  			return nil, err
   102  		}
   103  		trackerTracerProviderOption = append(trackerTracerProviderOption,
   104  			tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(ratio))),
   105  		)
   106  	}
   107  	kv := []attribute.KeyValue{
   108  		semconv.ServiceVersionKey.String(version.PackageVersion),
   109  		semconv.ServiceNameKey.String(ops.serviceName),
   110  	}
   111  	if ops.instanceID != "" {
   112  		kv = append(kv, semconv.ServiceInstanceIDKey.String(ops.instanceID))
   113  	}
   114  	// Record information about this application in an Resource.
   115  	resources := tracesdk.WithResource(resource.NewWithAttributes(
   116  		semconv.SchemaURL,
   117  		kv...,
   118  	))
   119  	trackerTracerProviderOption = append(trackerTracerProviderOption, resources)
   120  	// Create the Jaeger exporter
   121  	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaegerCollectorEndpointOption...))
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	// Always be sure to batch in production.
   126  	trackerTracerProviderOption = append(trackerTracerProviderOption, tracesdk.WithBatcher(exp))
   127  	tp := tracesdk.NewTracerProvider(trackerTracerProviderOption...)
   128  	//set global provider
   129  	otel.SetTracerProvider(tp)
   130  	return tp, nil
   131  }