dubbo.apache.org/dubbo-go/v3@v3.1.1/config/otel_config.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package config
    19  
    20  import (
    21  	"github.com/creasty/defaults"
    22  
    23  	"github.com/dubbogo/gost/log/logger"
    24  
    25  	"github.com/pkg/errors"
    26  
    27  	"go.opentelemetry.io/otel"
    28  )
    29  
    30  import (
    31  	"dubbo.apache.org/dubbo-go/v3/common/extension"
    32  	"dubbo.apache.org/dubbo-go/v3/otel/trace"
    33  )
    34  
    35  type OtelConfig struct {
    36  	TraceConfig *OtelTraceConfig `yaml:"trace" json:"trace,omitempty" property:"trace"`
    37  }
    38  
    39  type OtelTraceConfig struct {
    40  	Enable      *bool   `default:"false" yaml:"enable" json:"enable,omitempty" property:"enable"`
    41  	Exporter    string  `default:"stdout" yaml:"exporter" json:"exporter,omitempty" property:"exporter"` // stdout, jaeger, zipkin, otlp-http, otlp-grpc
    42  	Endpoint    string  `default:"" yaml:"endpoint" json:"endpoint,omitempty" property:"endpoint"`
    43  	Propagator  string  `default:"w3c" yaml:"propagator" json:"propagator,omitempty" property:"propagator"`       // one of w3c(standard), b3(for zipkin),
    44  	SampleMode  string  `default:"ratio" yaml:"sample-mode" json:"sample-mode,omitempty" property:"sample-mode"`  // one of always, never, ratio
    45  	SampleRatio float64 `default:"0.5" yaml:"sample-ratio" json:"sample-ratio,omitempty" property:"sample-ratio"` // [0.0, 1.0]
    46  }
    47  
    48  func (oc *OtelConfig) Init(appConfig *ApplicationConfig) error {
    49  	if oc == nil {
    50  		return errors.New("otel config is nil")
    51  	}
    52  	if err := defaults.Set(oc); err != nil {
    53  		return err
    54  	}
    55  	if err := verify(oc); err != nil {
    56  		return err
    57  	}
    58  	if *oc.TraceConfig.Enable {
    59  		extension.AddCustomShutdownCallback(extension.GetTraceShutdownCallback())
    60  		return oc.TraceConfig.init(appConfig)
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  func (c *OtelTraceConfig) init(appConfig *ApplicationConfig) error {
    67  	exporter, err := extension.GetTraceExporter(c.Exporter, c.toTraceProviderConfig(appConfig))
    68  	if err != nil {
    69  		return err
    70  	}
    71  	otel.SetTracerProvider(exporter.GetTracerProvider())
    72  	otel.SetTextMapPropagator(exporter.GetPropagator())
    73  
    74  	// print trace exporter configuration
    75  	if c.Exporter == "stdout" {
    76  		logger.Infof("enable %s trace provider with propagator: %s", c.Exporter, c.Propagator)
    77  	} else {
    78  		logger.Infof("enable %s trace provider with endpoint: %s, propagator: %s", c.Exporter, c.Endpoint, c.Propagator)
    79  	}
    80  	logger.Infof("sample mode: %s", c.SampleMode)
    81  	if c.SampleMode == "ratio" {
    82  		logger.Infof("sample ratio: %.2f", c.SampleRatio)
    83  	}
    84  
    85  	return nil
    86  }
    87  
    88  func (c *OtelTraceConfig) toTraceProviderConfig(a *ApplicationConfig) *trace.ExporterConfig {
    89  	tpc := &trace.ExporterConfig{
    90  		Exporter:         c.Exporter,
    91  		Endpoint:         c.Endpoint,
    92  		SampleMode:       c.SampleMode,
    93  		SampleRatio:      c.SampleRatio,
    94  		Propagator:       c.Propagator,
    95  		ServiceNamespace: a.Organization,
    96  		ServiceName:      a.Name,
    97  		ServiceVersion:   a.Version,
    98  	}
    99  	return tpc
   100  }
   101  
   102  type OtelConfigBuilder struct {
   103  	otelConfig *OtelConfig
   104  }
   105  
   106  func NewOtelConfigBuilder() *OtelConfigBuilder {
   107  	return &OtelConfigBuilder{
   108  		otelConfig: &OtelConfig{
   109  			TraceConfig: &OtelTraceConfig{},
   110  		},
   111  	}
   112  }
   113  
   114  func (ocb *OtelConfigBuilder) Build() *OtelConfig {
   115  	return ocb.otelConfig
   116  }
   117  
   118  // TODO: dynamic config