github.com/shuguocloud/go-zero@v1.3.0/core/trace/agent.go (about)

     1  package trace
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/shuguocloud/go-zero/core/lang"
     8  	"github.com/shuguocloud/go-zero/core/logx"
     9  	"go.opentelemetry.io/otel"
    10  	"go.opentelemetry.io/otel/exporters/jaeger"
    11  	"go.opentelemetry.io/otel/exporters/zipkin"
    12  	"go.opentelemetry.io/otel/propagation"
    13  	"go.opentelemetry.io/otel/sdk/resource"
    14  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
    15  	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
    16  )
    17  
    18  const (
    19  	kindJaeger = "jaeger"
    20  	kindZipkin = "zipkin"
    21  )
    22  
    23  var (
    24  	agents = make(map[string]lang.PlaceholderType)
    25  	lock   sync.Mutex
    26  )
    27  
    28  // StartAgent starts a opentelemetry agent.
    29  func StartAgent(c Config) {
    30  	lock.Lock()
    31  	defer lock.Unlock()
    32  
    33  	_, ok := agents[c.Endpoint]
    34  	if ok {
    35  		return
    36  	}
    37  
    38  	// if error happens, let later calls run.
    39  	if err := startAgent(c); err != nil {
    40  		return
    41  	}
    42  
    43  	agents[c.Endpoint] = lang.Placeholder
    44  }
    45  
    46  func createExporter(c Config) (sdktrace.SpanExporter, error) {
    47  	// Just support jaeger and zipkin now, more for later
    48  	switch c.Batcher {
    49  	case kindJaeger:
    50  		return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(c.Endpoint)))
    51  	case kindZipkin:
    52  		return zipkin.New(c.Endpoint)
    53  	default:
    54  		return nil, fmt.Errorf("unknown exporter: %s", c.Batcher)
    55  	}
    56  }
    57  
    58  func startAgent(c Config) error {
    59  	opts := []sdktrace.TracerProviderOption{
    60  		// Set the sampling rate based on the parent span to 100%
    61  		sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(c.Sampler))),
    62  		// Record information about this application in an Resource.
    63  		sdktrace.WithResource(resource.NewSchemaless(semconv.ServiceNameKey.String(c.Name))),
    64  	}
    65  
    66  	if len(c.Endpoint) > 0 {
    67  		exp, err := createExporter(c)
    68  		if err != nil {
    69  			logx.Error(err)
    70  			return err
    71  		}
    72  
    73  		// Always be sure to batch in production.
    74  		opts = append(opts, sdktrace.WithBatcher(exp))
    75  	}
    76  
    77  	tp := sdktrace.NewTracerProvider(opts...)
    78  	otel.SetTracerProvider(tp)
    79  	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
    80  		propagation.TraceContext{}, propagation.Baggage{}))
    81  	otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
    82  		logx.Errorf("[otel] error: %v", err)
    83  	}))
    84  
    85  	return nil
    86  }