github.com/argoproj/argo-cd/v3@v3.2.1/util/trace/trace.go (about)

     1  package trace
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	log "github.com/sirupsen/logrus"
     9  	"go.opentelemetry.io/otel"
    10  	"go.opentelemetry.io/otel/attribute"
    11  	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
    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.6.1"
    16  	"google.golang.org/grpc/credentials"
    17  )
    18  
    19  // InitTracer initializes the trace provider and the otel grpc exporter.
    20  func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpInsecure bool, otlpHeaders map[string]string, otlpAttrs []string) (func(), error) {
    21  	attrs := make([]attribute.KeyValue, 0, len(otlpAttrs))
    22  	for i := range otlpAttrs {
    23  		attr := otlpAttrs[i]
    24  		slice := strings.Split(attr, ":")
    25  		if len(slice) != 2 {
    26  			log.Warnf("OTLP attr '%s' split with ':' length not 2", attr)
    27  			continue
    28  		}
    29  		attrs = append(attrs, attribute.String(slice[0], slice[1]))
    30  	}
    31  
    32  	res, err := resource.New(ctx,
    33  		resource.WithAttributes(
    34  			semconv.ServiceNameKey.String(serviceName),
    35  		),
    36  		resource.WithAttributes(attrs...),
    37  	)
    38  	if err != nil {
    39  		return nil, fmt.Errorf("failed to create resource: %w", err)
    40  	}
    41  
    42  	// set up grpc options based on secure/insecure connection
    43  	var secureOption otlptracegrpc.Option
    44  	if otlpInsecure {
    45  		secureOption = otlptracegrpc.WithInsecure()
    46  	} else {
    47  		secureOption = otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, ""))
    48  	}
    49  
    50  	// set up a trace exporter
    51  	exporter, err := otlptracegrpc.New(ctx,
    52  		secureOption,
    53  		otlptracegrpc.WithEndpoint(otlpAddress),
    54  		otlptracegrpc.WithHeaders(otlpHeaders),
    55  	)
    56  	if err != nil {
    57  		return nil, fmt.Errorf("failed to create trace exporter: %w", err)
    58  	}
    59  
    60  	// Register the trace exporter with a TracerProvider, using a batch
    61  	// span processor to aggregate spans before export.
    62  	bsp := sdktrace.NewBatchSpanProcessor(exporter)
    63  	provider := sdktrace.NewTracerProvider(
    64  		sdktrace.WithSampler(sdktrace.AlwaysSample()),
    65  		sdktrace.WithResource(res),
    66  		sdktrace.WithSpanProcessor(bsp),
    67  	)
    68  
    69  	// set global propagator to tracecontext (the default is no-op).
    70  	otel.SetTextMapPropagator(propagation.TraceContext{})
    71  	otel.SetTracerProvider(provider)
    72  
    73  	return func() {
    74  		if err := exporter.Shutdown(ctx); err != nil {
    75  			log.Errorf("failed to stop exporter: %v", err)
    76  		}
    77  	}, nil
    78  }