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 }