github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/cmd/init.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 "time" 10 11 "contrib.go.opencensus.io/exporter/jaeger" 12 "contrib.go.opencensus.io/exporter/prometheus" 13 "github.com/hellofresh/janus/pkg/config" 14 obs "github.com/hellofresh/janus/pkg/observability" 15 "github.com/hellofresh/logging-go" 16 _trace "github.com/hellofresh/opencensus-go-extras/trace" 17 "github.com/hellofresh/stats-go" 18 "github.com/hellofresh/stats-go/bucket" 19 "github.com/hellofresh/stats-go/client" 20 "github.com/hellofresh/stats-go/hooks" 21 log "github.com/sirupsen/logrus" 22 "go.opencensus.io/stats/view" 23 "go.opencensus.io/trace" 24 ) 25 26 var ( 27 globalConfig *config.Specification 28 statsClient client.Client 29 ) 30 31 func initLogWriterEarly() { 32 switch logging.LogWriter(strings.ToLower(os.Getenv("LOG_WRITER"))) { 33 case logging.StdOut: 34 log.SetOutput(os.Stdout) 35 case logging.Discard: 36 log.SetOutput(ioutil.Discard) 37 case logging.StdErr: 38 fallthrough 39 default: 40 log.SetOutput(os.Stderr) 41 } 42 } 43 44 func initConfig() { 45 var err error 46 globalConfig, err = config.Load(configFile) 47 if nil != err { 48 log.WithError(err).Info("Could not load configurations from file - trying environment configurations instead.") 49 50 globalConfig, err = config.LoadEnv() 51 if nil != err { 52 log.WithError(err).Error("Could not load configurations from environment variables") 53 } 54 } 55 } 56 57 // initializes the basic configuration for the log wrapper 58 func initLog() { 59 err := globalConfig.Log.Apply() 60 if nil != err { 61 log.WithError(err).Fatal("Could not apply logging configurations") 62 } 63 } 64 65 func initStatsClient() { 66 // FIXME: this causes application hang because we're in the locked log already 67 //statsLog.SetHandler(func(msg string, fields map[string]interface{}, err error) { 68 // entry := log.WithFields(log.Fields(fields)) 69 // if err == nil { 70 // entry.Warn(msg) 71 // } else { 72 // entry.WithError(err).Warn(msg) 73 // } 74 //}) 75 76 sectionsTestsMap, err := bucket.ParseSectionsTestsMap(globalConfig.Stats.IDs) 77 if err != nil { 78 log.WithError(err).WithField("config", globalConfig.Stats.IDs). 79 Error("Failed to parse stats second level IDs from env") 80 sectionsTestsMap = map[bucket.PathSection]bucket.SectionTestDefinition{} 81 } 82 log.WithField("config", globalConfig.Stats.IDs). 83 WithField("map", sectionsTestsMap.String()). 84 Debug("Setting stats second level IDs") 85 86 statsClient, err = stats.NewClient(globalConfig.Stats.DSN) 87 if err != nil { 88 log.WithError(err).Fatal("Error initializing stats client") 89 } 90 91 statsClient.SetHTTPMetricCallback(bucket.NewHasIDAtSecondLevelCallback(&bucket.SecondLevelIDConfig{ 92 HasIDAtSecondLevel: sectionsTestsMap, 93 AutoDiscoverThreshold: globalConfig.Stats.AutoDiscoverThreshold, 94 AutoDiscoverWhiteList: globalConfig.Stats.AutoDiscoverWhiteList, 95 })) 96 97 host, err := os.Hostname() 98 if nil != err { 99 host = "-unknown-" 100 } 101 102 _, appFile := filepath.Split(os.Args[0]) 103 statsClient.TrackMetric("app", bucket.MetricOperation{"init", host, appFile}) 104 105 log.AddHook(hooks.NewLogrusHook(statsClient, globalConfig.Stats.ErrorsSection)) 106 } 107 108 func initStatsExporter() { 109 var err error 110 logger := log.WithField("stats.exporter", globalConfig.Stats.Exporter) 111 112 // Register stats exporter according to config 113 switch globalConfig.Stats.Exporter { 114 case obs.Datadog: 115 fallthrough 116 case obs.Stackdriver: 117 logger.Warn("Not implemented!") 118 return 119 case obs.Prometheus: 120 err = initPrometheusExporter() 121 default: 122 logger.Info("Invalid or no stats exporter was specified") 123 return 124 } 125 126 if err != nil { 127 logger.WithError(err).Error("Failed initialising stats exporter") 128 return 129 } 130 131 // Configure/Register stats views 132 view.SetReportingPeriod(time.Second) 133 134 vv := append(obs.AllViews) 135 136 if err := view.Register(vv...); err != nil { 137 log.WithError(err).Warn("Failed to register server views") 138 } 139 } 140 141 func initPrometheusExporter() (err error) { 142 obs.PrometheusExporter, err = prometheus.NewExporter(prometheus.Options{}) 143 if err != nil { 144 log.WithError(err).Warn("Failed to create prometheus exporter") 145 } else { 146 view.RegisterExporter(obs.PrometheusExporter) 147 } 148 return err 149 } 150 151 func initTracingExporter() { 152 var err error 153 logger := log.WithField("tracing.exporter", globalConfig.Tracing.Exporter) 154 155 switch globalConfig.Tracing.Exporter { 156 case obs.AzureMonitor: 157 fallthrough 158 case obs.Datadog: 159 fallthrough 160 case obs.Stackdriver: 161 fallthrough 162 case obs.Zipkin: 163 logger.Warn("Not implemented!") 164 case obs.Jaeger: 165 err = initJaegerExporter() 166 default: 167 logger.Info("Invalid or no tracing exporter was specified") 168 return 169 } 170 171 if err != nil { 172 logger.WithError(err).Error("Failed initialising tracing exporter") 173 return 174 } 175 176 var traceConfig trace.Config 177 var sampler trace.Sampler 178 logger = logger.WithField("tracing.samplingStrategy", globalConfig.Tracing.SamplingStrategy) 179 180 switch globalConfig.Tracing.SamplingStrategy { 181 case "always": 182 sampler = trace.AlwaysSample() 183 case "never": 184 sampler = trace.NeverSample() 185 case "probabilistic": 186 sampler = trace.ProbabilitySampler(globalConfig.Tracing.SamplingParam) 187 default: 188 logger.Warn("Invalid tracing sampling strategy specified") 189 return 190 } 191 192 if !globalConfig.Tracing.IsPublicEndpoint { 193 sampler = _trace.RespectParentSampler(sampler) 194 } 195 196 traceConfig.DefaultSampler = sampler 197 trace.ApplyConfig(traceConfig) 198 } 199 200 func initJaegerExporter() (err error) { 201 jaegerURL := globalConfig.Tracing.JaegerTracing.SamplingServerURL 202 if jaegerURL == "" { 203 jaegerURL = fmt.Sprintf("%s:%s", globalConfig.Tracing.JaegerTracing.SamplingServerHost, globalConfig.Tracing.JaegerTracing.SamplingServerPort) 204 } 205 206 jaegerExporter, err := jaeger.NewExporter(jaeger.Options{ 207 AgentEndpoint: jaegerURL, 208 ServiceName: globalConfig.Tracing.ServiceName, 209 }) 210 if err != nil { 211 log.WithError(err).Warn("Failed to create jaeger exporter") 212 } else { 213 trace.RegisterExporter(jaegerExporter) 214 } 215 return err 216 }