github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/cb/setup.go (about) 1 package cb 2 3 import ( 4 "errors" 5 "fmt" 6 "net/url" 7 "strings" 8 9 "github.com/afex/hystrix-go/hystrix" 10 metricCollector "github.com/afex/hystrix-go/hystrix/metric_collector" 11 "github.com/afex/hystrix-go/plugins" 12 "github.com/asaskevich/govalidator" 13 log "github.com/sirupsen/logrus" 14 15 "github.com/hellofresh/janus/pkg/plugin" 16 "github.com/hellofresh/janus/pkg/proxy" 17 ) 18 19 const ( 20 pluginName = "cb" 21 ) 22 23 // Config represents the Body Limit configuration 24 type Config struct { 25 hystrix.CommandConfig 26 Name string `json:"name"` 27 Predicate string `json:"predicate"` 28 } 29 30 func init() { 31 plugin.RegisterEventHook(plugin.StartupEvent, onStartup) 32 plugin.RegisterEventHook(plugin.AdminAPIStartupEvent, onAdminAPIStartup) 33 plugin.RegisterPlugin(pluginName, plugin.Plugin{ 34 Action: setupCB, 35 Validate: validateConfig, 36 }) 37 } 38 39 func setupCB(def *proxy.RouterDefinition, rawConfig plugin.Config) error { 40 var c Config 41 err := plugin.Decode(rawConfig, &c) 42 if err != nil { 43 return err 44 } 45 46 log.WithFields(log.Fields{ 47 "plugin_event": plugin.SetupEvent, 48 "plugin": pluginName, 49 "name": c.Name, 50 }).Debug("Configuring cb plugin") 51 52 hystrix.ConfigureCommand(c.Name, hystrix.CommandConfig{ 53 Timeout: c.Timeout, 54 MaxConcurrentRequests: c.MaxConcurrentRequests, 55 ErrorPercentThreshold: c.ErrorPercentThreshold, 56 SleepWindow: c.SleepWindow, 57 }) 58 59 def.AddMiddleware(NewCBMiddleware(c)) 60 return nil 61 } 62 63 func validateConfig(rawConfig plugin.Config) (bool, error) { 64 var config Config 65 err := plugin.Decode(rawConfig, &config) 66 if err != nil { 67 return false, err 68 } 69 70 return govalidator.ValidateStruct(config) 71 } 72 73 func onAdminAPIStartup(event interface{}) error { 74 logger := log.WithFields(log.Fields{ 75 "plugin_event": plugin.AdminAPIStartupEvent, 76 "plugin": pluginName, 77 }) 78 79 e, ok := event.(plugin.OnAdminAPIStartup) 80 if !ok { 81 return errors.New("could not convert event to admin startup type") 82 } 83 84 logger.Debug("Registering hystrix stream endpoint") 85 hystrixStreamHandler := hystrix.NewStreamHandler() 86 hystrixStreamHandler.Start() 87 88 e.Router.GET("/hystrix", hystrixStreamHandler.ServeHTTP) 89 return nil 90 } 91 92 func onStartup(event interface{}) error { 93 logger := log.WithFields(log.Fields{ 94 "plugin_event": plugin.StartupEvent, 95 "plugin": pluginName, 96 }) 97 98 e, ok := event.(plugin.OnStartup) 99 if !ok { 100 return errors.New("could not convert event to startup type") 101 } 102 103 logger.WithField("metrics_dsn", e.Config.Stats.DSN).Debug("Statsd metrics enabled") 104 105 dsnURL, err := url.Parse(e.Config.Stats.DSN) 106 if err != nil { 107 return fmt.Errorf("could not parse stats dsn: %w", err) 108 } 109 110 c, err := plugins.InitializeStatsdCollector(&plugins.StatsdCollectorConfig{ 111 StatsdAddr: dsnURL.Host, 112 Prefix: strings.Trim(dsnURL.Path, "/"), 113 }) 114 if err != nil { 115 return fmt.Errorf("could not initialize statsd client: %w", err) 116 } 117 118 metricCollector.Registry.Register(c.NewStatsdCollector) 119 logger.Debug("Metrics enabled") 120 121 return nil 122 }