github.com/kaydxh/golang@v0.0.131/pkg/monitor/opentelemetry/config.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package opentelemetry
    23  
    24  import (
    25  	"context"
    26  	"fmt"
    27  
    28  	prometheus_ "github.com/kaydxh/golang/pkg/monitor/opentelemetry/metric/prometheus"
    29  	stdoutmetric_ "github.com/kaydxh/golang/pkg/monitor/opentelemetry/metric/stdout"
    30  	"github.com/kaydxh/golang/pkg/monitor/opentelemetry/resource"
    31  	jaeger_ "github.com/kaydxh/golang/pkg/monitor/opentelemetry/tracer/jaeger"
    32  	stdouttrace_ "github.com/kaydxh/golang/pkg/monitor/opentelemetry/tracer/stdout"
    33  	viper_ "github.com/kaydxh/golang/pkg/viper"
    34  	"github.com/sirupsen/logrus"
    35  	"github.com/spf13/viper"
    36  )
    37  
    38  type Config struct {
    39  	Proto Monitor_OpenTelemetry
    40  	opts  struct {
    41  		// If set, overrides params below
    42  		viper                       *viper.Viper
    43  		resourceStatsServiceOptions []resource.ResourceStatsServiceOption
    44  	}
    45  }
    46  
    47  type completedConfig struct {
    48  	*Config
    49  	completeError error
    50  }
    51  
    52  type CompletedConfig struct {
    53  	// Embed a private pointer that cannot be instantiated outside of this package.
    54  	*completedConfig
    55  }
    56  
    57  func (c *completedConfig) New(ctx context.Context) error {
    58  
    59  	logrus.Infof("Installing OpenTelemetry")
    60  
    61  	if c.completeError != nil {
    62  		return c.completeError
    63  	}
    64  
    65  	if !c.Proto.GetEnabled() {
    66  		return nil
    67  	}
    68  
    69  	err := c.install(ctx)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	logrus.Infof("Installed OpenTelemetry")
    74  
    75  	return nil
    76  }
    77  
    78  func (c *completedConfig) install(ctx context.Context) error {
    79  
    80  	var openTelemetryOpts []OpenTelemetryOption
    81  	opts, err := c.installMeter(ctx)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	openTelemetryOpts = append(openTelemetryOpts, opts...)
    86  
    87  	opts, err = c.installTracer(ctx)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	openTelemetryOpts = append(openTelemetryOpts, opts...)
    92  
    93  	ot := NewOpenTelemetry(openTelemetryOpts...)
    94  	err = ot.Install(ctx)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	_, err = c.installResource(ctx)
   100  	return err
   101  }
   102  
   103  func (c *completedConfig) installMeter(ctx context.Context) ([]OpenTelemetryOption, error) {
   104  
   105  	var opts []OpenTelemetryOption
   106  	collectDuration := c.Proto.GetMetricCollectDuration().AsDuration()
   107  	if collectDuration > 0 {
   108  		opts = append(opts, WithMetricCollectDuration(collectDuration))
   109  	}
   110  
   111  	metricType := c.Proto.OtelMetricExporterType
   112  	switch metricType {
   113  	case Monitor_OpenTelemetry_metric_prometheus:
   114  		builder := prometheus_.NewPrometheusExporterBuilder(
   115  			prometheus_.WithMetricUrlPath(c.Proto.GetOtelMetricExporter().GetPrometheus().GetUrl()),
   116  		)
   117  		opts = append(opts, WithMeterPullExporter(builder))
   118  
   119  	case Monitor_OpenTelemetry_metric_stdout:
   120  		builder := stdoutmetric_.NewStdoutExporterBuilder(
   121  			stdoutmetric_.WithPrettyPrint(c.Proto.GetOtelMetricExporter().GetStdout().GetPrettyPrint()),
   122  		)
   123  		opts = append(opts, WithMeterPushExporter(builder))
   124  
   125  	case Monitor_OpenTelemetry_metric_none:
   126  		// not enable metric
   127  		return nil, nil
   128  
   129  	default:
   130  		return nil, fmt.Errorf("not support the metricType[%v]", metricType.String())
   131  
   132  	}
   133  
   134  	return opts, nil
   135  }
   136  
   137  func (c *completedConfig) installTracer(ctx context.Context) ([]OpenTelemetryOption, error) {
   138  
   139  	var opts []OpenTelemetryOption
   140  	tracerType := c.Proto.OtelTraceExporterType
   141  	switch tracerType {
   142  	case Monitor_OpenTelemetry_trace_jaeger:
   143  		builder, err := jaeger_.NewJaegerExporertBuilder(c.Proto.GetOtelTraceExporter().GetJaeger().GetUrl())
   144  		if err != nil {
   145  			return nil, fmt.Errorf("new jaeger exporter builder err: %v", err)
   146  		}
   147  		opts = append(opts, WithTracerExporter(builder))
   148  
   149  	case Monitor_OpenTelemetry_trace_stdout:
   150  		builder := stdouttrace_.NewStdoutExporterBuilder(
   151  			stdouttrace_.WithPrettyPrint(c.Proto.GetOtelTraceExporter().GetStdout().GetPrettyPrint()),
   152  		)
   153  		opts = append(opts, WithTracerExporter(builder))
   154  
   155  	case Monitor_OpenTelemetry_trace_none:
   156  		// not enable tracer
   157  		return nil, nil
   158  
   159  	default:
   160  		return nil, fmt.Errorf("not support the tracerType[%v]", tracerType.String())
   161  	}
   162  
   163  	return opts, nil
   164  }
   165  
   166  func (c *completedConfig) installResource(ctx context.Context) (*resource.ResourceStatsService, error) {
   167  
   168  	var opts []resource.ResourceStatsServiceOption
   169  	collectDuration := c.Proto.GetMetricCollectDuration().AsDuration()
   170  	if collectDuration > 0 {
   171  		opts = append(opts, resource.WithStatsCheckInterval(collectDuration))
   172  	}
   173  	opts = append(opts, c.opts.resourceStatsServiceOptions...)
   174  
   175  	statsServer, err := resource.NewResourceStatsService(opts...)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	statsServer.Run(ctx)
   180  
   181  	return statsServer, nil
   182  }
   183  
   184  // Complete set default ServerRunOptions.
   185  func (c *Config) Complete() CompletedConfig {
   186  	err := c.loadViper()
   187  	if err != nil {
   188  		return CompletedConfig{&completedConfig{
   189  			Config:        c,
   190  			completeError: err,
   191  		}}
   192  	}
   193  
   194  	return CompletedConfig{&completedConfig{Config: c}}
   195  }
   196  
   197  func (c *Config) loadViper() error {
   198  	if c.opts.viper != nil {
   199  		return viper_.UnmarshalProtoMessageWithJsonPb(c.opts.viper, &c.Proto)
   200  	}
   201  
   202  	return nil
   203  }
   204  
   205  func NewConfig(options ...ConfigOption) *Config {
   206  	c := &Config{}
   207  	c.ApplyOptions(options...)
   208  
   209  	return c
   210  }