github.com/cs3org/reva/v2@v2.27.7/pkg/trace/trace.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package trace
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"sync"
    25  
    26  	"go.opentelemetry.io/otel/attribute"
    27  	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
    28  	"go.opentelemetry.io/otel/propagation"
    29  	"go.opentelemetry.io/otel/sdk/resource"
    30  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
    31  	"google.golang.org/grpc"
    32  	"google.golang.org/grpc/credentials"
    33  	"google.golang.org/grpc/credentials/insecure"
    34  
    35  	"go.opentelemetry.io/otel"
    36  	"go.opentelemetry.io/otel/trace"
    37  	"go.opentelemetry.io/otel/trace/noop"
    38  )
    39  
    40  var (
    41  	// Propagator is the default Reva propagator.
    42  	Propagator      = propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})
    43  	defaultProvider = revaDefaultTracerProvider{}
    44  )
    45  
    46  type revaDefaultTracerProvider struct {
    47  	mutex       sync.RWMutex
    48  	initialized bool
    49  }
    50  
    51  // NewTracerProvider returns a new TracerProvider, configure for the specified service
    52  func NewTracerProvider(opts ...Option) trace.TracerProvider {
    53  	options := Options{}
    54  
    55  	for _, o := range opts {
    56  		o(&options)
    57  	}
    58  
    59  	if options.TransportCredentials == nil {
    60  		options.TransportCredentials = credentials.NewClientTLSFromCert(nil, "")
    61  	}
    62  
    63  	if !options.Enabled {
    64  		return noop.NewTracerProvider()
    65  	}
    66  
    67  	// default to 'reva' as service name if not set
    68  	if options.ServiceName == "" {
    69  		options.ServiceName = "reva"
    70  	}
    71  
    72  	return getOtlpTracerProvider(options)
    73  }
    74  
    75  // SetDefaultTracerProvider sets the default trace provider
    76  func SetDefaultTracerProvider(tp trace.TracerProvider) {
    77  	otel.SetTracerProvider(tp)
    78  	defaultProvider.mutex.Lock()
    79  	defer defaultProvider.mutex.Unlock()
    80  	defaultProvider.initialized = true
    81  }
    82  
    83  // InitDefaultTracerProvider initializes a global default jaeger TracerProvider at a package level.
    84  //
    85  // Deprecated: Use NewTracerProvider and SetDefaultTracerProvider to properly initialize a tracer provider with options
    86  func InitDefaultTracerProvider(collector, endpoint string) {
    87  	defaultProvider.mutex.Lock()
    88  	defer defaultProvider.mutex.Unlock()
    89  	if !defaultProvider.initialized {
    90  		SetDefaultTracerProvider(getOtlpTracerProvider(Options{
    91  			Endpoint:    endpoint,
    92  			ServiceName: "reva default otlp provider",
    93  			Insecure:    true,
    94  		}))
    95  	}
    96  }
    97  
    98  // DefaultProvider returns the "global" default TracerProvider
    99  // Currently used by the pool to get the global tracer
   100  func DefaultProvider() trace.TracerProvider {
   101  	defaultProvider.mutex.RLock()
   102  	defer defaultProvider.mutex.RUnlock()
   103  	return otel.GetTracerProvider()
   104  }
   105  
   106  // getOtelTracerProvider returns a new TracerProvider, configure for the specified service
   107  func getOtlpTracerProvider(options Options) trace.TracerProvider {
   108  	transportCredentials := options.TransportCredentials
   109  	if options.Insecure {
   110  		transportCredentials = insecure.NewCredentials()
   111  	}
   112  	conn, err := grpc.NewClient(options.Endpoint,
   113  		grpc.WithTransportCredentials(transportCredentials),
   114  	)
   115  	if err != nil {
   116  		panic(fmt.Errorf("failed to create gRPC connection to endpoint: %w", err))
   117  	}
   118  	exporter, err := otlptracegrpc.New(
   119  		context.Background(),
   120  		otlptracegrpc.WithGRPCConn(conn),
   121  	)
   122  
   123  	if err != nil {
   124  		panic(err)
   125  	}
   126  
   127  	resources, err := resource.New(
   128  		context.Background(),
   129  		resource.WithAttributes(
   130  			attribute.String("service.name", options.ServiceName),
   131  			attribute.String("library.language", "go"),
   132  		),
   133  	)
   134  	if err != nil {
   135  		panic(err)
   136  	}
   137  
   138  	return sdktrace.NewTracerProvider(
   139  		sdktrace.WithSampler(sdktrace.AlwaysSample()),
   140  		sdktrace.WithBatcher(exporter),
   141  		sdktrace.WithResource(resources),
   142  	)
   143  }