diff --git a/cmd/optimizely/main.go b/cmd/optimizely/main.go index 9062fe5a..1b9c4002 100644 --- a/cmd/optimizely/main.go +++ b/cmd/optimizely/main.go @@ -144,7 +144,8 @@ func main() { setRuntimeEnvironment(conf.Runtime) - agentMetricsRegistry := metrics.NewRegistry() + // Set metrics type to be used + agentMetricsRegistry := metrics.NewRegistry(conf.Admin.MetricsType) sdkMetricsRegistry := optimizely.NewRegistry(agentMetricsRegistry) ctx, cancel := context.WithCancel(context.Background()) // Create default service context diff --git a/cmd/optimizely/main_test.go b/cmd/optimizely/main_test.go index 94bde671..f9a7f66f 100644 --- a/cmd/optimizely/main_test.go +++ b/cmd/optimizely/main_test.go @@ -121,6 +121,7 @@ func assertLog(t *testing.T, actual config.LogConfig) { func assertAdmin(t *testing.T, actual config.AdminConfig) { assert.Equal(t, "3002", actual.Port) + assert.Equal(t, "prometheus", actual.MetricsType) } func assertAdminAuth(t *testing.T, actual config.ServiceAuthConfig) { @@ -282,6 +283,7 @@ func TestViperProps(t *testing.T) { v.Set("log.level", "debug") v.Set("admin.port", "3002") + v.Set("admin.metricsType", "prometheus") v.Set("admin.auth.ttl", "30m") v.Set("admin.auth.hmacSecrets", "efgh,ijkl") v.Set("admin.auth.jwksURL", "admin_jwks_url") @@ -375,6 +377,7 @@ func TestViperEnv(t *testing.T) { _ = os.Setenv("OPTIMIZELY_LOG_LEVEL", "debug") _ = os.Setenv("OPTIMIZELY_ADMIN_PORT", "3002") + _ = os.Setenv("OPTIMIZELY_ADMIN_METRICSTYPE", "prometheus") _ = os.Setenv("OPTIMIZELY_API_MAXCONNS", "100") _ = os.Setenv("OPTIMIZELY_API_PORT", "3000") diff --git a/cmd/optimizely/testdata/default.yaml b/cmd/optimizely/testdata/default.yaml index 4220b392..bce73bad 100644 --- a/cmd/optimizely/testdata/default.yaml +++ b/cmd/optimizely/testdata/default.yaml @@ -70,6 +70,7 @@ client: admin: port: "3002" + metricsType: "prometheus" auth: ttl: 30m hmacSecrets: diff --git a/config.yaml b/config.yaml index 2e40ed7a..0e9edbbc 100644 --- a/config.yaml +++ b/config.yaml @@ -95,6 +95,10 @@ api: admin: ## http listener port port: "8088" + ## metrics package to use + ## supported packages are expvar and prometheus + ## default is expvar + metricsType: "" ## ## webhook service receives update notifications to your Optimizely project. Receipt of the webhook will ## trigger an immediate download of the datafile from the CDN diff --git a/config/config.go b/config/config.go index 85be10b0..cc6702d5 100644 --- a/config/config.go +++ b/config/config.go @@ -39,7 +39,8 @@ func NewDefaultConfig() *AgentConfig { JwksURL: "", JwksUpdateInterval: 0, }, - Port: "8088", + Port: "8088", + MetricsType: "expvar", }, API: APIConfig{ Auth: ServiceAuthConfig{ @@ -255,8 +256,9 @@ type CORSConfig struct { // AdminConfig holds the configuration for the admin web interface type AdminConfig struct { - Auth ServiceAuthConfig `json:"-"` - Port string `json:"port"` + Auth ServiceAuthConfig `json:"-"` + Port string `json:"port"` + MetricsType string `json:"metricsType"` } // WebhookConfig holds configuration for Optimizely Webhooks diff --git a/config/config_test.go b/config/config_test.go index 67ec7849..969e7748 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -50,6 +50,7 @@ func TestDefaultConfig(t *testing.T) { assert.Equal(t, "info", conf.Log.Level) assert.Equal(t, "8088", conf.Admin.Port) + assert.Equal(t, "expvar", conf.Admin.MetricsType) assert.Equal(t, make([]OAuthClientCredentials, 0), conf.Admin.Auth.Clients) assert.Equal(t, make([]string, 0), conf.Admin.Auth.HMACSecrets) assert.Equal(t, time.Duration(0), conf.Admin.Auth.TTL) diff --git a/go.mod b/go.mod index b172aecd..1f50c6df 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,9 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/uuid v1.3.0 github.com/lestrrat-go/jwx v0.9.0 - github.com/optimizely/go-sdk v1.8.4-0.20230411182937-99d0bcfccf75 + github.com/optimizely/go-sdk v1.8.4-0.20230515121609-7ffed835c991 github.com/orcaman/concurrent-map v1.0.0 + github.com/prometheus/client_golang v1.11.0 github.com/rakyll/statik v0.1.7 github.com/rs/zerolog v1.29.0 github.com/spf13/viper v1.15.0 @@ -23,6 +24,16 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.30.0 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + google.golang.org/protobuf v1.28.1 // indirect +) + require ( github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/ajg/form v1.5.1 // indirect diff --git a/go.sum b/go.sum index cae38ce1..4e590d11 100644 --- a/go.sum +++ b/go.sum @@ -42,7 +42,17 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -81,11 +91,19 @@ github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIo github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -113,6 +131,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -124,6 +145,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -157,12 +179,21 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -179,28 +210,56 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/optimizely/go-sdk v1.8.4-0.20230411182937-99d0bcfccf75 h1:RVvxYfI/AaUnZ4f5WSezbWtjLeTEdL1uD9LHDsLSnj0= -github.com/optimizely/go-sdk v1.8.4-0.20230411182937-99d0bcfccf75/go.mod h1:06VK8mwwQTEh7QzP+qivf16tXtXEpoeblqtlhfvWEgk= +github.com/optimizely/go-sdk v1.8.4-0.20230515121609-7ffed835c991 h1:bRoRDKRa7EgSTCEb54qaDuU6IDegQKQumun8buDV/cY= +github.com/optimizely/go-sdk v1.8.4-0.20230515121609-7ffed835c991/go.mod h1:06VK8mwwQTEh7QzP+qivf16tXtXEpoeblqtlhfvWEgk= github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -210,6 +269,9 @@ github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.9.4 h1:Sd43wM1IWz/s1aVXdOBkjJvuP8UdyqioeE4AmM0QsBs= github.com/spf13/afero v1.9.4/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= @@ -221,6 +283,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -248,6 +311,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -292,6 +356,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -299,6 +364,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -321,6 +387,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -331,6 +398,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -344,9 +412,12 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -355,6 +426,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -367,6 +439,8 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -374,8 +448,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -391,6 +468,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -535,14 +613,24 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/handlers/admin_entities.go b/pkg/handlers/admin_entities.go index 9b555fd5..1c6e9abc 100644 --- a/pkg/handlers/admin_entities.go +++ b/pkg/handlers/admin_entities.go @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2019-2020, Optimizely, Inc. and contributors * + * Copyright 2019-2020,2023 Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -18,14 +18,13 @@ package handlers import ( - "expvar" "net/http" "os" "time" "github.com/go-chi/render" - "github.com/optimizely/agent/config" + "github.com/optimizely/agent/pkg/metrics" ) var startTime = time.Now() @@ -87,5 +86,5 @@ func (a Admin) AppInfoHeader(next http.Handler) http.Handler { // Metrics returns expvar info func (a Admin) Metrics(w http.ResponseWriter, r *http.Request) { - expvar.Handler().ServeHTTP(w, r) + metrics.GetHandler(a.Config.Admin.MetricsType).ServeHTTP(w, r) } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index cd8379ce..09c15ea3 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -18,11 +18,17 @@ package metrics import ( + "expvar" + "net/http" + "regexp" + "strings" "sync" go_kit_metrics "github.com/go-kit/kit/metrics" - go_kit_expvar "github.com/go-kit/kit/metrics/expvar" + go_kit_prometheus "github.com/go-kit/kit/metrics/prometheus" + stdprometheus "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/zerolog/log" ) @@ -33,12 +39,42 @@ const ( TimerPrefix = "timer" ) +const ( + prometheusPackage = "prometheus" +) + +// GetHandler returns request handler for provided metrics package type +func GetHandler(packageType string) http.Handler { + switch packageType { + case prometheusPackage: + return promhttp.Handler() + default: + // expvar + return expvar.Handler() + } +} + +// Timer is the collection of some timers +type Timer struct { + hits go_kit_metrics.Counter + totalTime go_kit_metrics.Counter + histogram go_kit_metrics.Histogram +} + +// Update timer components +func (t *Timer) Update(delta float64) { + t.hits.Add(1) + t.totalTime.Add(delta) + t.histogram.Observe(delta) +} + // Registry initializes expvar metrics registry type Registry struct { metricsCounterVars map[string]go_kit_metrics.Counter metricsGaugeVars map[string]go_kit_metrics.Gauge metricsHistogramVars map[string]go_kit_metrics.Histogram metricsTimerVars map[string]*Timer + metricsType string gaugeLock sync.RWMutex counterLock sync.RWMutex @@ -46,24 +82,6 @@ type Registry struct { timerLock sync.RWMutex } -// NewRegistry initializes metrics registry -func NewRegistry() *Registry { - - return &Registry{ - metricsCounterVars: map[string]go_kit_metrics.Counter{}, - metricsGaugeVars: map[string]go_kit_metrics.Gauge{}, - metricsHistogramVars: map[string]go_kit_metrics.Histogram{}, - metricsTimerVars: map[string]*Timer{}, - } -} - -// Timer is the collection of some timers -type Timer struct { - hits go_kit_metrics.Counter - totalTime go_kit_metrics.Counter - histogram go_kit_metrics.Histogram -} - // NewTimer constructs Timer func (m *Registry) NewTimer(key string) *Timer { if key == "" { @@ -81,16 +99,22 @@ func (m *Registry) NewTimer(key string) *Timer { return m.createTimer(combinedKey) } -// Update timer components -func (t *Timer) Update(delta float64) { - t.hits.Add(1) - t.totalTime.Add(delta) - t.histogram.Observe(delta) +// GetCounter gets go-kit expvar Counter +// NewRegistry initializes metrics registry +func NewRegistry(metricsType string) *Registry { + + registry := &Registry{ + metricsCounterVars: map[string]go_kit_metrics.Counter{}, + metricsGaugeVars: map[string]go_kit_metrics.Gauge{}, + metricsHistogramVars: map[string]go_kit_metrics.Histogram{}, + metricsTimerVars: map[string]*Timer{}, + metricsType: metricsType, + } + return registry } -// GetCounter gets go-kit expvar Counter +// GetCounter gets go-kit Counter func (m *Registry) GetCounter(key string) go_kit_metrics.Counter { - if key == "" { log.Warn().Msg("metrics counter key is empty") return nil @@ -103,13 +127,11 @@ func (m *Registry) GetCounter(key string) go_kit_metrics.Counter { if val, ok := m.metricsCounterVars[combinedKey]; ok { return val } - return m.createCounter(combinedKey) } -// GetGauge gets go-kit expvar Gauge +// GetGauge gets go-kit Gauge func (m *Registry) GetGauge(key string) go_kit_metrics.Gauge { - if key == "" { log.Warn().Msg("metrics gauge key is empty") return nil @@ -127,9 +149,8 @@ func (m *Registry) GetGauge(key string) go_kit_metrics.Gauge { // GetHistogram gets go-kit Histogram func (m *Registry) GetHistogram(key string) go_kit_metrics.Histogram { - if key == "" { - log.Warn().Msg("metrics gauge key is empty") + log.Warn().Msg("metrics histogram key is empty") return nil } @@ -141,25 +162,52 @@ func (m *Registry) GetHistogram(key string) go_kit_metrics.Histogram { return m.createHistogram(key) } -func (m *Registry) createGauge(key string) *go_kit_expvar.Gauge { - gaugeVar := go_kit_expvar.NewGauge(key) +func (m *Registry) createGauge(key string) (gaugeVar go_kit_metrics.Gauge) { + // This is required since naming convention for every package differs + name := m.getPackageSupportedName(key) + switch m.metricsType { + case prometheusPackage: + gaugeVar = go_kit_prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Name: name, + }, []string{}) + default: + // Default expvar + gaugeVar = go_kit_expvar.NewGauge(name) + } m.metricsGaugeVars[key] = gaugeVar - return gaugeVar - + return } -func (m *Registry) createCounter(key string) *go_kit_expvar.Counter { - counterVar := go_kit_expvar.NewCounter(key) +func (m *Registry) createCounter(key string) (counterVar go_kit_metrics.Counter) { + // This is required since naming convention for every package differs + name := m.getPackageSupportedName(key) + switch m.metricsType { + case prometheusPackage: + counterVar = go_kit_prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Name: name, + }, []string{}) + default: + // Default expvar + counterVar = go_kit_expvar.NewCounter(name) + } m.metricsCounterVars[key] = counterVar - return counterVar - + return } -func (m *Registry) createHistogram(key string) *go_kit_expvar.Histogram { - histogramVar := go_kit_expvar.NewHistogram(key, 50) +func (m *Registry) createHistogram(key string) (histogramVar go_kit_metrics.Histogram) { + // This is required since naming convention for every package differs + name := m.getPackageSupportedName(key) + switch m.metricsType { + case prometheusPackage: + histogramVar = go_kit_prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + Name: name, + }, []string{}) + default: + // Default expvar + histogramVar = go_kit_expvar.NewHistogram(name, 50) + } m.metricsHistogramVars[key] = histogramVar - return histogramVar - + return } func (m *Registry) createTimer(key string) *Timer { @@ -168,8 +216,33 @@ func (m *Registry) createTimer(key string) *Timer { totalTime: m.createCounter(key + ".responseTime"), histogram: m.createHistogram(key + ".responseTimeHist"), } - m.metricsTimerVars[key] = timerVar return timerVar +} +// getPackageSupportedName converts name to package supported type +func (m *Registry) getPackageSupportedName(name string) string { + switch m.metricsType { + case prometheusPackage: + // https://prometheus.io/docs/practices/naming/ + return toSnakeCase(name) + default: + // Default expvar + return name + } +} + +func toSnakeCase(name string) string { + v := strings.Replace(name, "-", "_", -1) + strArray := strings.Split(v, ".") + var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") + var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") + convertedArray := []string{} + + for _, v := range strArray { + snake := matchFirstCap.ReplaceAllString(v, "${1}_${2}") + snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}") + convertedArray = append(convertedArray, strings.ToLower(snake)) + } + return strings.Join(convertedArray, "_") } diff --git a/pkg/metrics/metrics_prometheus_test.go b/pkg/metrics/metrics_prometheus_test.go new file mode 100644 index 00000000..a8a4cc10 --- /dev/null +++ b/pkg/metrics/metrics_prometheus_test.go @@ -0,0 +1,204 @@ +/**************************************************************************** + * Copyright 2023, Optimizely, Inc. and contributors * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ***************************************************************************/ + +// Package optimizely // +package metrics + +import ( + "expvar" + "io/ioutil" + "net/http/httptest" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/stretchr/testify/assert" +) + +func TestPrometheusCounterValid(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + counter := metricsRegistry.GetCounter("metrics") + counter.Add(12) + counter.Add(23) + + expvar.Handler().ServeHTTP(rec, req) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "counter_metrics 35") +} + +func TestPrometheusCounterMultipleRetrievals(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + counterKey := "next_counter_metrics" + counter := metricsRegistry.GetCounter(counterKey) + counter.Add(12) + + nextCounter := metricsRegistry.GetCounter(counterKey) + nextCounter.Add(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "counter_"+counterKey+"35") +} + +func TestPrometheusCounterEmptyKey(t *testing.T) { + + metricsRegistry := NewRegistry(prometheusPackage) + counter := metricsRegistry.GetCounter("") + assert.Nil(t, counter) +} + +func TestPrometheusGaugeValid(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + gauge := metricsRegistry.GetGauge("metrics") + gauge.Set(12) + gauge.Set(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "gauge_metrics") +} + +func TestPrometheusGaugeMultipleRetrievals(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + guageKey := "next_gauge_metrics" + gauge := metricsRegistry.GetGauge(guageKey) + gauge.Set(12) + nextGauge := metricsRegistry.GetGauge(guageKey) + nextGauge.Set(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "gauge_"+guageKey+" 23") +} + +func TestPrometheusGaugeEmptyKey(t *testing.T) { + + metricsRegistry := NewRegistry(prometheusPackage) + gauge := metricsRegistry.GetGauge("") + assert.Nil(t, gauge) +} + +func TestPrometheusHistogramValid(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + histogram := metricsRegistry.GetHistogram("metrics") + histogram.Observe(12) + histogram.Observe(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "timer_metrics_response_time_hist_sum 35") + strings.Contains(strResponse, "timer_metrics_response_time_hist_count 2") +} + +func TestPrometheusHistogramMultipleRetrievals(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + histogramKey := "next_histogram_metrics" + histogram := metricsRegistry.GetHistogram(histogramKey) + histogram.Observe(12) + nextGauge := metricsRegistry.GetHistogram(histogramKey) + nextGauge.Observe(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "timer_metrics_response_time_hist_sum 35") + strings.Contains(strResponse, "timer_metrics_response_time_hist_count 2") +} + +func TestPrometheusHistogramEmptyKey(t *testing.T) { + + metricsRegistry := NewRegistry(prometheusPackage) + histogram := metricsRegistry.GetHistogram("") + + assert.Nil(t, histogram) +} + +func TestPrometheusTimerValid(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + timer := metricsRegistry.NewTimer("metrics") + timer.Update(12) + timer.Update(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "timer_metrics_response_time_hist_sum 35") + strings.Contains(strResponse, "timer_metrics_response_time_hist_count 2") + strings.Contains(strResponse, `timer_metrics_response_time_hist_bucket{le="+Inf"} 2`) +} + +func TestPrometheusTimerMultipleRetrievals(t *testing.T) { + + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + metricsRegistry := NewRegistry(prometheusPackage) + timerKey := "next_timer_metrics" + timer := metricsRegistry.NewTimer(timerKey) + timer.Update(12) + nextTimer := metricsRegistry.NewTimer(timerKey) + nextTimer.Update(23) + + promhttp.Handler().ServeHTTP(rec, req) + resp, err := ioutil.ReadAll(rec.Body) + assert.Nil(t, err) + strResponse := string(resp) + strings.Contains(strResponse, "timer_metrics_response_time_hist_sum 35") + strings.Contains(strResponse, "timer_metrics_response_time_hist_count 2") + strings.Contains(strResponse, `timer_metrics_response_time_hist_bucket{le="+Inf"} 2`) +} diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index 9b108798..1eadda22 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2019, Optimizely, Inc. and contributors * + * Copyright 2019,2023 Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -28,12 +28,18 @@ import ( type JSON map[string]interface{} +func TestGetHandler(t *testing.T) { + assert.NotNil(t, GetHandler("")) + assert.NotNil(t, GetHandler("expvar")) + assert.NotNil(t, GetHandler("123131231")) +} + func TestCounterValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") counter := metricsRegistry.GetCounter("metrics") counter.Add(12) counter.Add(23) @@ -52,7 +58,7 @@ func TestCounterMultipleRetrievals(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") counterKey := "next_counter_metrics" counter := metricsRegistry.GetCounter(counterKey) counter.Add(12) @@ -70,7 +76,7 @@ func TestCounterMultipleRetrievals(t *testing.T) { func TestCounterEmptyKey(t *testing.T) { - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") counter := metricsRegistry.GetCounter("") assert.Nil(t, counter) @@ -82,7 +88,7 @@ func TestGaugeValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") gauge := metricsRegistry.GetGauge("metrics") gauge.Set(12) gauge.Set(23) @@ -101,7 +107,7 @@ func TestGaugeMultipleRetrievals(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") guageKey := "next_gauge_metrics" gauge := metricsRegistry.GetGauge(guageKey) gauge.Set(12) @@ -119,7 +125,7 @@ func TestGaugeMultipleRetrievals(t *testing.T) { func TestGaugeEmptyKey(t *testing.T) { - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") gauge := metricsRegistry.GetGauge("") assert.Nil(t, gauge) @@ -131,7 +137,7 @@ func TestHistorgramValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") histogram := metricsRegistry.GetHistogram("metrics") histogram.Observe(12) histogram.Observe(23) @@ -151,7 +157,7 @@ func TestHistogramMultipleRetrievals(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") histogramKey := "next_histogram_metrics" histogram := metricsRegistry.GetHistogram(histogramKey) histogram.Observe(12) @@ -170,7 +176,7 @@ func TestHistogramMultipleRetrievals(t *testing.T) { func TestHistogramEmptyKey(t *testing.T) { - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") histogram := metricsRegistry.GetHistogram("") assert.Nil(t, histogram) @@ -181,7 +187,7 @@ func TestTimerValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") timer := metricsRegistry.NewTimer("metrics") timer.Update(12) timer.Update(23) @@ -202,7 +208,7 @@ func TestTimerMultipleRetrievals(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := NewRegistry() + metricsRegistry := NewRegistry("") timerKey := "next_timer_metrics" timer := metricsRegistry.NewTimer(timerKey) timer.Update(12) @@ -219,3 +225,18 @@ func TestTimerMultipleRetrievals(t *testing.T) { assert.Equal(t, 23.0, expVarMap["timer.next_timer_metrics.responseTimeHist.p99"]) } + +func TestToSnakeCase(t *testing.T) { + assert.Equal(t, "", toSnakeCase("")) + assert.Equal(t, "abc", toSnakeCase("abc")) + assert.Equal(t, "abc_123", toSnakeCase("abc_123")) + assert.Equal(t, "abc_efg", toSnakeCase("abcEfg")) + assert.Equal(t, "timer_activate_response_time", toSnakeCase("timer.activate.responseTime")) + assert.Equal(t, "timer_activate_response_time_hist_p95", toSnakeCase("timer.activate.responseTimeHist.p95")) + assert.Equal(t, "timer_create_api_access_token_response_time_hist_p50", toSnakeCase("timer.create-api-access-token.responseTimeHist.p50")) + assert.Equal(t, "timer_get_config_response_time_hist_p50", toSnakeCase("timer.get-config.responseTimeHist.p50")) + assert.Equal(t, "timer_track_event_response_time_hist_p50", toSnakeCase("timer.track-event.responseTimeHist.p50")) + assert.Equal(t, "counter_dispatcher_success_flush", toSnakeCase("counter.dispatcher.successFlush")) + assert.Equal(t, "timer_get_config_response_time", toSnakeCase("timer.get-config.responseTime")) + assert.Equal(t, "timer_get_config_hits", toSnakeCase("timer.get-config.hits")) +} diff --git a/pkg/middleware/metrics_test.go b/pkg/middleware/metrics_test.go index 6148a4e8..5d35a3e2 100644 --- a/pkg/middleware/metrics_test.go +++ b/pkg/middleware/metrics_test.go @@ -53,7 +53,7 @@ func (rm *RequestMetrics) SetupRoute(key string) { r := httptest.NewRequest("GET", "/", nil) rm.req = r.WithContext(context.WithValue(r.Context(), responseTime, time.Now())) - rm.handler = http.Handler(Metricize(key, metrics.NewRegistry())(getTestMetrics())) + rm.handler = http.Handler(Metricize(key, metrics.NewRegistry(""))(getTestMetrics())) } diff --git a/pkg/optimizely/cache_test.go b/pkg/optimizely/cache_test.go index efc68d08..2beabb4b 100644 --- a/pkg/optimizely/cache_test.go +++ b/pkg/optimizely/cache_test.go @@ -108,7 +108,7 @@ func (suite *CacheTestSuite) TestUpdateConfigs() { } func (suite *CacheTestSuite) TestNewCache() { - agentMetricsRegistry := metrics.NewRegistry() + agentMetricsRegistry := metrics.NewRegistry("") sdkMetricsRegistry := NewRegistry(agentMetricsRegistry) // To improve coverage @@ -378,7 +378,7 @@ type DefaultLoaderTestSuite struct { func (s *DefaultLoaderTestSuite) SetupTest() { // Need the registry to be created only once since it panics if we create gauges with the same name again and again doOnce.Do(func() { - s.registry = &MetricsRegistry{metrics.NewRegistry()} + s.registry = &MetricsRegistry{metrics.NewRegistry("")} }) s.upsMap = cmap.New() s.odpCacheMap = cmap.New() diff --git a/pkg/optimizely/metrics_test.go b/pkg/optimizely/metrics_test.go index 76ce9c8b..b64ed154 100644 --- a/pkg/optimizely/metrics_test.go +++ b/pkg/optimizely/metrics_test.go @@ -35,7 +35,7 @@ func TestCounterValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := metrics.NewRegistry() + metricsRegistry := metrics.NewRegistry("") metricsSDKRegistry := NewRegistry(metricsRegistry) counter := metricsSDKRegistry.GetCounter("metrics") @@ -56,7 +56,7 @@ func TestGaugeValid(t *testing.T) { rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) - metricsRegistry := metrics.NewRegistry() + metricsRegistry := metrics.NewRegistry("") metricsSDKRegistry := NewRegistry(metricsRegistry) gauge := metricsSDKRegistry.GetGauge("metrics") diff --git a/pkg/routers/api_test.go b/pkg/routers/api_test.go index 933ce491..a34244f4 100644 --- a/pkg/routers/api_test.go +++ b/pkg/routers/api_test.go @@ -33,7 +33,7 @@ import ( "github.com/optimizely/agent/pkg/optimizely/optimizelytest" ) -var metricsRegistry = metrics.NewRegistry() +var metricsRegistry = metrics.NewRegistry("") const methodHeaderKey = "X-Method-Header" const clientHeaderKey = "X-Client-Header"