diff --git a/receiver/prometheusreceiver/config.go b/receiver/prometheusreceiver/config.go index 6dfd2f54f73ca..88dd7e907c892 100644 --- a/receiver/prometheusreceiver/config.go +++ b/receiver/prometheusreceiver/config.go @@ -31,6 +31,7 @@ import ( "github.com/prometheus/prometheus/discovery/kubernetes" "github.com/prometheus/prometheus/discovery/targetgroup" "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/service/featuregate" "gopkg.in/yaml.v2" ) @@ -39,6 +40,16 @@ const ( prometheusConfigKey = "config" ) +var pdataPipelineGate = featuregate.Gate{ + ID: "receiver.prometheus.OTLPDirect", + Enabled: false, + Description: "Controls whether to use a new translation directly from Prometheus timeseries to pdata, without an intermediate representation as OpenCensus data.", +} + +func init() { + featuregate.Register(pdataPipelineGate) +} + // Config defines configuration for Prometheus receiver. type Config struct { config.ReceiverSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct @@ -47,6 +58,7 @@ type Config struct { BufferCount int `mapstructure:"buffer_count"` UseStartTimeMetric bool `mapstructure:"use_start_time_metric"` StartTimeMetricRegex string `mapstructure:"start_time_metric_regex"` + pdataDirect bool // ConfigPlaceholder is just an entry to make the configuration pass a check // that requires that all keys present in the config actually exist on the diff --git a/receiver/prometheusreceiver/factory.go b/receiver/prometheusreceiver/factory.go index 9b12bd686717a..36c9880013175 100644 --- a/receiver/prometheusreceiver/factory.go +++ b/receiver/prometheusreceiver/factory.go @@ -23,6 +23,7 @@ import ( "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver/receiverhelper" + "go.opentelemetry.io/collector/service/featuregate" ) // This file implements config for Prometheus receiver. @@ -44,6 +45,7 @@ func NewFactory() component.ReceiverFactory { func createDefaultConfig() config.Receiver { return &Config{ ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), + pdataDirect: featuregate.IsEnabled(pdataPipelineGate.ID), } } diff --git a/receiver/prometheusreceiver/go.mod b/receiver/prometheusreceiver/go.mod index fdad6768c13f7..49045a6794c44 100644 --- a/receiver/prometheusreceiver/go.mod +++ b/receiver/prometheusreceiver/go.mod @@ -38,8 +38,8 @@ require ( github.com/aws/aws-sdk-go v1.42.14 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.1.2 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/containerd v1.5.8 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/containerd/containerd v1.4.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/digitalocean/godo v1.62.0 // indirect github.com/docker/distribution v2.7.1+incompatible // indirect diff --git a/receiver/prometheusreceiver/go.sum b/receiver/prometheusreceiver/go.sum index d2b9fa32b7828..7946f86da8664 100644 --- a/receiver/prometheusreceiver/go.sum +++ b/receiver/prometheusreceiver/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -48,20 +47,17 @@ collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs= contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v55.2.0+incompatible h1:TL2/vJWJEPOrmv97nHcbvjXES0Ntlb9P95hqGA1J2dU= github.com/Azure/azure-sdk-for-go v55.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.10.1/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.19 h1:7/IqD2fEYVha1EPeaiytVKhzmPV223pfkRIQUGOK2IE= github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= @@ -70,7 +66,6 @@ github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.14 h1:G8hexQdV5D4khOXrWG2YuLCFKhWYmWD8bHYaXN5ophk= @@ -84,7 +79,6 @@ github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSY github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= @@ -109,25 +103,9 @@ github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnl github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.16.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= -github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= -github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= -github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= -github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= -github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= -github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -136,7 +114,6 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -150,7 +127,6 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4= github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -161,7 +137,6 @@ github.com/apache/arrow/go/arrow v0.0.0-20200923215132-ac86123a3f01/go.mod h1:QN github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= @@ -175,7 +150,6 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.29.16/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= @@ -199,26 +173,15 @@ github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFA github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps= -github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bonitoo-io/go-sql-bigquery v0.3.4-1.4.0/go.mod h1:J4Y6YJm0qTWB9aFziB7cPeSyc6dOZFyJdteSeybVpXQ= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/cactus/go-statsd-client/statsd v0.0.0-20191106001114-12b4e2b38748/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -226,7 +189,6 @@ github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6 github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -235,19 +197,11 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -262,127 +216,27 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= -github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= -github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= -github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= -github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= -github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= -github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= -github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3 h1:ijQT13JedHSHrQGWFcGEwzcNKrAGIiZ+jSD5QQG07SY= github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= -github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= -github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= -github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.8 h1:NmkCC1/QxyZFBny8JogwLpOy2f+VEbO/f6bV2Mqtwuw= -github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= -github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= -github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= -github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= -github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= -github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= -github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= -github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= -github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= -github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= -github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= -github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= -github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= -github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= -github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= -github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= -github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= -github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= -github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.62.0 h1:7Gw2KFsWkxl36qJa0s50tgXaE0Cgm51JdRP+MFQvNnM= @@ -390,22 +244,15 @@ github.com/digitalocean/godo v1.62.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2x github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= -github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -418,7 +265,6 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -446,13 +292,10 @@ github.com/foxcpp/go-mockdns v0.0.0-20201212160233-ede2f9158d15/go.mod h1:tPg4cp github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -467,7 +310,6 @@ github.com/go-chi/chi v4.1.0+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxm 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-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 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.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -481,7 +323,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -612,22 +453,15 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= -github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -636,7 +470,6 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -718,7 +551,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -734,20 +566,15 @@ github.com/gophercloud/gophercloud v0.18.0 h1:V6hcuMPmjXg+js9flU8T3RIHDCjV7F5CG5 github.com/gophercloud/gophercloud v0.18.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -764,7 +591,6 @@ github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPA github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -783,7 +609,6 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= @@ -836,9 +661,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -859,11 +681,8 @@ github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bS github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/tdigest v0.0.2-0.20210216194612-fc98d27c9e8b/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -901,8 +720,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -938,7 +755,6 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -951,7 +767,6 @@ github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -970,7 +785,6 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -983,9 +797,7 @@ github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7 github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mileusna/useragent v0.0.0-20190129205925-3e331f0949a5/go.mod h1:JWhYAp2EXqUtsxTKdeGlY8Wp44M7VxThC9FEoNGi2IE= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= @@ -1010,16 +822,10 @@ github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1034,10 +840,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/go-grpc-compression v1.1.15 h1:9pLWmZldgo3vstd3yGyNgpCzY5gvhCrCj3PyvnvlDiY= github.com/mostynb/go-grpc-compression v1.1.15/go.mod h1:OTK+ha9cKfSY0Pb3ESCzvGhzStJrudBxXPzuC3PaA5A= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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 h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1049,59 +853,30 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= -github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= @@ -1120,10 +895,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= @@ -1136,7 +909,6 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pierrec/lz4/v3 v3.3.4/go.mod h1:280XNCGS8jAcG++AHdd6SeWnzyJ1w9oow2vbORyey8Q= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/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= @@ -1150,15 +922,11 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= github.com/prometheus/alertmanager v0.22.2/go.mod h1:rYinOWxFuCnNssc3iOjn2oMTlhLaPcUuqV5yk5JKUAE= -github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -1167,7 +935,6 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= 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-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1175,10 +942,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.1.0/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.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= @@ -1193,18 +957,13 @@ github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/exporter-toolkit v0.5.1/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/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= @@ -1213,7 +972,6 @@ github.com/prometheus/prometheus v1.8.2-0.20210621150501-ff58416a0b02 h1:waKRn/b github.com/prometheus/prometheus v1.8.2-0.20210621150501-ff58416a0b02/go.mod h1:fC6ROpjS/2o+MQTO7X8NSZLhLBSNlDzxaeDMqQm+TUM= github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8= github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= @@ -1234,18 +992,15 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44 h1:3egqo0Vut6daANFm7tOXdNAa8v5/uLU+sgCJrc88Meo= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/schollz/progressbar/v2 v2.13.2/go.mod h1:6YZjqdthH6SCZKv2rqGryrxPtfmRB/DWZxSMfCXPyD8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -1255,8 +1010,6 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -1266,45 +1019,35 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snowflakedb/gosnowflake v1.3.4/go.mod h1:NsRq2QeiMUuoNUJhp5Q6xGC4uBrsS9g6LwZVEkTWgsE= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1314,10 +1057,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -1336,7 +1075,6 @@ github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber-go/tally v3.3.15+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= github.com/uber/athenadriver v1.1.4/go.mod h1:tQjho4NzXw55LGfSZEcETuYydpY1vtmixUabHkC1K/E= @@ -1344,36 +1082,21 @@ github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1382,14 +1105,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= @@ -1403,7 +1120,6 @@ go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4S go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= -go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1443,7 +1159,6 @@ go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuN go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1470,10 +1185,8 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1495,12 +1208,10 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1547,7 +1258,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1560,10 +1270,8 @@ golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 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-20190619014844-b5b0513f8c1b/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= @@ -1589,7 +1297,6 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1656,21 +1363,14 @@ golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7w 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-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1678,25 +1378,19 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1707,22 +1401,13 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w 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-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/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= @@ -1734,13 +1419,11 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/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-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1772,7 +1455,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= @@ -1868,7 +1550,6 @@ gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1904,14 +1585,12 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1924,7 +1603,6 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1945,7 +1623,6 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1959,7 +1636,6 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 h1:ysnBoUyeL/H6RCvNRhWHjKoDEmguI+mPU+qHgK8qv/w= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2009,11 +1685,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2025,17 +1699,13 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -2054,8 +1724,6 @@ gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= @@ -2068,33 +1736,14 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.17.5/go.mod h1:0zV5/ungglgy2Rlm3QK8fbxkXVs+BSJWpJP/+8gUVLY= -k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= -k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0= -k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= -k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/client-go v0.17.5/go.mod h1:S8uZpBpjJJdEH/fEyxcqg7Rn0P5jH+ilkgBHjriSmNo= -k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= -k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= -k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= -k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= -k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -2102,15 +1751,12 @@ k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20200316234421-82d701f24f9d/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= @@ -2119,11 +1765,8 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/receiver/prometheusreceiver/internal/metricfamily.go b/receiver/prometheusreceiver/internal/metricfamily.go index 06d4a24ced64f..97b4dd05c5413 100644 --- a/receiver/prometheusreceiver/internal/metricfamily.go +++ b/receiver/prometheusreceiver/internal/metricfamily.go @@ -32,7 +32,6 @@ import ( // a single scrape. type MetricFamily interface { Add(metricName string, ls labels.Labels, t int64, v float64) error - IsSameFamily(metricName string) bool ToMetric() (*metricspb.Metric, int, int) } @@ -125,12 +124,6 @@ func defineInternalMetric(metricName string, metadata scrape.MetricMetadata, log return metadata } -func (mf *metricFamily) IsSameFamily(metricName string) bool { - // trim known suffix if necessary - familyName := normalizeMetricName(metricName) - return mf.name == familyName || familyName != metricName && mf.name == metricName -} - // updateLabelKeys is used to store all the label keys of a same metric family in observed order. since prometheus // receiver removes any label with empty value before feeding it to an appender, in order to figure out all the labels // from the same metric family we will need to keep track of what labels have ever been observed. diff --git a/receiver/prometheusreceiver/internal/metrics_adjuster_test.go b/receiver/prometheusreceiver/internal/metrics_adjuster_test.go index e6e45e1b0ef16..712f5b3f930c7 100644 --- a/receiver/prometheusreceiver/internal/metrics_adjuster_test.go +++ b/receiver/prometheusreceiver/internal/metrics_adjuster_test.go @@ -408,24 +408,11 @@ func Test_jobGC(t *testing.T) { } var ( - g1 = "gauge1" - gd1 = "gaugedist1" - c1 = "cumulative1" - cd1 = "cumulativedist1" - s1 = "summary1" - k1 = []string{"k1"} - k1k2 = []string{"k1", "k2"} - k1k2k3 = []string{"k1", "k2", "k3"} - v1v2 = []string{"v1", "v2"} - v10v20 = []string{"v10", "v20"} - v100v200 = []string{"v100", "v200"} - bounds0 = []float64{1, 2, 4} - percent0 = []float64{10, 50, 90} - t1Ms = time.Unix(0, 1000000) - t2Ms = time.Unix(0, 2000000) - t3Ms = time.Unix(0, 3000000) - t4Ms = time.Unix(0, 5000000) - t5Ms = time.Unix(0, 5000000) + t1Ms = time.Unix(0, 1000000) + t2Ms = time.Unix(0, 2000000) + t3Ms = time.Unix(0, 3000000) + t4Ms = time.Unix(0, 5000000) + t5Ms = time.Unix(0, 5000000) ) type metricsAdjusterTest struct { diff --git a/receiver/prometheusreceiver/internal/metricsbuilder.go b/receiver/prometheusreceiver/internal/metricsbuilder.go index 6d34fb1ffdf9c..ecef3dab8cebf 100644 --- a/receiver/prometheusreceiver/internal/metricsbuilder.go +++ b/receiver/prometheusreceiver/internal/metricsbuilder.go @@ -58,7 +58,7 @@ type metricBuilder struct { startTime float64 intervalStartTimeMs int64 logger *zap.Logger - currentMf MetricFamily + families map[string]MetricFamily } // newMetricBuilder creates a MetricBuilder which is allowed to feed all the datapoints from a single prometheus @@ -72,6 +72,7 @@ func newMetricBuilder(mc MetadataCache, useStartTimeMetric bool, startTimeMetric return &metricBuilder{ mc: mc, metrics: make([]*metricspb.Metric, 0), + families: map[string]MetricFamily{}, logger: logger, numTimeseries: 0, droppedTimeseries: 0, @@ -137,19 +138,18 @@ func (b *metricBuilder) AddDataPoint(ls labels.Labels, t int64, v float64) error b.hasData = true - if b.currentMf != nil && !b.currentMf.IsSameFamily(metricName) { - m, ts, dts := b.currentMf.ToMetric() - b.numTimeseries += ts - b.droppedTimeseries += dts - if m != nil { - b.metrics = append(b.metrics, m) + familyName := normalizeMetricName(metricName) + curMF, ok := b.families[familyName] + if !ok { + if mf, ok := b.families[metricName]; ok { + curMF = mf + } else { + curMF = newMetricFamily(metricName, b.mc, b.logger, b.intervalStartTimeMs) + b.families[familyName] = curMF } - b.currentMf = newMetricFamily(metricName, b.mc, b.logger, b.intervalStartTimeMs) - } else if b.currentMf == nil { - b.currentMf = newMetricFamily(metricName, b.mc, b.logger, b.intervalStartTimeMs) } - return b.currentMf.Add(metricName, ls, t, v) + return curMF.Add(metricName, ls, t, v) } // Build an opencensus data.MetricsData based on all added data complexValue. @@ -162,14 +162,13 @@ func (b *metricBuilder) Build() ([]*metricspb.Metric, int, int, error) { return nil, 0, 0, errNoDataToBuild } - if b.currentMf != nil { - m, ts, dts := b.currentMf.ToMetric() + for _, mf := range b.families { + m, ts, dts := mf.ToMetric() b.numTimeseries += ts b.droppedTimeseries += dts if m != nil { b.metrics = append(b.metrics, m) } - b.currentMf = nil } return b.metrics, b.numTimeseries, b.droppedTimeseries, nil diff --git a/receiver/prometheusreceiver/internal/metricsbuilder_test.go b/receiver/prometheusreceiver/internal/metricsbuilder_test.go index f1c7d419dc39b..da8ddfee2875b 100644 --- a/receiver/prometheusreceiver/internal/metricsbuilder_test.go +++ b/receiver/prometheusreceiver/internal/metricsbuilder_test.go @@ -108,13 +108,30 @@ func runBuilderTests(t *testing.T, tests []buildTestData) { } metrics, _, _, err := b.Build() assert.NoError(t, err) - assert.EqualValues(t, tt.wants[i], metrics) + assertEquivalentMetrics(t, tt.wants[i], metrics) st += interval } }) } } +func assertEquivalentMetrics(t *testing.T, want, got []*metricspb.Metric) { + if !assert.Equal(t, len(want), len(got)) { + return + } + wmap := map[string]*metricspb.Metric{} + gmap := map[string]*metricspb.Metric{} + + for i := 0; i < len(want); i++ { + wi := want[i] + wmap[wi.GetMetricDescriptor().GetName()] = wi + gi := got[i] + gmap[gi.GetMetricDescriptor().GetName()] = gi + } + + assert.EqualValues(t, wmap, gmap) +} + func runBuilderStartTimeTests(t *testing.T, tests []buildTestData, startTimeMetricRegex string, expectedBuilderStartTime float64) { for _, tt := range tests { @@ -1298,10 +1315,10 @@ func Test_isUsefulLabel(t *testing.T) { func Benchmark_dpgSignature(b *testing.B) { knownLabelKeys := []string{"a", "b"} - labels := labels.FromStrings("a", "va", "b", "vb", "x", "xa") + ls := labels.FromStrings("a", "va", "b", "vb", "x", "xa") b.ReportAllocs() for i := 0; i < b.N; i++ { - runtime.KeepAlive(dpgSignature(knownLabelKeys, labels)) + runtime.KeepAlive(dpgSignature(knownLabelKeys, ls)) } } diff --git a/receiver/prometheusreceiver/internal/metricsutil_pdata_test.go b/receiver/prometheusreceiver/internal/metricsutil_pdata_test.go new file mode 100644 index 0000000000000..7fd3eb7fb7fa1 --- /dev/null +++ b/receiver/prometheusreceiver/internal/metricsutil_pdata_test.go @@ -0,0 +1,140 @@ +// Copyright The OpenTelemetry Authors +// +// 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 internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal" + +import "go.opentelemetry.io/collector/model/pdata" + +type kv struct { + Key, Value string +} + +func distPointPdata(ts pdata.Timestamp, bounds []float64, counts []uint64) *pdata.HistogramDataPoint { + hdp := pdata.NewHistogramDataPoint() + hdp.SetExplicitBounds(bounds) + hdp.SetBucketCounts(counts) + hdp.SetTimestamp(ts) + var sum float64 + var count uint64 + for i, bcount := range counts { + count += bcount + if i > 0 { + sum += float64(bcount) * bounds[i-1] + } + } + hdp.SetCount(count) + hdp.SetSum(sum) + + return &hdp +} + +func cumulativeDistMetricPdata(name string, kvp []*kv, startTs pdata.Timestamp, points ...*pdata.HistogramDataPoint) *pdata.Metric { + metric := pdata.NewMetric() + metric.SetName(name) + metric.SetDataType(pdata.MetricDataTypeHistogram) + histogram := metric.Histogram() + histogram.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + + destPointL := histogram.DataPoints() + // By default the AggregationTemporality is Cumulative until it'll be changed by the caller. + for _, point := range points { + destPoint := destPointL.AppendEmpty() + point.CopyTo(destPoint) + point.SetStartTimestamp(startTs) + attrs := destPoint.Attributes() + for _, kv := range kvp { + attrs.InsertString(kv.Key, kv.Value) + } + } + return &metric +} + +func doublePointPdata(ts pdata.Timestamp, value float64) *pdata.NumberDataPoint { + ndp := pdata.NewNumberDataPoint() + ndp.SetTimestamp(ts) + ndp.SetDoubleVal(value) + + return &ndp +} + +func gaugeMetricPdata(name string, kvp []*kv, startTs pdata.Timestamp, points ...*pdata.NumberDataPoint) *pdata.Metric { + metric := pdata.NewMetric() + metric.SetName(name) + metric.SetDataType(pdata.MetricDataTypeGauge) + + destPointL := metric.Gauge().DataPoints() + for _, point := range points { + destPoint := destPointL.AppendEmpty() + point.CopyTo(destPoint) + point.SetStartTimestamp(startTs) + attrs := destPoint.Attributes() + for _, kv := range kvp { + attrs.InsertString(kv.Key, kv.Value) + } + } + return &metric +} + +func summaryPointPdata(ts pdata.Timestamp, count uint64, sum float64, quantiles, values []float64) *pdata.SummaryDataPoint { + sdp := pdata.NewSummaryDataPoint() + sdp.SetTimestamp(ts) + sdp.SetCount(count) + sdp.SetSum(sum) + qvL := sdp.QuantileValues() + for i := 0; i < len(quantiles); i++ { + qvi := qvL.AppendEmpty() + qvi.SetQuantile(quantiles[i]) + qvi.SetValue(values[i]) + } + return &sdp +} + +func summaryMetricPdata(name string, kvp []*kv, startTs pdata.Timestamp, points ...*pdata.SummaryDataPoint) *pdata.Metric { + metric := pdata.NewMetric() + metric.SetName(name) + metric.SetDataType(pdata.MetricDataTypeSummary) + + destPointL := metric.Summary().DataPoints() + for _, point := range points { + destPoint := destPointL.AppendEmpty() + point.CopyTo(destPoint) + point.SetStartTimestamp(startTs) + attrs := destPoint.Attributes() + for _, kv := range kvp { + attrs.InsertString(kv.Key, kv.Value) + } + } + return &metric +} + +func sumMetricPdata(name string, kvp []*kv, startTs pdata.Timestamp, points ...*pdata.NumberDataPoint) *pdata.Metric { + metric := pdata.NewMetric() + metric.SetName(name) + metric.SetDataType(pdata.MetricDataTypeSum) + sum := metric.Sum() + sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum.SetIsMonotonic(true) + + destPointL := sum.DataPoints() + for _, point := range points { + destPoint := destPointL.AppendEmpty() + point.CopyTo(destPoint) + point.SetStartTimestamp(startTs) + attrs := destPoint.Attributes() + for _, kv := range kvp { + attrs.InsertString(kv.Key, kv.Value) + } + } + return &metric +} diff --git a/receiver/prometheusreceiver/internal/ocastore.go b/receiver/prometheusreceiver/internal/ocastore.go index 85804da115c7f..84f572452aba6 100644 --- a/receiver/prometheusreceiver/internal/ocastore.go +++ b/receiver/prometheusreceiver/internal/ocastore.go @@ -18,6 +18,7 @@ import ( "context" "errors" "sync/atomic" + "time" "github.com/prometheus/prometheus/pkg/exemplar" "github.com/prometheus/prometheus/pkg/labels" @@ -44,11 +45,13 @@ type OcaStore struct { running int32 // access atomically sink consumer.Metrics mc *metadataService - jobsMap *JobsMap + jobsMapPdata *JobsMapPdata + jobsMapOC *JobsMap useStartTimeMetric bool startTimeMetricRegex string receiverID config.ComponentID externalLabels labels.Labels + pdataDirect bool settings component.ReceiverCreateSettings } @@ -58,21 +61,29 @@ func NewOcaStore( ctx context.Context, sink consumer.Metrics, set component.ReceiverCreateSettings, - jobsMap *JobsMap, useStartTimeMetric bool, startTimeMetricRegex string, receiverID config.ComponentID, - externalLabels labels.Labels) *OcaStore { + externalLabels labels.Labels, + pdataDirect bool) *OcaStore { + var jobsMapPdata *JobsMapPdata + var jobsMapOC *JobsMap + if !useStartTimeMetric { + jobsMapPdata = NewJobsMapPdata(2 * time.Minute) + jobsMapOC = NewJobsMap(2 * time.Minute) + } return &OcaStore{ running: runningStateInit, ctx: ctx, sink: sink, settings: set, - jobsMap: jobsMap, + jobsMapPdata: jobsMapPdata, + jobsMapOC: jobsMapOC, useStartTimeMetric: useStartTimeMetric, startTimeMetricRegex: startTimeMetricRegex, receiverID: receiverID, externalLabels: externalLabels, + pdataDirect: pdataDirect, } } @@ -87,9 +98,24 @@ func (o *OcaStore) SetScrapeManager(scrapeManager *scrape.Manager) { func (o *OcaStore) Appender(context.Context) storage.Appender { state := atomic.LoadInt32(&o.running) if state == runningStateReady { + if o.pdataDirect { + return newTransactionPdata( + o.ctx, + &txConfig{ + jobsMap: o.jobsMapPdata, + useStartTimeMetric: o.useStartTimeMetric, + startTimeMetricRegex: o.startTimeMetricRegex, + receiverID: o.receiverID, + ms: o.mc, + sink: o.sink, + externalLabels: o.externalLabels, + settings: o.settings, + }, + ) + } return newTransaction( o.ctx, - o.jobsMap, + o.jobsMapOC, o.useStartTimeMetric, o.startTimeMetricRegex, o.receiverID, diff --git a/receiver/prometheusreceiver/internal/ocastore_test.go b/receiver/prometheusreceiver/internal/ocastore_test.go index bf0adeb5a7e52..a9a6c46e7d270 100644 --- a/receiver/prometheusreceiver/internal/ocastore_test.go +++ b/receiver/prometheusreceiver/internal/ocastore_test.go @@ -26,7 +26,7 @@ import ( ) func TestOcaStore(t *testing.T) { - o := NewOcaStore(context.Background(), nil, testTelemetry.ToReceiverCreateSettings(), nil, false, "", config.NewComponentID("prometheus"), nil) + o := NewOcaStore(context.Background(), nil, testTelemetry.ToReceiverCreateSettings(), false, "", config.NewComponentID("prometheus"), nil, false) o.SetScrapeManager(&scrape.Manager{}) app := o.Appender(context.Background()) diff --git a/receiver/prometheusreceiver/internal/otlp_metricfamily.go b/receiver/prometheusreceiver/internal/otlp_metricfamily.go index f39dc6c9abbe7..e3f82b7e819d2 100644 --- a/receiver/prometheusreceiver/internal/otlp_metricfamily.go +++ b/receiver/prometheusreceiver/internal/otlp_metricfamily.go @@ -15,43 +15,55 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal" import ( + "fmt" "sort" "strings" + "time" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/textparse" + "github.com/prometheus/prometheus/scrape" "go.opentelemetry.io/collector/model/pdata" + "go.uber.org/zap" ) // MetricFamilyPdata is unit which is corresponding to the metrics items which shared the same TYPE/UNIT/... metadata from // a single scrape. type MetricFamilyPdata interface { Add(metricName string, ls labels.Labels, t int64, v float64) error - IsSameFamily(metricName string) bool ToMetricPdata(metrics *pdata.MetricSlice) (int, int) } type metricFamilyPdata struct { - // We are composing the already present metricFamily to - // make for a scalable migration, so that we only edit target - // fields progressively, when we are ready to make changes. - metricFamily - mtype pdata.MetricDataType - groups map[string]*metricGroupPdata + mtype pdata.MetricDataType + groups map[string]*metricGroupPdata + name string + mc MetadataCache + droppedTimeseries int + labelKeys map[string]bool + labelKeysOrdered []string + metadata *scrape.MetricMetadata + groupOrders map[string]int + intervalStartTimeMs int64 } // metricGroupPdata, represents a single metric of a metric family. for example a histogram metric is usually represent by // a couple data complexValue (buckets and count/sum), a group of a metric family always share a same set of tags. for // simple types like counter and gauge, each data point is a group of itself type metricGroupPdata struct { - // We are composing the already present metricGroup to - // make for a scalable migration, so that we only edit target - // fields progressively, when we are ready to make changes. - metricGroup - family *metricFamilyPdata + family *metricFamilyPdata + ts int64 + ls labels.Labels + count float64 + hasCount bool + sum float64 + hasSum bool + value float64 + complexValue []*dataPoint + intervalStartTimeMs int64 } -func newMetricFamilyPdata(metricName string, mc MetadataCache, intervalStartTimeMs int64) MetricFamilyPdata { +func newMetricFamilyPdata(metricName string, mc MetadataCache, logger *zap.Logger, intervalStartTimeMs int64) MetricFamilyPdata { familyName := normalizeMetricName(metricName) // lookup metadata based on familyName @@ -68,11 +80,19 @@ func newMetricFamilyPdata(metricName string, mc MetadataCache, intervalStartTime metadata.Type = textparse.MetricTypeUnknown } } else if !ok { - // Prometheus sends metrics without a type hint as gauges. - // MetricTypeUnknown is converted to a gauge in convToOCAMetricType() - metadata.Type = textparse.MetricTypeUnknown + if isInternalMetric(metricName) { + metadata = defineInternalMetric(metricName, metadata, logger) + } else { + // Prometheus sends metrics without a type hint as gauges. + // MetricTypeUnknown is converted to a gauge in convToOCAMetricType() + metadata.Type = textparse.MetricTypeUnknown + } } + mtype := convToPdataMetricType(metadata.Type) + if mtype == pdata.MetricDataTypeNone { + logger.Debug(fmt.Sprintf("Invalid metric : %s %+v", metricName, metadata)) + } // If a counter has a _total suffix but metadata is stored without it, keep _total suffix as the name otherwise // the metric sent won't have the suffix @@ -81,18 +101,16 @@ func newMetricFamilyPdata(metricName string, mc MetadataCache, intervalStartTime } return &metricFamilyPdata{ - mtype: mtype, - groups: make(map[string]*metricGroupPdata), - metricFamily: metricFamily{ - name: familyName, - mc: mc, - droppedTimeseries: 0, - labelKeys: make(map[string]bool), - labelKeysOrdered: make([]string, 0), - metadata: &metadata, - groupOrders: make(map[string]int), - intervalStartTimeMs: intervalStartTimeMs, - }, + mtype: mtype, + groups: make(map[string]*metricGroupPdata), + name: familyName, + mc: mc, + droppedTimeseries: 0, + labelKeys: make(map[string]bool), + labelKeysOrdered: make([]string, 0), + metadata: &metadata, + groupOrders: make(map[string]int), + intervalStartTimeMs: intervalStartTimeMs, } } @@ -120,6 +138,12 @@ func (mf *metricFamilyPdata) getGroupKey(ls labels.Labels) string { return dpgSignature(mf.labelKeysOrdered, ls) } +func (mg *metricGroupPdata) sortPoints() { + sort.Slice(mg.complexValue, func(i, j int) bool { + return mg.complexValue[i].boundary < mg.complexValue[j].boundary + }) +} + func (mg *metricGroupPdata) toDistributionPoint(orderedLabelKeys []string, dest *pdata.HistogramDataPointSlice) bool { if !mg.hasCount || len(mg.complexValue) == 0 { return false @@ -150,14 +174,21 @@ func (mg *metricGroupPdata) toDistributionPoint(orderedLabelKeys []string, dest point.SetSum(mg.sum) point.SetBucketCounts(bucketCounts) // The timestamp MUST be in retrieved from milliseconds and converted to nanoseconds. - tsNanos := pdata.Timestamp(mg.ts * 1e6) - point.SetStartTimestamp(tsNanos) + tsNanos := pdataTimestampFromMs(mg.ts) + if mg.family.isCumulativeTypePdata() { + point.SetStartTimestamp(pdataTimestampFromMs(mg.intervalStartTimeMs)) + } point.SetTimestamp(tsNanos) populateAttributesPdata(orderedLabelKeys, mg.ls, point.Attributes()) return true } +func pdataTimestampFromMs(timeAtMs int64) pdata.Timestamp { + secs, ns := timeAtMs/1e3, (timeAtMs%1e3)*1e6 + return pdata.NewTimestampFromTime(time.Unix(secs, ns)) +} + func (mg *metricGroupPdata) toSummaryPoint(orderedLabelKeys []string, dest *pdata.SummaryDataPointSlice) bool { // expecting count to be provided, however, in the following two cases, they can be missed. // 1. data is corrupted @@ -173,7 +204,7 @@ func (mg *metricGroupPdata) toSummaryPoint(orderedLabelKeys []string, dest *pdat for _, p := range mg.complexValue { quantile := quantileValues.AppendEmpty() quantile.SetValue(p.value) - quantile.SetQuantile(p.boundary * 100) + quantile.SetQuantile(p.boundary) } // Based on the summary description from https://prometheus.io/docs/concepts/metric_types/#summary @@ -181,9 +212,11 @@ func (mg *metricGroupPdata) toSummaryPoint(orderedLabelKeys []string, dest *pdat // observations and the corresponding sum is a sum of all observed values, thus the sum and count used // at the global level of the metricspb.SummaryValue // The timestamp MUST be in retrieved from milliseconds and converted to nanoseconds. - tsNanos := pdata.Timestamp(mg.ts * 1e6) - point.SetStartTimestamp(tsNanos) + tsNanos := pdataTimestampFromMs(mg.ts) point.SetTimestamp(tsNanos) + if mg.family.isCumulativeTypePdata() { + point.SetStartTimestamp(pdataTimestampFromMs(mg.intervalStartTimeMs)) + } point.SetSum(mg.sum) point.SetCount(uint64(mg.count)) populateAttributesPdata(orderedLabelKeys, mg.ls, point.Attributes()) @@ -193,10 +226,10 @@ func (mg *metricGroupPdata) toSummaryPoint(orderedLabelKeys []string, dest *pdat func (mg *metricGroupPdata) toNumberDataPoint(orderedLabelKeys []string, dest *pdata.NumberDataPointSlice) bool { var startTsNanos pdata.Timestamp - tsNanos := pdata.Timestamp(mg.ts * 1e6) + tsNanos := pdataTimestampFromMs(mg.ts) // gauge/undefined types have no start time. if mg.family.isCumulativeTypePdata() { - startTsNanos = pdata.Timestamp(mg.intervalStartTimeMs * 1e6) + startTsNanos = pdataTimestampFromMs(mg.intervalStartTimeMs) } point := dest.AppendEmpty() @@ -211,6 +244,10 @@ func (mg *metricGroupPdata) toNumberDataPoint(orderedLabelKeys []string, dest *p func populateAttributesPdata(orderedKeys []string, ls labels.Labels, dest pdata.AttributeMap) { src := ls.Map() for _, key := range orderedKeys { + if src[key] == "" { + // empty label values should be omitted + continue + } dest.InsertString(key, src[key]) } } @@ -228,13 +265,11 @@ func (mf *metricFamilyPdata) loadMetricGroupOrCreate(groupKey string, ls labels. mg, ok := mf.groups[groupKey] if !ok { mg = &metricGroupPdata{ - family: mf, - metricGroup: metricGroup{ - ts: ts, - ls: ls, - complexValue: make([]*dataPoint, 0), - intervalStartTimeMs: mf.intervalStartTimeMs, - }, + family: mf, + ts: ts, + ls: ls, + complexValue: make([]*dataPoint, 0), + intervalStartTimeMs: mf.intervalStartTimeMs, } mf.groups[groupKey] = mg // maintaining data insertion order is helpful to generate stable/reproducible metric output @@ -284,11 +319,15 @@ func (mf *metricFamilyPdata) getGroups() []*metricGroupPdata { func (mf *metricFamilyPdata) ToMetricPdata(metrics *pdata.MetricSlice) (int, int) { metric := pdata.NewMetric() + metric.SetDataType(mf.mtype) + metric.SetName(mf.name) + pointCount := 0 switch mf.mtype { case pdata.MetricDataTypeHistogram: histogram := metric.Histogram() + histogram.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) hdpL := histogram.DataPoints() for _, mg := range mf.getGroups() { if !mg.toDistributionPoint(mf.labelKeysOrdered, &hdpL) { @@ -309,6 +348,8 @@ func (mf *metricFamilyPdata) ToMetricPdata(metrics *pdata.MetricSlice) (int, int case pdata.MetricDataTypeSum: sum := metric.Sum() + sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum.SetIsMonotonic(true) sdpL := sum.DataPoints() for _, mg := range mf.getGroups() { if !mg.toNumberDataPoint(mf.labelKeysOrdered, &sdpL) { @@ -317,7 +358,8 @@ func (mf *metricFamilyPdata) ToMetricPdata(metrics *pdata.MetricSlice) (int, int } pointCount = sdpL.Len() - default: + default: // Everything else should be set to a Gauge. + metric.SetDataType(pdata.MetricDataTypeGauge) gauge := metric.Gauge() gdpL := gauge.DataPoints() for _, mg := range mf.getGroups() { diff --git a/receiver/prometheusreceiver/internal/otlp_metricfamily_test.go b/receiver/prometheusreceiver/internal/otlp_metricfamily_test.go index 33592c6717521..1fb678e99963e 100644 --- a/receiver/prometheusreceiver/internal/otlp_metricfamily_test.go +++ b/receiver/prometheusreceiver/internal/otlp_metricfamily_test.go @@ -15,13 +15,11 @@ package internal import ( - "fmt" "testing" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/textparse" "github.com/prometheus/prometheus/scrape" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/model/pdata" "go.uber.org/zap" @@ -77,31 +75,6 @@ var mc = byLookupMetadataCache{ }, } -func TestIsCumulativeEquivalence(t *testing.T) { - tests := []struct { - name string - want bool - }{ - {name: "counter", want: true}, - {name: "gauge", want: false}, - {name: "histogram", want: true}, - {name: "gaugehistogram", want: false}, - {name: "does not exist", want: false}, - {name: "unknown", want: false}, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - mf := newMetricFamily(tt.name, mc, zap.NewNop(), 1).(*metricFamily) - mfp := newMetricFamilyPdata(tt.name, mc, 1).(*metricFamilyPdata) - assert.Equal(t, mf.isCumulativeType(), mfp.isCumulativeTypePdata(), "mismatch in isCumulative") - assert.Equal(t, mf.isCumulativeType(), tt.want, "isCumulative does not match for regular metricFamily") - assert.Equal(t, mfp.isCumulativeTypePdata(), tt.want, "isCumulative does not match for pdata metricFamily") - }) - } -} - func TestMetricGroupData_toDistributionUnitTest(t *testing.T) { type scrape struct { at int64 @@ -119,7 +92,7 @@ func TestMetricGroupData_toDistributionUnitTest(t *testing.T) { { name: "histogram with startTimestamp of 11", metricName: "histogram", - intervalStartTimeMs: 1717, + intervalStartTimeMs: 11, labels: labels.Labels{{Name: "a", Value: "A"}, {Name: "le", Value: "0.75"}, {Name: "b", Value: "B"}}, scrapes: []*scrape{ {at: 11, value: 10, metric: "histogram_count"}, @@ -145,7 +118,7 @@ func TestMetricGroupData_toDistributionUnitTest(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - mp := newMetricFamilyPdata(tt.metricName, mc, tt.intervalStartTimeMs).(*metricFamilyPdata) + mp := newMetricFamilyPdata(tt.metricName, mc, zap.NewNop(), tt.intervalStartTimeMs).(*metricFamilyPdata) for _, tv := range tt.scrapes { require.NoError(t, mp.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) } @@ -164,93 +137,6 @@ func TestMetricGroupData_toDistributionUnitTest(t *testing.T) { } } -func TestMetricGroupData_toDistributionPointEquivalence(t *testing.T) { - type scrape struct { - at int64 - value float64 - metric string - } - tests := []struct { - name string - labels labels.Labels - scrapes []*scrape - }{ - { - name: "histogram", - labels: labels.Labels{{Name: "a", Value: "A"}, {Name: "le", Value: "0.75"}, {Name: "b", Value: "B"}}, - scrapes: []*scrape{ - {at: 11, value: 10, metric: "histogram_count"}, - {at: 11, value: 1004.78, metric: "histogram_sum"}, - {at: 13, value: 33.7, metric: "value"}, - }, - }, - } - - for i, tt := range tests { - tt := tt - intervalStartTimeMs := int64(i + 1) - t.Run(tt.name, func(t *testing.T) { - mf := newMetricFamily(tt.name, mc, zap.NewNop(), intervalStartTimeMs).(*metricFamily) - mp := newMetricFamilyPdata(tt.name, mc, intervalStartTimeMs).(*metricFamilyPdata) - for _, tv := range tt.scrapes { - require.NoError(t, mp.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - require.NoError(t, mf.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - } - groupKey := mf.getGroupKey(tt.labels.Copy()) - ocTimeseries := mf.groups[groupKey].toDistributionTimeSeries(mf.labelKeysOrdered) - hdpL := pdata.NewHistogramDataPointSlice() - require.True(t, mp.groups[groupKey].toDistributionPoint(mp.labelKeysOrdered, &hdpL)) - require.Equal(t, len(ocTimeseries.Points), hdpL.Len(), "They should have the exact same number of points") - require.Equal(t, 1, hdpL.Len(), "Exactly one point expected") - ocPoint := ocTimeseries.Points[0] - pdataPoint := hdpL.At(0) - // 1. Ensure that the startTimestamps are equal. - require.Equal(t, ocTimeseries.GetStartTimestamp().AsTime(), pdataPoint.Timestamp().AsTime(), "The timestamp must be equal") - // 2. Ensure that the count is equal. - ocHistogram := ocPoint.GetDistributionValue() - require.Equal(t, ocHistogram.GetCount(), int64(pdataPoint.Count()), "Count must be equal") - // 3. Ensure that the sum is equal. - require.Equal(t, ocHistogram.GetSum(), pdataPoint.Sum(), "Sum must be equal") - // 4. Ensure that the point's timestamp is equal to that from the OpenCensusProto data point. - require.Equal(t, ocPoint.GetTimestamp().AsTime(), pdataPoint.Timestamp().AsTime(), "Point timestamps must be equal") - // 5. Ensure that bucket bounds are the same. - require.Equal(t, len(ocHistogram.GetBuckets()), len(pdataPoint.BucketCounts()), "Bucket counts must have the same length") - var ocBucketCounts []uint64 - for i, bucket := range ocHistogram.GetBuckets() { - ocBucketCounts = append(ocBucketCounts, uint64(bucket.GetCount())) - - // 6. Ensure that the exemplars match. - ocExemplar := bucket.Exemplar - if ocExemplar == nil { - if i >= pdataPoint.Exemplars().Len() { // Both have the exact same number of exemplars. - continue - } - // Otherwise an exemplar is present for the pdata data point but not for the OpenCensus Proto histogram. - t.Fatalf("Exemplar #%d is ONLY present in the pdata point but not in the OpenCensus Proto histogram", i) - } - pdataExemplar := pdataPoint.Exemplars().At(i) - msgPrefix := fmt.Sprintf("Exemplar #%d:: ", i) - require.Equal(t, ocExemplar.Timestamp.AsTime(), pdataExemplar.Timestamp().AsTime(), msgPrefix+"timestamp mismatch") - require.Equal(t, ocExemplar.Value, pdataExemplar.DoubleVal(), msgPrefix+"value mismatch") - pdataExemplarAttachments := make(map[string]string) - pdataExemplar.FilteredAttributes().Range(func(key string, value pdata.AttributeValue) bool { - pdataExemplarAttachments[key] = value.AsString() - return true - }) - require.Equal(t, ocExemplar.Attachments, pdataExemplarAttachments, msgPrefix+"attachments mismatch") - } - // 7. Ensure that bucket bounds are the same. - require.Equal(t, ocBucketCounts, pdataPoint.BucketCounts(), "Bucket counts must be equal") - // 8. Ensure that the labels all match up. - ocStringMap := pdata.NewAttributeMap() - for i, labelValue := range ocTimeseries.LabelValues { - ocStringMap.InsertString(mf.labelKeysOrdered[i], labelValue.Value) - } - require.Equal(t, ocStringMap.Sort(), pdataPoint.Attributes().Sort()) - }) - } -} - func TestMetricGroupData_toSummaryUnitTest(t *testing.T) { type scrape struct { at int64 @@ -330,19 +216,19 @@ func TestMetricGroupData_toSummaryUnitTest(t *testing.T) { qn0.SetQuantile(0) qn0.SetValue(8) qn50 := qtL.AppendEmpty() - qn50.SetQuantile(50) + qn50.SetQuantile(.5) qn50.SetValue(27) qn75 := qtL.AppendEmpty() - qn75.SetQuantile(75) + qn75.SetQuantile(.75) qn75.SetValue(33.7) qn90 := qtL.AppendEmpty() - qn90.SetQuantile(90) + qn90.SetQuantile(.9) qn90.SetValue(56) qn99 := qtL.AppendEmpty() - qn99.SetQuantile(99) + qn99.SetQuantile(.99) qn99.SetValue(82) point.SetTimestamp(14 * 1e6) // the time in milliseconds -> nanoseconds. - point.SetStartTimestamp(14 * 1e6) + point.SetStartTimestamp(10 * 1e5) attributes := point.Attributes() attributes.InsertString("a", "A") attributes.InsertString("b", "B") @@ -354,7 +240,7 @@ func TestMetricGroupData_toSummaryUnitTest(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - mp := newMetricFamilyPdata(tt.name, mc, 1).(*metricFamilyPdata) + mp := newMetricFamilyPdata(tt.name, mc, zap.NewNop(), 1).(*metricFamilyPdata) for _, lbs := range tt.labelsScrapes { for _, scrape := range lbs.scrapes { require.NoError(t, mp.Add(scrape.metric, lbs.labels.Copy(), scrape.at, scrape.value)) @@ -379,77 +265,6 @@ func TestMetricGroupData_toSummaryUnitTest(t *testing.T) { } } -func TestMetricGroupData_toSummaryPointEquivalence(t *testing.T) { - type scrape struct { - at int64 - value float64 - metric string - } - tests := []struct { - name string - labels labels.Labels - scrapes []*scrape - }{ - { - name: "summary", - labels: labels.Labels{{Name: "a", Value: "A"}, {Name: "quantile", Value: "0.75"}, {Name: "b", Value: "B"}}, - scrapes: []*scrape{ - {at: 11, value: 10, metric: "summary_count"}, - {at: 11, value: 1004.78, metric: "summary_sum"}, - {at: 13, value: 33.7, metric: "value"}, - }, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - mf := newMetricFamily(tt.name, mc, zap.NewNop(), 1).(*metricFamily) - mp := newMetricFamilyPdata(tt.name, mc, 1).(*metricFamilyPdata) - for _, tv := range tt.scrapes { - require.NoError(t, mp.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - require.NoError(t, mf.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - } - groupKey := mf.getGroupKey(tt.labels.Copy()) - ocTimeseries := mf.groups[groupKey].toSummaryTimeSeries(mf.labelKeysOrdered) - sdpL := pdata.NewSummaryDataPointSlice() - require.True(t, mp.groups[groupKey].toSummaryPoint(mp.labelKeysOrdered, &sdpL)) - require.Equal(t, len(ocTimeseries.Points), sdpL.Len(), "They should have the exact same number of points") - require.Equal(t, 1, sdpL.Len(), "Exactly one point expected") - ocPoint := ocTimeseries.Points[0] - pdataPoint := sdpL.At(0) - // 1. Ensure that the startTimestamps are equal. - require.Equal(t, ocTimeseries.GetStartTimestamp().AsTime(), pdataPoint.Timestamp().AsTime(), "The timestamp must be equal") - // 2. Ensure that the count is equal. - ocSummary := ocPoint.GetSummaryValue() - if false { - t.Logf("\nOcSummary: %#v\nPdSummary: %#v\n\nocPoint: %#v\n", ocSummary, pdataPoint, ocPoint.GetSummaryValue()) - return - } - require.Equal(t, ocSummary.GetCount().GetValue(), int64(pdataPoint.Count()), "Count must be equal") - // 3. Ensure that the sum is equal. - require.Equal(t, ocSummary.GetSum().GetValue(), pdataPoint.Sum(), "Sum must be equal") - // 4. Ensure that the point's timestamp is equal to that from the OpenCensusProto data point. - require.Equal(t, ocPoint.GetTimestamp().AsTime(), pdataPoint.Timestamp().AsTime(), "Point timestamps must be equal") - // 5. Ensure that the labels all match up. - ocStringMap := pdata.NewAttributeMap() - for i, labelValue := range ocTimeseries.LabelValues { - ocStringMap.InsertString(mf.labelKeysOrdered[i], labelValue.Value) - } - require.Equal(t, ocStringMap.Sort(), pdataPoint.Attributes().Sort()) - // 6. Ensure that the quantile values all match up. - ocQuantiles := ocSummary.GetSnapshot().GetPercentileValues() - pdataQuantiles := pdataPoint.QuantileValues() - require.Equal(t, len(ocQuantiles), pdataQuantiles.Len()) - for i, ocQuantile := range ocQuantiles { - pdataQuantile := pdataQuantiles.At(i) - require.Equal(t, ocQuantile.Percentile, pdataQuantile.Quantile(), "The quantile percentiles must match") - require.Equal(t, ocQuantile.Value, pdataQuantile.Value(), "The quantile values must match") - } - }) - } -} - func TestMetricGroupData_toNumberDataUnitTest(t *testing.T) { type scrape struct { at int64 @@ -507,7 +322,7 @@ func TestMetricGroupData_toNumberDataUnitTest(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - mp := newMetricFamilyPdata(tt.metricKind, mc, tt.intervalStartTimestampMs).(*metricFamilyPdata) + mp := newMetricFamilyPdata(tt.metricKind, mc, zap.NewNop(), tt.intervalStartTimestampMs).(*metricFamilyPdata) for _, tv := range tt.scrapes { require.NoError(t, mp.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) } @@ -525,61 +340,3 @@ func TestMetricGroupData_toNumberDataUnitTest(t *testing.T) { }) } } - -func TestMetricGroupData_toNumberDataPointEquivalence(t *testing.T) { - type scrape struct { - at int64 - value float64 - metric string - } - tests := []struct { - name string - labels labels.Labels - scrapes []*scrape - wantValue float64 - }{ - { - name: "counter", - labels: labels.Labels{{Name: "a", Value: "A"}, {Name: "b", Value: "B"}}, - scrapes: []*scrape{ - {at: 13, value: 33.7, metric: "value"}, - }, - wantValue: 33.7, - }, - } - - for i, tt := range tests { - tt := tt - intervalStartTimeMs := int64(11 + i) - t.Run(tt.name, func(t *testing.T) { - mf := newMetricFamily(tt.name, mc, zap.NewNop(), intervalStartTimeMs).(*metricFamily) - mp := newMetricFamilyPdata(tt.name, mc, intervalStartTimeMs).(*metricFamilyPdata) - for _, tv := range tt.scrapes { - require.NoError(t, mp.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - require.NoError(t, mf.Add(tv.metric, tt.labels.Copy(), tv.at, tv.value)) - } - groupKey := mf.getGroupKey(tt.labels.Copy()) - ocTimeseries := mf.groups[groupKey].toDoubleValueTimeSeries(mf.labelKeysOrdered) - ddpL := pdata.NewNumberDataPointSlice() - require.True(t, mp.groups[groupKey].toNumberDataPoint(mp.labelKeysOrdered, &ddpL)) - require.Equal(t, len(ocTimeseries.Points), ddpL.Len(), "They should have the exact same number of points") - require.Equal(t, 1, ddpL.Len(), "Exactly one point expected") - ocPoint := ocTimeseries.Points[0] - pdataPoint := ddpL.At(0) - // 1. Ensure that the startTimestamps are equal. - require.Equal(t, ocTimeseries.GetStartTimestamp().AsTime(), pdataPoint.StartTimestamp().AsTime(), "The timestamp must be equal") - require.Equal(t, intervalStartTimeMs*1e6, pdataPoint.StartTimestamp().AsTime().UnixNano(), "intervalStartTimeMs must be the same") - // 2. Ensure that the value is equal. - require.Equal(t, ocPoint.GetDoubleValue(), pdataPoint.DoubleVal(), "Values must be equal") - require.Equal(t, tt.wantValue, pdataPoint.DoubleVal(), "Values must be equal") - // 4. Ensure that the point's timestamp is equal to that from the OpenCensusProto data point. - require.Equal(t, ocPoint.GetTimestamp().AsTime(), pdataPoint.Timestamp().AsTime(), "Point timestamps must be equal") - // 5. Ensure that the labels all match up. - ocStringMap := pdata.NewAttributeMap() - for i, labelValue := range ocTimeseries.LabelValues { - ocStringMap.InsertString(mf.labelKeysOrdered[i], labelValue.Value) - } - require.Equal(t, ocStringMap.Sort(), pdataPoint.Attributes().Sort()) - }) - } -} diff --git a/receiver/prometheusreceiver/internal/otlp_metrics_adjuster.go b/receiver/prometheusreceiver/internal/otlp_metrics_adjuster.go new file mode 100644 index 0000000000000..3138f9728c3a5 --- /dev/null +++ b/receiver/prometheusreceiver/internal/otlp_metrics_adjuster.go @@ -0,0 +1,450 @@ +// Copyright The OpenTelemetry Authors +// +// 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 internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal" + +import ( + "fmt" + "strings" + "sync" + "time" + + "go.opentelemetry.io/collector/model/pdata" + "go.uber.org/zap" +) + +// Notes on garbage collection (gc): +// +// Job-level gc: +// The Prometheus receiver will likely execute in a long running service whose lifetime may exceed +// the lifetimes of many of the jobs that it is collecting from. In order to keep the JobsMap from +// leaking memory for entries of no-longer existing jobs, the JobsMap needs to remove entries that +// haven't been accessed for a long period of time. +// +// Timeseries-level gc: +// Some jobs that the Prometheus receiver is collecting from may export timeseries based on metrics +// from other jobs (e.g. cAdvisor). In order to keep the timeseriesMap from leaking memory for entries +// of no-longer existing jobs, the timeseriesMap for each job needs to remove entries that haven't +// been accessed for a long period of time. +// +// The gc strategy uses a standard mark-and-sweep approach - each time a timeseriesMap is accessed, +// it is marked. Similarly, each time a timeseriesinfo is accessed, it is also marked. +// +// At the end of each JobsMap.get(), if the last time the JobsMap was gc'd exceeds the 'gcInterval', +// the JobsMap is locked and any timeseriesMaps that are unmarked are removed from the JobsMap +// otherwise the timeseriesMap is gc'd +// +// The gc for the timeseriesMap is straightforward - the map is locked and, for each timeseriesinfo +// in the map, if it has not been marked, it is removed otherwise it is unmarked. +// +// Alternative Strategies +// 1. If the job-level gc doesn't run often enough, or runs too often, a separate go routine can +// be spawned at JobMap creation time that gc's at periodic intervals. This approach potentially +// adds more contention and latency to each scrape so the current approach is used. Note that +// the go routine will need to be cancelled upon Shutdown(). +// 2. If the gc of each timeseriesMap during the gc of the JobsMap causes too much contention, +// the gc of timeseriesMaps can be moved to the end of MetricsAdjuster().AdjustMetrics(). This +// approach requires adding 'lastGC' Time and (potentially) a gcInterval duration to +// timeseriesMap so the current approach is used instead. + +// timeseriesinfo contains the information necessary to adjust from the initial point and to detect +// resets. +type timeseriesinfoPdata struct { + mark bool + initial *pdata.Metric + previous *pdata.Metric +} + +// timeseriesMap maps from a timeseries instance (metric * label values) to the timeseries info for +// the instance. +type timeseriesMapPdata struct { + sync.RWMutex + // The mutex is used to protect access to the member fields. It is acquired for the entirety of + // AdjustMetrics() and also acquired by gc(). + + mark bool + tsiMap map[string]*timeseriesinfoPdata +} + +// Get the timeseriesinfo for the timeseries associated with the metric and label values. +func (tsm *timeseriesMapPdata) get(metric *pdata.Metric, kv pdata.AttributeMap) *timeseriesinfoPdata { + // This should only be invoked be functions called (directly or indirectly) by AdjustMetrics(). + // The lock protecting tsm.tsiMap is acquired there. + name := metric.Name() + sig := getTimeseriesSignaturePdata(name, kv) + if metric.DataType() == pdata.MetricDataTypeHistogram { + // There are 2 types of Histograms whose aggregation temporality needs distinguishing: + // * CumulativeHistogram + // * GaugeHistogram + aggTemporality := metric.Histogram().AggregationTemporality() + sig += "," + aggTemporality.String() + } + tsi, ok := tsm.tsiMap[sig] + if !ok { + tsi = ×eriesinfoPdata{} + tsm.tsiMap[sig] = tsi + } + tsm.mark = true + tsi.mark = true + return tsi +} + +// Create a unique timeseries signature consisting of the metric name and label values. +func getTimeseriesSignaturePdata(name string, kv pdata.AttributeMap) string { + labelValues := make([]string, 0, kv.Len()) + kv.Sort().Range(func(_ string, attrValue pdata.AttributeValue) bool { + value := attrValue.StringVal() + if value != "" { + labelValues = append(labelValues, value) + } + return true + }) + return fmt.Sprintf("%s,%s", name, strings.Join(labelValues, ",")) +} + +// Remove timeseries that have aged out. +func (tsm *timeseriesMapPdata) gc() { + tsm.Lock() + defer tsm.Unlock() + // this shouldn't happen under the current gc() strategy + if !tsm.mark { + return + } + for ts, tsi := range tsm.tsiMap { + if !tsi.mark { + delete(tsm.tsiMap, ts) + } else { + tsi.mark = false + } + } + tsm.mark = false +} + +func newTimeseriesMapPdata() *timeseriesMapPdata { + return ×eriesMapPdata{mark: true, tsiMap: map[string]*timeseriesinfoPdata{}} +} + +// JobsMapPdata maps from a job instance to a map of timeseriesPdata instances for the job. +type JobsMapPdata struct { + sync.RWMutex + // The mutex is used to protect access to the member fields. It is acquired for most of + // get() and also acquired by gc(). + + gcInterval time.Duration + lastGC time.Time + jobsMap map[string]*timeseriesMapPdata +} + +// NewJobsMap creates a new (empty) JobsMapPdata. +func NewJobsMapPdata(gcInterval time.Duration) *JobsMapPdata { + return &JobsMapPdata{gcInterval: gcInterval, lastGC: time.Now(), jobsMap: make(map[string]*timeseriesMapPdata)} +} + +// Remove jobs and timeseries that have aged out. +func (jm *JobsMapPdata) gc() { + jm.Lock() + defer jm.Unlock() + // once the structure is locked, confirm that gc() is still necessary + if time.Since(jm.lastGC) > jm.gcInterval { + for sig, tsm := range jm.jobsMap { + tsm.RLock() + tsmNotMarked := !tsm.mark + // take a read lock here, no need to get a full lock as we have a lock on the JobsMapPdata + tsm.RUnlock() + if tsmNotMarked { + delete(jm.jobsMap, sig) + } else { + // a full lock will be obtained in here, if required. + tsm.gc() + } + } + jm.lastGC = time.Now() + } +} + +func (jm *JobsMapPdata) maybeGC() { + // speculatively check if gc() is necessary, recheck once the structure is locked + jm.RLock() + defer jm.RUnlock() + if time.Since(jm.lastGC) > jm.gcInterval { + go jm.gc() + } +} + +func (jm *JobsMapPdata) get(job, instance string) *timeseriesMapPdata { + sig := job + ":" + instance + // a read locke is taken here as we will not need to modify jobsMap if the target timeseriesMap is available. + jm.RLock() + tsm, ok := jm.jobsMap[sig] + jm.RUnlock() + defer jm.maybeGC() + if ok { + return tsm + } + jm.Lock() + defer jm.Unlock() + // Now that we've got an exclusive lock, check once more to ensure an entry wasn't created in the interim + // and then create a new timeseriesMap if required. + tsm2, ok2 := jm.jobsMap[sig] + if ok2 { + return tsm2 + } + tsm2 = newTimeseriesMapPdata() + jm.jobsMap[sig] = tsm2 + return tsm2 +} + +// MetricsAdjusterPdata takes a map from a metric instance to the initial point in the metrics instance +// and provides AdjustMetrics, which takes a sequence of metrics and adjust their start times based on +// the initial points. +type MetricsAdjusterPdata struct { + tsm *timeseriesMapPdata + logger *zap.Logger +} + +// NewMetricsAdjuster is a constructor for MetricsAdjuster. +func NewMetricsAdjusterPdata(tsm *timeseriesMapPdata, logger *zap.Logger) *MetricsAdjusterPdata { + return &MetricsAdjusterPdata{ + tsm: tsm, + logger: logger, + } +} + +// AdjustMetrics takes a sequence of metrics and adjust their start times based on the initial and +// previous points in the timeseriesMap. +// Returns the total number of timeseries that had reset start times. +func (ma *MetricsAdjusterPdata) AdjustMetrics(metricL *pdata.MetricSlice) int { + resets := 0 + // The lock on the relevant timeseriesMap is held throughout the adjustment process to ensure that + // nothing else can modify the data used for adjustment. + ma.tsm.Lock() + defer ma.tsm.Unlock() + for i := 0; i < metricL.Len(); i++ { + metric := metricL.At(i) + resets += ma.adjustMetric(&metric) + } + return resets +} + +// Returns the number of timeseries with reset start times. +func (ma *MetricsAdjusterPdata) adjustMetric(metric *pdata.Metric) int { + switch metric.DataType() { + case pdata.MetricDataTypeGauge: + // gauges don't need to be adjusted so no additional processing is necessary + return 0 + default: + return ma.adjustMetricPoints(metric) + } +} + +// Returns the number of timeseries that had reset start times. +func (ma *MetricsAdjusterPdata) adjustMetricPoints(metric *pdata.Metric) int { + switch dataType := metric.DataType(); dataType { + case pdata.MetricDataTypeGauge: + return ma.adjustMetricGauge(metric) + + case pdata.MetricDataTypeHistogram: + return ma.adjustMetricHistogram(metric) + + case pdata.MetricDataTypeSummary: + return ma.adjustMetricSummary(metric) + + case pdata.MetricDataTypeSum: + return ma.adjustMetricSum(metric) + + default: + // this shouldn't happen + ma.logger.Info("Adjust - skipping unexpected point", zap.String("type", dataType.String())) + return 0 + } +} + +// Returns true if 'current' was adjusted and false if 'current' is an the initial occurrence or a +// reset of the timeseries. +func (ma *MetricsAdjusterPdata) adjustMetricGauge(current *pdata.Metric) (resets int) { + currentPoints := current.Gauge().DataPoints() + + for i := 0; i < currentPoints.Len(); i++ { + currentGauge := currentPoints.At(i) + tsi := ma.tsm.get(current, currentGauge.Attributes()) + previous := tsi.previous + tsi.previous = current + if tsi.initial == nil { + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + initialPoints := tsi.initial.Gauge().DataPoints() + previousPoints := previous.Gauge().DataPoints() + if i >= initialPoints.Len() || i >= previousPoints.Len() { + ma.logger.Debug("Adjusting Points, all lengths should be equal", + zap.Int("len(current)", currentPoints.Len()), + zap.Int("len(initial)", initialPoints.Len()), + zap.Int("len(previous)", previousPoints.Len())) + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + + currentGauge, previousGauge := currentPoints.At(i), previousPoints.At(i) + if currentGauge.DoubleVal() < previousGauge.DoubleVal() { + // reset detected + tsi.initial = current + continue + } + initialGauge := initialPoints.At(i) + currentGauge.SetStartTimestamp(initialGauge.StartTimestamp()) + resets++ + } + return +} + +func (ma *MetricsAdjusterPdata) adjustMetricHistogram(current *pdata.Metric) (resets int) { + histogram := current.Histogram() + if histogram.AggregationTemporality() != pdata.MetricAggregationTemporalityCumulative { + // Only dealing with CumulativeDistributions. + return 0 + } + + // Note: Sum of Squared Deviation not currently supported. + currentPoints := histogram.DataPoints() + + if currentPoints.Len() == 0 { + return 0 + } + + for i := 0; i < currentPoints.Len(); i++ { + currentDist := currentPoints.At(i) + tsi := ma.tsm.get(current, currentDist.Attributes()) + previous := tsi.previous + tsi.previous = current + if tsi.initial == nil { + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + initialPoints := tsi.initial.Histogram().DataPoints() + previousPoints := previous.Histogram().DataPoints() + if i >= initialPoints.Len() || i >= previousPoints.Len() { + ma.logger.Debug("Adjusting Points, all lengths should be equal", + zap.Int("len(current)", currentPoints.Len()), + zap.Int("len(initial)", initialPoints.Len()), + zap.Int("len(previous)", previousPoints.Len())) + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + + previousDist := previousPoints.At(i) + if currentDist.Count() < previousDist.Count() || currentDist.Sum() < previousDist.Sum() { + // reset detected + tsi.initial = current + resets++ + continue + } + initialDist := initialPoints.At(i) + currentDist.SetStartTimestamp(initialDist.StartTimestamp()) + } + return +} + +func (ma *MetricsAdjusterPdata) adjustMetricSum(current *pdata.Metric) (resets int) { + currentPoints := current.Sum().DataPoints() + + for i := 0; i < currentPoints.Len(); i++ { + currentSum := currentPoints.At(i) + tsi := ma.tsm.get(current, currentSum.Attributes()) + previous := tsi.previous + tsi.previous = current + if tsi.initial == nil { + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + initialPoints := tsi.initial.Sum().DataPoints() + previousPoints := previous.Sum().DataPoints() + if i >= initialPoints.Len() || i >= previousPoints.Len() { + ma.logger.Debug("Adjusting Points, all lengths should be equal", + zap.Int("len(current)", currentPoints.Len()), + zap.Int("len(initial)", initialPoints.Len()), + zap.Int("len(previous)", previousPoints.Len())) + tsi.initial = current + resets++ + continue + } + + previousSum := previousPoints.At(i) + if currentSum.DoubleVal() < previousSum.DoubleVal() { + // reset detected + tsi.initial = current + resets++ + continue + } + initialSum := initialPoints.At(i) + currentSum.SetStartTimestamp(initialSum.StartTimestamp()) + } + + return +} + +func (ma *MetricsAdjusterPdata) adjustMetricSummary(current *pdata.Metric) (resets int) { + currentPoints := current.Summary().DataPoints() + + for i := 0; i < currentPoints.Len(); i++ { + currentSummary := currentPoints.At(i) + tsi := ma.tsm.get(current, currentSummary.Attributes()) + previous := tsi.previous + tsi.previous = current + if tsi.initial == nil { + // initial || reset timeseries. + tsi.initial = current + resets++ + continue + } + initialPoints := tsi.initial.Summary().DataPoints() + previousPoints := previous.Summary().DataPoints() + if i >= initialPoints.Len() || i >= previousPoints.Len() { + ma.logger.Debug("Adjusting Points, all lengths should be equal", + zap.Int("len(current)", currentPoints.Len()), + zap.Int("len(initial)", initialPoints.Len()), + zap.Int("len(previous)", previousPoints.Len())) + tsi.initial = current + resets++ + continue + } + + previousSummary := previousPoints.At(i) + if (currentSummary.Count() != 0 && + previousSummary.Count() != 0 && + currentSummary.Count() < previousSummary.Count()) || + + (currentSummary.Sum() != 0 && + previousSummary.Sum() != 0 && + currentSummary.Sum() < previousSummary.Sum()) { + // reset detected + tsi.initial = current + resets++ + continue + } + initialSummary := initialPoints.At(i) + currentSummary.SetStartTimestamp(initialSummary.StartTimestamp()) + } + + return +} diff --git a/receiver/prometheusreceiver/internal/otlp_metrics_adjuster_test.go b/receiver/prometheusreceiver/internal/otlp_metrics_adjuster_test.go new file mode 100644 index 0000000000000..57dfb2d2a0424 --- /dev/null +++ b/receiver/prometheusreceiver/internal/otlp_metrics_adjuster_test.go @@ -0,0 +1,843 @@ +// Copyright The OpenTelemetry Authors +// +// 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 internal + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/model/pdata" + "go.uber.org/zap" +) + +var ( + pdt1Ms = pdata.Timestamp(time.Unix(0, 1000000).UnixNano()) + pdt2Ms = pdata.Timestamp(time.Unix(0, 2000000).UnixNano()) + pdt3Ms = pdata.Timestamp(time.Unix(0, 3000000).UnixNano()) + pdt4Ms = pdata.Timestamp(time.Unix(0, 5000000).UnixNano()) + pdt5Ms = pdata.Timestamp(time.Unix(0, 5000000).UnixNano()) + + bounds0 = []float64{1, 2, 4} + percent0 = []float64{10, 50, 90} + + g1 = "gauge1" + gd1 = "gaugedist1" + c1 = "cumulative1" + cd1 = "cumulativedist1" + s1 = "summary1" + k1 = []string{"k1"} + k1k2 = []string{"k1", "k2"} + k1k2k3 = []string{"k1", "k2", "k3"} + v1v2 = []string{"v1", "v2"} + v10v20 = []string{"v10", "v20"} + v100v200 = []string{"v100", "v200"} +) + +func Test_gauge_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "Gauge: round 1 - gauge not adjusted", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt1Ms) + pt0.Attributes().InsertString("v1", "v2") + pt0.SetTimestamp(pdt1Ms) + pt0.SetDoubleVal(44) + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt1Ms) + pt0.Attributes().InsertString("v1", "v2") + pt0.SetTimestamp(pdt1Ms) + pt0.SetDoubleVal(44) + return &mL + }(), + 0, + }, + { + "Gauge: round 2 - gauge not adjusted", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt2Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt2Ms) + pt0.SetDoubleVal(66) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt2Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt2Ms) + pt0.SetDoubleVal(66) + return &mL + }(), + 0, + }, + { + "Gauge: round 3 - value less than previous value - gauge is not adjusted", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt3Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt3Ms) + pt0.SetDoubleVal(55) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeGauge) + m0.SetName("gauge1") + g0 := m0.Gauge() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt3Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt3Ms) + pt0.SetDoubleVal(55) + + return &mL + }(), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func Test_cumulative_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "Cumulative: round 1 - initial instance, start time is established", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt1Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt1Ms) + pt0.SetDoubleVal(44) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt1Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt1Ms) + pt0.SetDoubleVal(44) + + return &mL + }(), + 1, + }, + { + "Cumulative: round 2 - instance adjusted based on round 1", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt2Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt2Ms) + pt0.SetDoubleVal(66) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt1Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt2Ms) + pt0.SetDoubleVal(66) + + return &mL + }(), + 0, + }, + { + "Cumulative: round 3 - instance reset (value less than previous value), start time is reset", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt3Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt3Ms) + pt0.SetDoubleVal(55) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt3Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt3Ms) + pt0.SetDoubleVal(55) + + return &mL + }(), + 1, + }, + { + "Cumulative: round 4 - instance adjusted based on round 3", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt4Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt4Ms) + pt0.SetDoubleVal(72) + + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSum) + m0.SetName("cumulative1") + g0 := m0.Sum() + pt0 := g0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(pdt3Ms) + pt0.Attributes().InsertString("k1", "v1") + pt0.Attributes().InsertString("k2", "v2") + pt0.SetTimestamp(pdt4Ms) + pt0.SetDoubleVal(72) + + return &mL + }(), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func populateSummary(sdp *pdata.SummaryDataPoint, timestamp pdata.Timestamp, count uint64, sum float64, quantilePercents, quantileValues []float64) { + quantiles := sdp.QuantileValues() + for i := range quantilePercents { + qv := quantiles.AppendEmpty() + qv.SetQuantile(quantilePercents[i]) + qv.SetValue(quantileValues[i]) + } + sdp.SetCount(count) + sdp.SetTimestamp(timestamp) + sdp.SetSum(sum) +} + +func Test_summary_no_count_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "Summary No Count: round 1 - initial instance, start time is established", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt1Ms, 10, 40, percent0, []float64{1, 5, 8}) + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt1Ms, 10, 40, percent0, []float64{1, 5, 8}) + return &mL + }(), + 1, + }, + { + "Summary No Count: round 2 - instance adjusted based on round 1", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt2Ms, 15, 70, percent0, []float64{7, 44, 9}) + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt2Ms, 15, 70, percent0, []float64{7, 44, 9}) + return &mL + }(), + 0, + }, + { + "Summary No Count: round 3 - instance reset (count less than previous), start time is reset", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt3Ms, 12, 66, percent0, []float64{3, 22, 5}) + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt3Ms, 12, 66, percent0, []float64{3, 22, 5}) + return &mL + }(), + 1, + }, + { + "Summary No Count: round 4 - instance adjusted based on round 3", + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt4Ms, 14, 96, percent0, []float64{9, 47, 8}) + pt0.SetStartTimestamp(pdt4Ms) + return &mL + }(), + func() *pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetDataType(pdata.MetricDataTypeSummary) + m0.SetName("summary1") + s0 := m0.Summary() + pt0 := s0.DataPoints().AppendEmpty() + pt0.Attributes().InsertString("v1", "v2") + populateSummary(&pt0, pdt4Ms, 14, 96, percent0, []float64{9, 47, 8}) + return &mL + }(), + 0, + }, + } + + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func Test_summary_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "Summary: round 1 - initial instance, start time is established", + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt1Ms, 10, 40, percent0, []float64{1, 5, 8})), + ), + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt1Ms, 10, 40, percent0, []float64{1, 5, 8})), + ), + 1, + }, + { + "Summary: round 2 - instance adjusted based on round 1", + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt2Ms, summaryPoint(pdt2Ms, 15, 70, percent0, []float64{7, 44, 9})), + ), + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt2Ms, 15, 70, percent0, []float64{7, 44, 9})), + ), + 0, + }, + { + "Summary: round 3 - instance reset (count less than previous), start time is reset", + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt3Ms, 12, 66, percent0, []float64{3, 22, 5})), + ), + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt3Ms, 12, 66, percent0, []float64{3, 22, 5})), + ), + 1, + }, + { + "Summary: round 4 - instance adjusted based on round 3", + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt4Ms, summaryPoint(pdt4Ms, 14, 96, percent0, []float64{9, 47, 8})), + ), + metricSlice( + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt4Ms, 14, 96, percent0, []float64{9, 47, 8})), + ), + 0, + }, + } + + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +var ( + distPoint = distPointPdata + histogramMetric = cumulativeDistMetricPdata + doublePoint = doublePointPdata + gaugeMetric = gaugeMetricPdata + summaryPoint = summaryPointPdata + summaryMetric = summaryMetricPdata + sumMetric = sumMetricPdata +) + +func metricSlice(metrics ...*pdata.Metric) *pdata.MetricSlice { + ms := pdata.NewMetricSlice() + for _, metric := range metrics { + destMetric := ms.AppendEmpty() + metric.CopyTo(destMetric) + } + return &ms +} + +var ( + k1v1k2v2 = []*kv{ + {"k1", "v1"}, + {"k2", "v2"}, + } + + k1v10k2v20 = []*kv{ + {"k1", "v10"}, + {"k2", "v20"}, + } + + k1v100k2v200 = []*kv{ + {"k1", "v100"}, + {"k2", "v200"}, + } +) + +func Test_cumulativeDistribution_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "CumulativeDist: round 1 - initial instance, start time is established", + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7}))), + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7}))), + 1, + }, { + "CumulativeDist: round 2 - instance adjusted based on round 1", + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt2Ms, distPoint(pdt2Ms, bounds0, []uint64{6, 3, 4, 8}))), + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt2Ms, bounds0, []uint64{6, 3, 4, 8}))), + 0, + }, { + "CumulativeDist: round 3 - instance reset (value less than previous value), start time is reset", + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{5, 3, 2, 7}))), + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{5, 3, 2, 7}))), + 1, + }, { + "CumulativeDist: round 4 - instance adjusted based on round 3", + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{7, 4, 2, 12}))), + metricSlice(histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt4Ms, bounds0, []uint64{7, 4, 2, 12}))), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func Test_multiMetrics_pdata(t *testing.T) { + g1 := "gauge1" + script := []*metricsAdjusterTestPdata{ + { + "MultiMetrics: round 1 - combined round 1 of individual metrics", + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt1Ms, 10, 40, percent0, []float64{1, 5, 8})), + ), + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt1Ms, 10, 40, percent0, []float64{1, 5, 8})), + ), + 3, + }, { + "MultiMetrics: round 2 - combined round 2 of individual metrics", + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt2Ms, doublePoint(pdt2Ms, 66)), + sumMetric(c1, k1v1k2v2, pdt2Ms, doublePoint(pdt2Ms, 66)), + histogramMetric(cd1, k1v1k2v2, pdt2Ms, distPoint(pdt2Ms, bounds0, []uint64{6, 3, 4, 8})), + summaryMetric(s1, k1v1k2v2, pdt2Ms, summaryPoint(pdt2Ms, 15, 70, percent0, []float64{7, 44, 9})), + ), + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt2Ms, doublePoint(pdt2Ms, 66)), + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt2Ms, 66)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt2Ms, bounds0, []uint64{6, 3, 4, 8})), + summaryMetric(s1, k1v1k2v2, pdt1Ms, summaryPoint(pdt2Ms, 15, 70, percent0, []float64{7, 44, 9})), + ), + 0, + }, { + "MultiMetrics: round 3 - combined round 3 of individual metrics", + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 55)), + sumMetric(c1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 55)), + histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{5, 3, 2, 7})), + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt3Ms, 12, 66, percent0, []float64{3, 22, 5})), + ), + metricSlice( + gaugeMetric(g1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 55)), + sumMetric(c1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 55)), + histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{5, 3, 2, 7})), + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt3Ms, 12, 66, percent0, []float64{3, 22, 5})), + ), + 3, + }, { + "MultiMetrics: round 4 - combined round 4 of individual metrics", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt4Ms, 72)), + histogramMetric(cd1, k1v1k2v2, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{7, 4, 2, 12})), + summaryMetric(s1, k1v1k2v2, pdt4Ms, summaryPoint(pdt4Ms, 14, 96, percent0, []float64{9, 47, 8})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt3Ms, doublePoint(pdt4Ms, 72)), + histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt4Ms, bounds0, []uint64{7, 4, 2, 12})), + summaryMetric(s1, k1v1k2v2, pdt3Ms, summaryPoint(pdt4Ms, 14, 96, percent0, []float64{9, 47, 8})), + ), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func Test_multiTimeseries_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "MultiTimeseries: round 1 - initial first instance, start time is established", + metricSlice(sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44))), + metricSlice(sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44))), + 1, + }, { + "MultiTimeseries: round 2 - first instance adjusted based on round 1, initial second instance", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt2Ms, doublePoint(pdt2Ms, 66)), + sumMetric(c1, k1v10k2v20, pdt2Ms, doublePoint(pdt2Ms, 20.0)), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt2Ms, 66)), + sumMetric(c1, k1v10k2v20, pdt2Ms, doublePoint(pdt2Ms, 20.0)), + ), + 1, + }, { + "MultiTimeseries: round 3 - first instance adjusted based on round 1, second based on round 2", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 88.0)), + sumMetric(c1, k1v10k2v20, pdt3Ms, doublePoint(pdt3Ms, 49.0)), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt3Ms, 88.0)), + sumMetric(c1, k1v10k2v20, pdt2Ms, doublePoint(pdt3Ms, 49.0)), + ), + 0, + }, { + "MultiTimeseries: round 4 - first instance reset, second instance adjusted based on round 2, initial third instance", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt4Ms, 87.0)), + sumMetric(c1, k1v10k2v20, pdt4Ms, doublePoint(pdt4Ms, 57.0)), + sumMetric(c1, k1v100k2v200, pdt4Ms, doublePoint(pdt4Ms, 10.0)), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt4Ms, 87.0)), + sumMetric(c1, k1v10k2v20, pdt2Ms, doublePoint(pdt4Ms, 57.0)), + sumMetric(c1, k1v100k2v200, pdt4Ms, doublePoint(pdt4Ms, 10.0)), + ), + 2, + }, { + "MultiTimeseries: round 5 - first instance adjusted based on round 4, second on round 2, third on round 4", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt5Ms, doublePoint(pdt5Ms, 90.0)), + sumMetric(c1, k1v10k2v20, pdt5Ms, doublePoint(pdt5Ms, 65.0)), + sumMetric(c1, k1v100k2v200, pdt5Ms, doublePoint(pdt5Ms, 22.0)), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt5Ms, 90.0)), + sumMetric(c1, k1v10k2v20, pdt2Ms, doublePoint(pdt5Ms, 65.0)), + sumMetric(c1, k1v100k2v200, pdt4Ms, doublePoint(pdt5Ms, 22.0)), + ), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +var ( + emptyLabels = []*kv{} + k1vEmpty = []*kv{{"k1", ""}} + k1vEmptyk2vEmptyk3vEmpty = []*kv{{"k1", ""}, {"k2", ""}, {"k3", ""}} +) + +func Test_emptyLabels_pdata(t *testing.T) { + script := []*metricsAdjusterTestPdata{ + { + "EmptyLabels: round 1 - initial instance, implicitly empty labels, start time is established", + metricSlice(sumMetric(c1, emptyLabels, pdt1Ms, doublePoint(pdt1Ms, 44))), + metricSlice(sumMetric(c1, emptyLabels, pdt1Ms, doublePoint(pdt1Ms, 44))), + 1, + }, { + "EmptyLabels: round 2 - instance adjusted based on round 1", + metricSlice(sumMetric(c1, emptyLabels, pdt2Ms, doublePoint(pdt2Ms, 66))), + metricSlice(sumMetric(c1, emptyLabels, pdt1Ms, doublePoint(pdt2Ms, 66))), + 0, + }, { + "EmptyLabels: round 3 - one explicitly empty label, instance adjusted based on round 1", + metricSlice(sumMetric(c1, k1vEmpty, pdt3Ms, doublePoint(pdt3Ms, 77))), + metricSlice(sumMetric(c1, k1vEmpty, pdt1Ms, doublePoint(pdt3Ms, 77))), + 0, + }, { + "EmptyLabels: round 4 - three explicitly empty labels, instance adjusted based on round 1", + metricSlice(sumMetric(c1, k1vEmptyk2vEmptyk3vEmpty, pdt3Ms, doublePoint(pdt3Ms, 88))), + metricSlice(sumMetric(c1, k1vEmptyk2vEmptyk3vEmpty, pdt1Ms, doublePoint(pdt3Ms, 88))), + 0, + }, + } + runScriptPdata(t, NewJobsMapPdata(time.Minute).get("job", "0"), script) +} + +func Test_tsGC_pdata(t *testing.T) { + script1 := []*metricsAdjusterTestPdata{ + { + "TsGC: round 1 - initial instances, start time is established", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v10k2v20, pdt1Ms, doublePoint(pdt1Ms, 20)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + histogramMetric(cd1, k1v10k2v20, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{40, 20, 30, 70})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v10k2v20, pdt1Ms, doublePoint(pdt1Ms, 20)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + histogramMetric(cd1, k1v10k2v20, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{40, 20, 30, 70})), + ), + 4, + }, + } + + script2 := []*metricsAdjusterTestPdata{ + { + "TsGC: round 2 - metrics first timeseries adjusted based on round 2, second timeseries not updated", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt2Ms, doublePoint(pdt2Ms, 88)), + histogramMetric(cd1, k1v1k2v2, pdt2Ms, distPoint(pdt2Ms, bounds0, []uint64{8, 7, 9, 14})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt2Ms, 88)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt2Ms, bounds0, []uint64{8, 7, 9, 14})), + ), + 0, + }, + } + + script3 := []*metricsAdjusterTestPdata{ + { + "TsGC: round 3 - metrics first timeseries adjusted based on round 2, second timeseries empty due to timeseries gc()", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt3Ms, doublePoint(pdt3Ms, 99)), + sumMetric(c1, k1v10k2v20, pdt3Ms, doublePoint(pdt3Ms, 80)), + histogramMetric(cd1, k1v1k2v2, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{9, 8, 10, 15})), + histogramMetric(cd1, k1v10k2v20, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{55, 66, 33, 77})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt3Ms, 99)), + sumMetric(c1, k1v10k2v20, pdt3Ms, doublePoint(pdt3Ms, 80)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt3Ms, bounds0, []uint64{9, 8, 10, 15})), + histogramMetric(cd1, k1v10k2v20, pdt3Ms, distPoint(pdt3Ms, bounds0, []uint64{55, 66, 33, 77})), + ), + 2, + }, + } + + jobsMap := NewJobsMapPdata(time.Minute) + + // run round 1 + runScriptPdata(t, jobsMap.get("job", "0"), script1) + // gc the tsmap, unmarking all entries + jobsMap.get("job", "0").gc() + // run round 2 - update metrics first timeseries only + runScriptPdata(t, jobsMap.get("job", "0"), script2) + // gc the tsmap, collecting umarked entries + jobsMap.get("job", "0").gc() + // run round 3 - verify that metrics second timeseries have been gc'd + runScriptPdata(t, jobsMap.get("job", "0"), script3) +} + +func Test_jobGC_pdata(t *testing.T) { + job1Script1 := []*metricsAdjusterTestPdata{ + { + "JobGC: job 1, round 1 - initial instances, adjusted should be empty", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v10k2v20, pdt1Ms, doublePoint(pdt1Ms, 20)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + histogramMetric(cd1, k1v10k2v20, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{40, 20, 30, 70})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt1Ms, doublePoint(pdt1Ms, 44)), + sumMetric(c1, k1v10k2v20, pdt1Ms, doublePoint(pdt1Ms, 20)), + histogramMetric(cd1, k1v1k2v2, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{4, 2, 3, 7})), + histogramMetric(cd1, k1v10k2v20, pdt1Ms, distPoint(pdt1Ms, bounds0, []uint64{40, 20, 30, 70})), + ), + 4, + }, + } + + emptyMetricSlice := func() *pdata.MetricSlice { ms := pdata.NewMetricSlice(); return &ms } + job2Script1 := []*metricsAdjusterTestPdata{ + { + "JobGC: job2, round 1 - no metrics adjusted, just trigger gc", + emptyMetricSlice(), + emptyMetricSlice(), + 0, + }, + } + + job1Script2 := []*metricsAdjusterTestPdata{ + { + "JobGC: job 1, round 2 - metrics timeseries empty due to job-level gc", + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt4Ms, 99)), + sumMetric(c1, k1v10k2v20, pdt4Ms, doublePoint(pdt4Ms, 80)), + histogramMetric(cd1, k1v1k2v2, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{9, 8, 10, 15})), + histogramMetric(cd1, k1v10k2v20, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{55, 66, 33, 77})), + ), + metricSlice( + sumMetric(c1, k1v1k2v2, pdt4Ms, doublePoint(pdt4Ms, 99)), + sumMetric(c1, k1v10k2v20, pdt4Ms, doublePoint(pdt4Ms, 80)), + histogramMetric(cd1, k1v1k2v2, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{9, 8, 10, 15})), + histogramMetric(cd1, k1v10k2v20, pdt4Ms, distPoint(pdt4Ms, bounds0, []uint64{55, 66, 33, 77})), + ), + 4, + }, + } + + gcInterval := 10 * time.Millisecond + jobsMap := NewJobsMapPdata(gcInterval) + + // run job 1, round 1 - all entries marked + runScriptPdata(t, jobsMap.get("job", "0"), job1Script1) + // sleep longer than gcInterval to enable job gc in the next run + time.Sleep(2 * gcInterval) + // run job 2, round1 - trigger job gc, unmarking all entries + runScriptPdata(t, jobsMap.get("job", "1"), job2Script1) + // sleep longer than gcInterval to enable job gc in the next run + time.Sleep(2 * gcInterval) + // re-run job 2, round1 - trigger job gc, removing unmarked entries + runScriptPdata(t, jobsMap.get("job", "1"), job2Script1) + // ensure that at least one jobsMap.gc() completed + jobsMap.gc() + // run job 1, round 2 - verify that all job 1 timeseries have been gc'd + runScriptPdata(t, jobsMap.get("job", "0"), job1Script2) +} + +type metricsAdjusterTestPdata struct { + description string + metrics *pdata.MetricSlice + adjusted *pdata.MetricSlice + resets int +} + +func runScriptPdata(t *testing.T, tsm *timeseriesMapPdata, script []*metricsAdjusterTestPdata) { + l := zap.NewNop() + t.Cleanup(func() { require.NoError(t, l.Sync()) }) // flushes buffer, if any + ma := NewMetricsAdjusterPdata(tsm, l) + + for _, test := range script { + expectedResets := test.resets + resets := ma.AdjustMetrics(test.metrics) + adjusted := test.metrics + assert.EqualValuesf(t, test.adjusted, adjusted, "Test: %v - expected: %v, actual: %v", test.description, test.adjusted, adjusted) + assert.Equalf(t, expectedResets, resets, "Test: %v", test.description) + } +} diff --git a/receiver/prometheusreceiver/internal/otlp_metricsbuilder.go b/receiver/prometheusreceiver/internal/otlp_metricsbuilder.go index 9bcc3f9e196d3..e5b1b50556e0b 100644 --- a/receiver/prometheusreceiver/internal/otlp_metricsbuilder.go +++ b/receiver/prometheusreceiver/internal/otlp_metricsbuilder.go @@ -63,7 +63,7 @@ func convToPdataMetricType(metricType textparse.MetricType) pdata.MetricDataType case textparse.MetricTypeCounter: // always use float64, as it's the internal data type used in prometheus return pdata.MetricDataTypeSum - // textparse.MetricTypeUnknown is converted to gauge by default to fix Prometheus untyped metrics from being dropped + // textparse.MetricTypeUnknown is converted to gauge by default to prevent Prometheus untyped metrics from being dropped case textparse.MetricTypeGauge, textparse.MetricTypeUnknown: return pdata.MetricDataTypeGauge case textparse.MetricTypeHistogram: @@ -71,45 +71,58 @@ func convToPdataMetricType(metricType textparse.MetricType) pdata.MetricDataType // dropping support for gaugehistogram for now until we have an official spec of its implementation // a draft can be found in: https://docs.google.com/document/d/1KwV0mAXwwbvvifBvDKH_LU1YjyXE_wxCkHNoCGq1GX0/edit#heading=h.1cvzqd4ksd23 // case textparse.MetricTypeGaugeHistogram: - // return metricspb.MetricDescriptor_GAUGE_DISTRIBUTION + // return case textparse.MetricTypeSummary: return pdata.MetricDataTypeSummary default: - // including: textparse.MetricTypeInfo, textparse.MetricTypeStateset + // including: textparse.MetricTypeGaugeHistogram, textparse.MetricTypeInfo, textparse.MetricTypeStateset return pdata.MetricDataTypeNone } } type metricBuilderPdata struct { - *metricBuilder - metrics pdata.MetricSlice - currentMf MetricFamilyPdata + metrics pdata.MetricSlice + families map[string]MetricFamilyPdata + hasData bool + hasInternalMetric bool + mc MetadataCache + numTimeseries int + droppedTimeseries int + useStartTimeMetric bool + startTimeMetricRegex *regexp.Regexp + startTime float64 + intervalStartTimeMs int64 + logger *zap.Logger } // newMetricBuilder creates a MetricBuilder which is allowed to feed all the datapoints from a single prometheus -// scraped page by calling its AddDataPoint function, and turn them into an opencensus data.MetricsData object +// scraped page by calling its AddDataPoint function, and turn them into a pdata.Metrics object. // by calling its Build function -func newMetricBuilderPdata(mc MetadataCache, useStartTimeMetric bool, startTimeMetricRegex string, logger *zap.Logger) *metricBuilderPdata { +func newMetricBuilderPdata(mc MetadataCache, useStartTimeMetric bool, startTimeMetricRegex string, logger *zap.Logger, intervalStartTimeMs int64) *metricBuilderPdata { var regex *regexp.Regexp if startTimeMetricRegex != "" { regex, _ = regexp.Compile(startTimeMetricRegex) } return &metricBuilderPdata{ - metrics: pdata.NewMetricSlice(), - metricBuilder: &metricBuilder{ - mc: mc, - logger: logger, - numTimeseries: 0, - droppedTimeseries: 0, - useStartTimeMetric: useStartTimeMetric, - startTimeMetricRegex: regex, - }, + metrics: pdata.NewMetricSlice(), + families: map[string]MetricFamilyPdata{}, + mc: mc, + logger: logger, + numTimeseries: 0, + droppedTimeseries: 0, + useStartTimeMetric: useStartTimeMetric, + startTimeMetricRegex: regex, + intervalStartTimeMs: intervalStartTimeMs, } } -// This code is used in follow-up changes but golangci-lint is so pedantic. -var _ = newMetricBuilderPdata -var _ = (*metricBuilderPdata)(nil).AddDataPoint +func (b *metricBuilderPdata) matchStartTimeMetric(metricName string) bool { + if b.startTimeMetricRegex != nil { + return b.startTimeMetricRegex.MatchString(metricName) + } + + return metricName == startTimeMetricName +} // AddDataPoint is for feeding prometheus data complexValue in its processing order func (b *metricBuilderPdata) AddDataPoint(ls labels.Labels, t int64, v float64) error { @@ -159,14 +172,36 @@ func (b *metricBuilderPdata) AddDataPoint(ls labels.Labels, t int64, v float64) b.hasData = true - if b.currentMf != nil && !b.currentMf.IsSameFamily(metricName) { - ts, dts := b.currentMf.ToMetricPdata(&b.metrics) + familyName := normalizeMetricName(metricName) + curMF, ok := b.families[familyName] + if !ok { + if mf, ok := b.families[metricName]; ok { + curMF = mf + } else { + curMF = newMetricFamilyPdata(metricName, b.mc, b.logger, b.intervalStartTimeMs) + b.families[familyName] = curMF + } + } + + return curMF.Add(metricName, ls, t, v) +} + +// Build an pdata.MetricSlice based on all added data complexValue. +// The only error returned by this function is errNoDataToBuild. +func (b *metricBuilderPdata) Build() (*pdata.MetricSlice, int, int, error) { + if !b.hasData { + if b.hasInternalMetric { + metricsL := pdata.NewMetricSlice() + return &metricsL, 0, 0, nil + } + return nil, 0, 0, errNoDataToBuild + } + + for _, mf := range b.families { + ts, dts := mf.ToMetricPdata(&b.metrics) b.numTimeseries += ts b.droppedTimeseries += dts - b.currentMf = newMetricFamilyPdata(metricName, b.mc, b.intervalStartTimeMs) - } else if b.currentMf == nil { - b.currentMf = newMetricFamilyPdata(metricName, b.mc, b.intervalStartTimeMs) } - return b.currentMf.Add(metricName, ls, t, v) + return &b.metrics, b.numTimeseries, b.droppedTimeseries, nil } diff --git a/receiver/prometheusreceiver/internal/otlp_metricsbuilder_test.go b/receiver/prometheusreceiver/internal/otlp_metricsbuilder_test.go index bfff50709a0e6..da6596c5b9589 100644 --- a/receiver/prometheusreceiver/internal/otlp_metricsbuilder_test.go +++ b/receiver/prometheusreceiver/internal/otlp_metricsbuilder_test.go @@ -17,97 +17,91 @@ package internal import ( "testing" - metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/textparse" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/model/pdata" + "go.uber.org/zap" ) -func TestGetBoundaryEquivalence(t *testing.T) { - cases := []struct { - name string - mtype metricspb.MetricDescriptor_Type - pmtype pdata.MetricDataType - labels labels.Labels - wantValue float64 - wantErr string - }{ - { - name: "cumulative histogram with bucket label", - mtype: metricspb.MetricDescriptor_CUMULATIVE_DISTRIBUTION, - pmtype: pdata.MetricDataTypeHistogram, - labels: labels.Labels{ - {Name: model.BucketLabel, Value: "0.256"}, - }, - wantValue: 0.256, - }, - { - name: "gauge histogram with bucket label", - mtype: metricspb.MetricDescriptor_GAUGE_DISTRIBUTION, - pmtype: pdata.MetricDataTypeHistogram, - labels: labels.Labels{ - {Name: model.BucketLabel, Value: "11.71"}, - }, - wantValue: 11.71, - }, +func runBuilderStartTimeTestsPdata(t *testing.T, tests []buildTestDataPdata, + startTimeMetricRegex string, expectedBuilderStartTime float64) { + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mc := newMockMetadataCache(testMetadata) + st := startTs + for _, page := range tt.inputs { + b := newMetricBuilderPdata(mc, true, startTimeMetricRegex, zap.NewNop(), 0) + b.startTime = defaultBuilderStartTime // set to a non-zero value + for _, pt := range page.pts { + // set ts for testing + pt.t = st + assert.NoError(t, b.AddDataPoint(pt.lb, pt.t, pt.v)) + } + _, _, _, err := b.Build() + assert.NoError(t, err) + assert.EqualValues(t, b.startTime, expectedBuilderStartTime) + st += interval + } + }) + } +} + +func Test_startTimeMetricMatch_pdata(t *testing.T) { + matchBuilderStartTime := 123.456 + matchTests := []buildTestDataPdata{ { - name: "summary with bucket label", - mtype: metricspb.MetricDescriptor_SUMMARY, - pmtype: pdata.MetricDataTypeSummary, - labels: labels.Labels{ - {Name: model.BucketLabel, Value: "11.71"}, + name: "prefix_match", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("example_process_start_time_seconds", + matchBuilderStartTime, "foo", "bar"), + }, + }, }, - wantErr: "QuantileLabel is empty", }, { - name: "summary with quantile label", - mtype: metricspb.MetricDescriptor_SUMMARY, - pmtype: pdata.MetricDataTypeSummary, - labels: labels.Labels{ - {Name: model.QuantileLabel, Value: "92.88"}, + name: "match", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("process_start_time_seconds", + matchBuilderStartTime, "foo", "bar"), + }, + }, }, - wantValue: 92.88, }, + } + nomatchTests := []buildTestDataPdata{ { - name: "gauge histogram mismatched with bucket label", - mtype: metricspb.MetricDescriptor_SUMMARY, - pmtype: pdata.MetricDataTypeSummary, - labels: labels.Labels{ - {Name: model.BucketLabel, Value: "11.71"}, + name: "nomatch1", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("_process_start_time_seconds", + matchBuilderStartTime, "foo", "bar"), + }, + }, }, - wantErr: "QuantileLabel is empty", }, { - name: "other data types without matches", - mtype: metricspb.MetricDescriptor_GAUGE_DOUBLE, - pmtype: pdata.MetricDataTypeGauge, - labels: labels.Labels{ - {Name: model.BucketLabel, Value: "11.71"}, + name: "nomatch2", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("subprocess_start_time_seconds", + matchBuilderStartTime, "foo", "bar"), + }, + }, }, - wantErr: "given metricType has no BucketLabel or QuantileLabel", }, } - for _, tt := range cases { - tt := tt - t.Run(tt.name, func(t *testing.T) { - oldBoundary, oerr := getBoundary(tt.mtype, tt.labels) - pdataBoundary, perr := getBoundaryPdata(tt.pmtype, tt.labels) - assert.Equal(t, oldBoundary, pdataBoundary, "Both boundary values MUST be equal") - assert.Equal(t, oldBoundary, tt.wantValue, "Mismatched boundary messages") - assert.Equal(t, oerr, perr, "The exact same error MUST be returned from both boundary helpers") - - if tt.wantErr != "" { - require.NotEqual(t, oerr, "expected an error from old style boundary retrieval") - require.NotEqual(t, perr, "expected an error from new style boundary retrieval") - require.Contains(t, oerr.Error(), tt.wantErr) - require.Contains(t, perr.Error(), tt.wantErr) - } - }) - } + runBuilderStartTimeTestsPdata(t, matchTests, "^(.+_)*process_start_time_seconds$", matchBuilderStartTime) + runBuilderStartTimeTestsPdata(t, nomatchTests, "^(.+_)*process_start_time_seconds$", defaultBuilderStartTime) } func TestGetBoundaryPdata(t *testing.T) { @@ -197,8 +191,8 @@ func TestConvToPdataMetricType(t *testing.T) { }, { name: "textparse.gauge", - mtype: textparse.MetricTypeCounter, - want: pdata.MetricDataTypeSum, + mtype: textparse.MetricTypeGauge, + want: pdata.MetricDataTypeGauge, }, { name: "textparse.unknown", @@ -231,7 +225,7 @@ func TestConvToPdataMetricType(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { got := convToPdataMetricType(tt.mtype) - require.Equal(t, got, tt.want) + require.Equal(t, got.String(), tt.want.String()) }) } } @@ -325,3 +319,913 @@ func TestIsUsefulLabelPdata(t *testing.T) { }) } } + +type buildTestDataPdata struct { + name string + inputs []*testScrapedPage + wants func() []*pdata.MetricSlice +} + +func Test_OTLPMetricBuilder_counters(t *testing.T) { + tests := []buildTestDataPdata{ + { + name: "single-item", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("counter_test", 100, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetName("counter_test") + m0.SetDataType(pdata.MetricDataTypeSum) + sum := m0.Sum() + sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum.SetIsMonotonic(true) + pt0 := sum.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL} + }, + }, + { + name: "two-items", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("counter_test", 150, "foo", "bar"), + createDataPoint("counter_test", 25, "foo", "other"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetName("counter_test") + m0.SetDataType(pdata.MetricDataTypeSum) + sum := m0.Sum() + sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum.SetIsMonotonic(true) + pt0 := sum.DataPoints().AppendEmpty() + pt0.SetDoubleVal(150.0) + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := sum.DataPoints().AppendEmpty() + pt1.SetDoubleVal(25.0) + pt1.SetStartTimestamp(startTsNanos) + pt1.SetTimestamp(startTsNanos) + pt1.Attributes().InsertString("foo", "other") + + return []*pdata.MetricSlice{&mL} + }, + }, + { + name: "two-metrics", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("counter_test", 150, "foo", "bar"), + createDataPoint("counter_test", 25, "foo", "other"), + createDataPoint("counter_test2", 100, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("counter_test") + m0.SetDataType(pdata.MetricDataTypeSum) + sum0 := m0.Sum() + sum0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum0.SetIsMonotonic(true) + pt0 := sum0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(150.0) + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := sum0.DataPoints().AppendEmpty() + pt1.SetDoubleVal(25.0) + pt1.SetStartTimestamp(startTsNanos) + pt1.SetTimestamp(startTsNanos) + pt1.Attributes().InsertString("foo", "other") + + m1 := mL0.AppendEmpty() + m1.SetName("counter_test2") + m1.SetDataType(pdata.MetricDataTypeSum) + sum1 := m1.Sum() + sum1.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum1.SetIsMonotonic(true) + pt2 := sum1.DataPoints().AppendEmpty() + pt2.SetDoubleVal(100.0) + pt2.SetStartTimestamp(startTsNanos) + pt2.SetTimestamp(startTsNanos) + pt2.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "metrics-with-poor-names", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("poor_name_count", 100, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL := pdata.NewMetricSlice() + m0 := mL.AppendEmpty() + m0.SetName("poor_name_count") + m0.SetDataType(pdata.MetricDataTypeSum) + sum := m0.Sum() + sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + sum.SetIsMonotonic(true) + pt0 := sum.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL} + }, + }, + } + + runBuilderTestsPdata(t, tests) +} + +func runBuilderTestsPdata(t *testing.T, tests []buildTestDataPdata) { + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wants := tt.wants() + assert.EqualValues(t, len(wants), len(tt.inputs)) + mc := newMockMetadataCache(testMetadata) + st := startTs + for i, page := range tt.inputs { + b := newMetricBuilderPdata(mc, true, "", zap.NewNop(), startTs) + b.startTime = defaultBuilderStartTime // set to a non-zero value + b.intervalStartTimeMs = startTs + for _, pt := range page.pts { + // set ts for testing + pt.t = st + assert.NoError(t, b.AddDataPoint(pt.lb, pt.t, pt.v)) + } + metrics, _, _, err := b.Build() + assert.NoError(t, err) + assertEquivalentMetricsPdata(t, wants[i], metrics) + st += interval + } + }) + } +} + +func assertEquivalentMetricsPdata(t *testing.T, want, got *pdata.MetricSlice) { + if !assert.Equal(t, want.Len(), got.Len()) { + return + } + wmap := map[string]pdata.Metric{} + gmap := map[string]pdata.Metric{} + + for i := 0; i < want.Len(); i++ { + wi := want.At(i) + wmap[wi.Name()] = wi + gi := got.At(i) + gmap[gi.Name()] = gi + } + + assert.EqualValues(t, wmap, gmap) +} + +var ( + startTsNanos = pdata.Timestamp(startTs * 1e6) + startTsPlusIntervalNanos = pdata.Timestamp((startTs + interval) * 1e6) +) + +func Test_OTLPMetricBuilder_gauges(t *testing.T) { + tests := []buildTestDataPdata{ + { + name: "one-gauge", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("gauge_test", 100, "foo", "bar"), + }, + }, + { + pts: []*testDataPoint{ + createDataPoint("gauge_test", 90, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("gauge_test") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + mL1 := pdata.NewMetricSlice() + m1 := mL1.AppendEmpty() + m1.SetName("gauge_test") + m1.SetDataType(pdata.MetricDataTypeGauge) + gauge1 := m1.Gauge() + pt1 := gauge1.DataPoints().AppendEmpty() + pt1.SetDoubleVal(90.0) + pt1.SetStartTimestamp(0) + pt1.SetTimestamp(startTsPlusIntervalNanos) + pt1.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0, &mL1} + }, + }, + { + name: "gauge-with-different-tags", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("gauge_test", 100, "foo", "bar"), + createDataPoint("gauge_test", 200, "bar", "foo"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("gauge_test") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := gauge0.DataPoints().AppendEmpty() + pt1.SetDoubleVal(200.0) + pt1.SetStartTimestamp(0) + pt1.SetTimestamp(startTsNanos) + pt1.Attributes().InsertString("bar", "foo") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + // TODO: A decision need to be made. If we want to have the behavior which can generate different tag key + // sets because metrics come and go + name: "gauge-comes-and-go-with-different-tagset", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("gauge_test", 100, "foo", "bar"), + createDataPoint("gauge_test", 200, "bar", "foo"), + }, + }, + { + pts: []*testDataPoint{ + createDataPoint("gauge_test", 20, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("gauge_test") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := gauge0.DataPoints().AppendEmpty() + pt1.SetDoubleVal(200.0) + pt1.SetStartTimestamp(0) + pt1.SetTimestamp(startTsNanos) + pt1.Attributes().InsertString("bar", "foo") + + mL1 := pdata.NewMetricSlice() + m1 := mL1.AppendEmpty() + m1.SetName("gauge_test") + m1.SetDataType(pdata.MetricDataTypeGauge) + gauge1 := m1.Gauge() + pt2 := gauge1.DataPoints().AppendEmpty() + pt2.SetDoubleVal(20.0) + pt2.SetStartTimestamp(0) + pt2.SetTimestamp(startTsPlusIntervalNanos) + pt2.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0, &mL1} + }, + }, + } + + runBuilderTestsPdata(t, tests) +} + +func Test_OTLPMetricBuilder_untype(t *testing.T) { + tests := []buildTestDataPdata{ + { + name: "one-unknown", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("unknown_test", 100, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("unknown_test") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetStartTimestamp(0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "no-type-hint", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("something_not_exists", 100, "foo", "bar"), + createDataPoint("theother_not_exists", 200, "foo", "bar"), + createDataPoint("theother_not_exists", 300, "bar", "foo"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("something_not_exists") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + m1 := mL0.AppendEmpty() + m1.SetName("theother_not_exists") + m1.SetDataType(pdata.MetricDataTypeGauge) + gauge1 := m1.Gauge() + pt1 := gauge1.DataPoints().AppendEmpty() + pt1.SetDoubleVal(200.0) + pt1.SetTimestamp(startTsNanos) + pt1.Attributes().InsertString("foo", "bar") + + pt2 := gauge1.DataPoints().AppendEmpty() + pt2.SetDoubleVal(300.0) + pt2.SetTimestamp(startTsNanos) + pt2.Attributes().InsertString("bar", "foo") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "untype-metric-poor-names", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("some_count", 100, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("some_count") + m0.SetDataType(pdata.MetricDataTypeGauge) + gauge0 := m0.Gauge() + pt0 := gauge0.DataPoints().AppendEmpty() + pt0.SetDoubleVal(100.0) + pt0.SetTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + } + + runBuilderTestsPdata(t, tests) +} + +func Test_OTLPMetricBuilder_histogram(t *testing.T) { + tests := []buildTestDataPdata{ + { + name: "single item", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test", 10, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test_sum", 99, "foo", "bar"), + createDataPoint("hist_test_count", 10, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(10) + pt0.SetSum(99) + pt0.SetExplicitBounds([]float64{10, 20}) + pt0.SetBucketCounts([]uint64{1, 1, 8}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "multi-groups", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test", 10, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test_sum", 99, "foo", "bar"), + createDataPoint("hist_test_count", 10, "foo", "bar"), + createDataPoint("hist_test", 1, "key2", "v2", "le", "10"), + createDataPoint("hist_test", 2, "key2", "v2", "le", "20"), + createDataPoint("hist_test", 3, "key2", "v2", "le", "+inf"), + createDataPoint("hist_test_sum", 50, "key2", "v2"), + createDataPoint("hist_test_count", 3, "key2", "v2"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(10) + pt0.SetSum(99) + pt0.SetExplicitBounds([]float64{10, 20}) + pt0.SetBucketCounts([]uint64{1, 1, 8}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := hist0.DataPoints().AppendEmpty() + pt1.SetCount(3) + pt1.SetSum(50) + pt1.SetExplicitBounds([]float64{10, 20}) + pt1.SetBucketCounts([]uint64{1, 1, 1}) + pt1.SetTimestamp(startTsNanos) + pt1.SetStartTimestamp(startTsNanos) + pt1.Attributes().InsertString("key2", "v2") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "multi-groups-and-families", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test", 10, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test_sum", 99, "foo", "bar"), + createDataPoint("hist_test_count", 10, "foo", "bar"), + createDataPoint("hist_test", 1, "key2", "v2", "le", "10"), + createDataPoint("hist_test", 2, "key2", "v2", "le", "20"), + createDataPoint("hist_test", 3, "key2", "v2", "le", "+inf"), + createDataPoint("hist_test_sum", 50, "key2", "v2"), + createDataPoint("hist_test_count", 3, "key2", "v2"), + createDataPoint("hist_test2", 1, "le", "10"), + createDataPoint("hist_test2", 2, "le", "20"), + createDataPoint("hist_test2", 3, "le", "+inf"), + createDataPoint("hist_test2_sum", 50), + createDataPoint("hist_test2_count", 3), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(10) + pt0.SetSum(99) + pt0.SetExplicitBounds([]float64{10, 20}) + pt0.SetBucketCounts([]uint64{1, 1, 8}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + pt1 := hist0.DataPoints().AppendEmpty() + pt1.SetCount(3) + pt1.SetSum(50) + pt1.SetExplicitBounds([]float64{10, 20}) + pt1.SetBucketCounts([]uint64{1, 1, 1}) + pt1.SetTimestamp(startTsNanos) + pt1.SetStartTimestamp(startTsNanos) + pt1.Attributes().InsertString("key2", "v2") + + m1 := mL0.AppendEmpty() + m1.SetName("hist_test2") + m1.SetDataType(pdata.MetricDataTypeHistogram) + hist1 := m1.Histogram() + hist1.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt2 := hist1.DataPoints().AppendEmpty() + pt2.SetCount(3) + pt2.SetSum(50) + pt2.SetExplicitBounds([]float64{10, 20}) + pt2.SetBucketCounts([]uint64{1, 1, 1}) + pt2.SetTimestamp(startTsNanos) + pt2.SetStartTimestamp(startTsNanos) + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "unordered-buckets", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 10, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test_sum", 99, "foo", "bar"), + createDataPoint("hist_test_count", 10, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(10) + pt0.SetSum(99) + pt0.SetExplicitBounds([]float64{10, 20}) + pt0.SetBucketCounts([]uint64{1, 1, 8}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + // this won't likely happen in real env, as prometheus wont generate histogram with less than 3 buckets + name: "only-one-bucket", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 3, "le", "+inf"), + createDataPoint("hist_test_count", 3), + createDataPoint("hist_test_sum", 100), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(3) + pt0.SetSum(100) + pt0.SetExplicitBounds([]float64{}) + pt0.SetBucketCounts([]uint64{3}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + // this won't likely happen in real env, as prometheus wont generate histogram with less than 3 buckets + name: "only-one-bucket-noninf", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 3, "le", "20"), + createDataPoint("hist_test_count", 3), + createDataPoint("hist_test_sum", 100), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(3) + pt0.SetSum(100) + pt0.SetExplicitBounds([]float64{}) + pt0.SetBucketCounts([]uint64{3}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "no-sum", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test", 3, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test_count", 3, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("hist_test") + m0.SetDataType(pdata.MetricDataTypeHistogram) + hist0 := m0.Histogram() + hist0.SetAggregationTemporality(pdata.MetricAggregationTemporalityCumulative) + pt0 := hist0.DataPoints().AppendEmpty() + pt0.SetCount(3) + pt0.SetSum(0) + pt0.SetExplicitBounds([]float64{10, 20}) + pt0.SetBucketCounts([]uint64{1, 1, 1}) + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "corrupted-no-buckets", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test_sum", 99), + createDataPoint("hist_test_count", 10), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "corrupted-no-count", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("hist_test", 1, "foo", "bar", "le", "10"), + createDataPoint("hist_test", 2, "foo", "bar", "le", "20"), + createDataPoint("hist_test", 3, "foo", "bar", "le", "+inf"), + createDataPoint("hist_test_sum", 99, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + return []*pdata.MetricSlice{&mL0} + }, + }, + } + + runBuilderTestsPdata(t, tests) +} + +func Test_OTLPMetricBuilder_summary(t *testing.T) { + tests := []buildTestDataPdata{ + { + name: "no-sum-and-count", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "no-count", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"), + createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"), + createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"), + createDataPoint("summary_test_sum", 500, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "no-sum", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"), + createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"), + createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"), + createDataPoint("summary_test_count", 500, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("summary_test") + m0.SetDataType(pdata.MetricDataTypeSummary) + sum0 := m0.Summary() + pt0 := sum0.DataPoints().AppendEmpty() + pt0.SetTimestamp(startTsNanos) + pt0.SetStartTimestamp(startTsNanos) + pt0.SetCount(500) + pt0.SetSum(0.0) + pt0.Attributes().InsertString("foo", "bar") + qvL := pt0.QuantileValues() + q50 := qvL.AppendEmpty() + q50.SetQuantile(.50) + q50.SetValue(1.0) + q75 := qvL.AppendEmpty() + q75.SetQuantile(.75) + q75.SetValue(2.0) + q100 := qvL.AppendEmpty() + q100.SetQuantile(1) + q100.SetValue(5.0) + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "empty-quantiles", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("summary_test_sum", 100, "foo", "bar"), + createDataPoint("summary_test_count", 500, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("summary_test") + m0.SetDataType(pdata.MetricDataTypeSummary) + sum0 := m0.Summary() + pt0 := sum0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.SetCount(500) + pt0.SetSum(100.0) + pt0.Attributes().InsertString("foo", "bar") + + return []*pdata.MetricSlice{&mL0} + }, + }, + { + name: "regular-summary", + inputs: []*testScrapedPage{ + { + pts: []*testDataPoint{ + createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"), + createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"), + createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"), + createDataPoint("summary_test_sum", 100, "foo", "bar"), + createDataPoint("summary_test_count", 500, "foo", "bar"), + }, + }, + }, + wants: func() []*pdata.MetricSlice { + mL0 := pdata.NewMetricSlice() + m0 := mL0.AppendEmpty() + m0.SetName("summary_test") + m0.SetDataType(pdata.MetricDataTypeSummary) + sum0 := m0.Summary() + pt0 := sum0.DataPoints().AppendEmpty() + pt0.SetStartTimestamp(startTsNanos) + pt0.SetTimestamp(startTsNanos) + pt0.SetCount(500) + pt0.SetSum(100.0) + pt0.Attributes().InsertString("foo", "bar") + qvL := pt0.QuantileValues() + q50 := qvL.AppendEmpty() + q50.SetQuantile(.50) + q50.SetValue(1.0) + q75 := qvL.AppendEmpty() + q75.SetQuantile(.75) + q75.SetValue(2.0) + q100 := qvL.AppendEmpty() + q100.SetQuantile(1) + q100.SetValue(5.0) + + return []*pdata.MetricSlice{&mL0} + }, + }, + } + + runBuilderTestsPdata(t, tests) +} + +// Ensure that we reject duplicate label keys. See https://github.com/open-telemetry/wg-prometheus/issues/44. +func TestOTLPMetricBuilderDuplicateLabelKeysAreRejected(t *testing.T) { + mc := newMockMetadataCache(testMetadata) + mb := newMetricBuilderPdata(mc, true, "", zap.NewNop(), 0) + + dupLabels := labels.Labels{ + {Name: "__name__", Value: "test"}, + {Name: "a", Value: "1"}, + {Name: "a", Value: "1"}, + {Name: "z", Value: "9"}, + {Name: "z", Value: "1"}, + {Name: "instance", Value: "0.0.0.0:8855"}, + {Name: "job", Value: "test"}, + } + + err := mb.AddDataPoint(dupLabels, 1917, 1.0) + require.NotNil(t, err) + require.Contains(t, err.Error(), `invalid sample: non-unique label names: ["a" "z"]`) +} + +func Test_OTLPMetricBuilder_baddata(t *testing.T) { + t.Run("empty-metric-name", func(t *testing.T) { + mc := newMockMetadataCache(testMetadata) + b := newMetricBuilderPdata(mc, true, "", zap.NewNop(), 0) + b.startTime = 1.0 // set to a non-zero value + if err := b.AddDataPoint(labels.FromStrings("a", "b"), startTs, 123); err != errMetricNameNotFound { + t.Error("expecting errMetricNameNotFound error, but get nil") + return + } + + if _, _, _, err := b.Build(); err != errNoDataToBuild { + t.Error("expecting errNoDataToBuild error, but get nil") + } + }) + + t.Run("histogram-datapoint-no-bucket-label", func(t *testing.T) { + mc := newMockMetadataCache(testMetadata) + b := newMetricBuilderPdata(mc, true, "", zap.NewNop(), 0) + b.startTime = 1.0 // set to a non-zero value + if err := b.AddDataPoint(createLabels("hist_test", "k", "v"), startTs, 123); err != errEmptyBoundaryLabel { + t.Error("expecting errEmptyBoundaryLabel error, but get nil") + } + }) + + t.Run("summary-datapoint-no-quantile-label", func(t *testing.T) { + mc := newMockMetadataCache(testMetadata) + b := newMetricBuilderPdata(mc, true, "", zap.NewNop(), 0) + b.startTime = 1.0 // set to a non-zero value + if err := b.AddDataPoint(createLabels("summary_test", "k", "v"), startTs, 123); err != errEmptyBoundaryLabel { + t.Error("expecting errEmptyBoundaryLabel error, but get nil") + } + }) +} diff --git a/receiver/prometheusreceiver/internal/otlp_transaction.go b/receiver/prometheusreceiver/internal/otlp_transaction.go new file mode 100644 index 0000000000000..7dc487a5c178e --- /dev/null +++ b/receiver/prometheusreceiver/internal/otlp_transaction.go @@ -0,0 +1,214 @@ +// Copyright The OpenTelemetry Authors +// +// 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 internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal" + +import ( + "context" + "sync/atomic" + "time" + + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/pkg/exemplar" + "github.com/prometheus/prometheus/pkg/labels" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/model/pdata" + "go.opentelemetry.io/collector/obsreport" + "go.uber.org/zap" +) + +type transactionPdata struct { + id int64 + isNew bool + ctx context.Context + useStartTimeMetric bool + startTimeMetricRegex string + sink consumer.Metrics + metadataService *metadataService + externalLabels labels.Labels + nodeResource *pdata.Resource + logger *zap.Logger + receiverID config.ComponentID + metricBuilder *metricBuilderPdata + job, instance string + jobsMap *JobsMapPdata + obsrecv *obsreport.Receiver + startTimeMs int64 +} + +type txConfig struct { + jobsMap *JobsMapPdata + useStartTimeMetric bool + startTimeMetricRegex string + receiverID config.ComponentID + ms *metadataService + sink consumer.Metrics + externalLabels labels.Labels + settings component.ReceiverCreateSettings +} + +func newTransactionPdata(ctx context.Context, txc *txConfig) *transactionPdata { + return &transactionPdata{ + id: atomic.AddInt64(&idSeq, 1), + ctx: ctx, + isNew: true, + sink: txc.sink, + jobsMap: txc.jobsMap, + useStartTimeMetric: txc.useStartTimeMetric, + startTimeMetricRegex: txc.startTimeMetricRegex, + receiverID: txc.receiverID, + metadataService: txc.ms, + externalLabels: txc.externalLabels, + logger: txc.settings.Logger, + obsrecv: obsreport.NewReceiver(obsreport.ReceiverSettings{ReceiverID: txc.receiverID, Transport: transport, ReceiverCreateSettings: txc.settings}), + } +} + +// Append always returns 0 to disable label caching. +func (t *transactionPdata) Append(ref uint64, labels labels.Labels, atMs int64, value float64) (pointCount uint64, err error) { + select { + case <-t.ctx.Done(): + return 0, errTransactionAborted + default: + } + + if len(t.externalLabels) != 0 { + labels = append(labels, t.externalLabels...) + } + + if t.isNew { + t.startTimeMs = atMs + if err := t.initTransaction(labels); err != nil { + return 0, err + } + } + + return 0, t.metricBuilder.AddDataPoint(labels, atMs, value) +} + +func (t *transactionPdata) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Exemplar) (uint64, error) { + return 0, nil +} + +func (t *transactionPdata) initTransaction(labels labels.Labels) error { + job, instance := labels.Get(model.JobLabel), labels.Get(model.InstanceLabel) + if job == "" || instance == "" { + return errNoJobInstance + } + metadataCache, err := t.metadataService.Get(job, instance) + if err != nil { + return err + } + if t.jobsMap != nil { + t.job = job + t.instance = instance + } + t.nodeResource = CreateNodeAndResourcePdata(job, instance, metadataCache.SharedLabels().Get(model.SchemeLabel)) + t.metricBuilder = newMetricBuilderPdata(metadataCache, t.useStartTimeMetric, t.startTimeMetricRegex, t.logger, t.startTimeMs) + t.isNew = false + return nil +} + +func (t *transactionPdata) Commit() error { + if t.isNew { + return nil + } + + t.startTimeMs = -1 + + ctx := t.obsrecv.StartMetricsOp(t.ctx) + metricsL, numPoints, _, err := t.metricBuilder.Build() + if err != nil { + t.obsrecv.EndMetricsOp(ctx, dataformat, 0, err) + return err + } + + if t.useStartTimeMetric { + if t.metricBuilder.startTime == 0.0 { + err = errNoStartTimeMetrics + t.obsrecv.EndMetricsOp(ctx, dataformat, 0, err) + return err + } + // Otherwise adjust the startTimestamp for all the metrics. + t.adjustStartTimestampPdata(metricsL) + } else { + // TODO: Derive numPoints in this case. + _ = NewMetricsAdjusterPdata(t.jobsMap.get(t.job, t.instance), t.logger).AdjustMetrics(metricsL) + } + + if metricsL.Len() > 0 { + metrics := t.metricSliceToMetrics(metricsL) + t.sink.ConsumeMetrics(ctx, *metrics) + } + + t.obsrecv.EndMetricsOp(ctx, dataformat, numPoints, nil) + return nil +} + +func (t *transactionPdata) Rollback() error { + t.startTimeMs = -1 + return nil +} + +func pdataTimestampFromFloat64(ts float64) pdata.Timestamp { + secs := int64(ts) + nanos := int64((ts - float64(secs)) * 1e9) + return pdata.NewTimestampFromTime(time.Unix(secs, nanos)) +} + +func (t transactionPdata) adjustStartTimestampPdata(metricsL *pdata.MetricSlice) { + startTimeTs := pdataTimestampFromFloat64(t.metricBuilder.startTime) + for i := 0; i < metricsL.Len(); i++ { + metric := metricsL.At(i) + switch metric.DataType() { + case pdata.MetricDataTypeGauge: + continue + + case pdata.MetricDataTypeSum: + dataPoints := metric.Sum().DataPoints() + for j := 0; j < dataPoints.Len(); j++ { + dp := dataPoints.At(j) + dp.SetStartTimestamp(startTimeTs) + } + + case pdata.MetricDataTypeSummary: + dataPoints := metric.Summary().DataPoints() + for j := 0; j < dataPoints.Len(); j++ { + dp := dataPoints.At(j) + dp.SetStartTimestamp(startTimeTs) + } + + case pdata.MetricDataTypeHistogram: + dataPoints := metric.Histogram().DataPoints() + for j := 0; j < dataPoints.Len(); j++ { + dp := dataPoints.At(j) + dp.SetStartTimestamp(startTimeTs) + } + + default: + t.logger.Warn("Unknown metric type", zap.String("type", metric.DataType().String())) + } + } +} + +func (t *transactionPdata) metricSliceToMetrics(metricsL *pdata.MetricSlice) *pdata.Metrics { + metrics := pdata.NewMetrics() + rms := metrics.ResourceMetrics().AppendEmpty() + ilm := rms.InstrumentationLibraryMetrics().AppendEmpty() + metricsL.CopyTo(ilm.Metrics()) + t.nodeResource.CopyTo(rms.Resource()) + return &metrics +} diff --git a/receiver/prometheusreceiver/internal/otlp_transaction_test.go b/receiver/prometheusreceiver/internal/otlp_transaction_test.go new file mode 100644 index 0000000000000..11087557c0442 --- /dev/null +++ b/receiver/prometheusreceiver/internal/otlp_transaction_test.go @@ -0,0 +1,138 @@ +// Copyright The OpenTelemetry Authors +// +// 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 internal + +import ( + "context" + "testing" + "time" + + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/scrape" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/consumer/consumertest" +) + +func Test_transaction_pdata(t *testing.T) { + // discoveredLabels contain labels prior to any processing + discoveredLabels := labels.New( + labels.Label{ + Name: model.AddressLabel, + Value: "address:8080", + }, + labels.Label{ + Name: model.MetricNameLabel, + Value: "foo", + }, + labels.Label{ + Name: model.SchemeLabel, + Value: "http", + }, + ) + // processedLabels contain label values after processing (e.g. relabeling) + processedLabels := labels.New( + labels.Label{ + Name: model.InstanceLabel, + Value: "localhost:8080", + }, + ) + + ms := &metadataService{ + sm: &mockScrapeManager{targets: map[string][]*scrape.Target{ + "test": {scrape.NewTarget(processedLabels, discoveredLabels, nil)}, + }}, + } + + rID := config.NewComponentID("prometheus") + + t.Run("Commit Without Adding", func(t *testing.T) { + nomc := consumertest.NewNop() + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, nomc, nil, componenttest.NewNopReceiverCreateSettings()}) + if got := tr.Commit(); got != nil { + t.Errorf("expecting nil from Commit() but got err %v", got) + } + }) + + t.Run("Rollback does nothing", func(t *testing.T) { + nomc := consumertest.NewNop() + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, nomc, nil, componenttest.NewNopReceiverCreateSettings()}) + if got := tr.Rollback(); got != nil { + t.Errorf("expecting nil from Rollback() but got err %v", got) + } + }) + + badLabels := labels.Labels([]labels.Label{{Name: "foo", Value: "bar"}}) + t.Run("Add One No Target", func(t *testing.T) { + nomc := consumertest.NewNop() + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, nomc, nil, componenttest.NewNopReceiverCreateSettings()}) + if _, got := tr.Append(0, badLabels, time.Now().Unix()*1000, 1.0); got == nil { + t.Errorf("expecting error from Add() but got nil") + } + }) + + jobNotFoundLb := labels.Labels([]labels.Label{ + {Name: "instance", Value: "localhost:8080"}, + {Name: "job", Value: "test2"}, + {Name: "foo", Value: "bar"}}) + t.Run("Add One Job not found", func(t *testing.T) { + nomc := consumertest.NewNop() + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, nomc, nil, componenttest.NewNopReceiverCreateSettings()}) + if _, got := tr.Append(0, jobNotFoundLb, time.Now().Unix()*1000, 1.0); got == nil { + t.Errorf("expecting error from Add() but got nil") + } + }) + + goodLabels := labels.Labels([]labels.Label{{Name: "instance", Value: "localhost:8080"}, + {Name: "job", Value: "test"}, + {Name: "__name__", Value: "foo"}}) + t.Run("Add One Good", func(t *testing.T) { + sink := new(consumertest.MetricsSink) + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, sink, nil, componenttest.NewNopReceiverCreateSettings()}) + if _, got := tr.Append(0, goodLabels, time.Now().Unix()*1000, 1.0); got != nil { + t.Errorf("expecting error == nil from Add() but got: %v\n", got) + } + tr.metricBuilder.startTime = 1.0 // set to a non-zero value + if got := tr.Commit(); got != nil { + t.Errorf("expecting nil from Commit() but got err %v", got) + } + expectedNodeResource := CreateNodeAndResourcePdata("test", "localhost:8080", "http") + mds := sink.AllMetrics() + if len(mds) != 1 { + t.Fatalf("wanted one batch, got %v\n", sink.AllMetrics()) + } + gotNodeResource := mds[0].ResourceMetrics().At(0).Resource() + require.Equal(t, *expectedNodeResource, gotNodeResource, "Resources do not match") + // TODO: re-enable this when handle unspecified OC type + // assert.Len(t, ocmds[0].Metrics, 1) + }) + + t.Run("Error when start time is zero", func(t *testing.T) { + sink := new(consumertest.MetricsSink) + tr := newTransactionPdata(context.Background(), &txConfig{nil, true, "", rID, ms, sink, nil, componenttest.NewNopReceiverCreateSettings()}) + if _, got := tr.Append(0, goodLabels, time.Now().Unix()*1000, 1.0); got != nil { + t.Errorf("expecting error == nil from Add() but got: %v\n", got) + } + tr.metricBuilder.startTime = 0 // zero value means the start time metric is missing + got := tr.Commit() + if got == nil { + t.Error("expecting error from Commit() but got nil") + } else if got.Error() != errNoStartTimeMetrics.Error() { + t.Errorf("expected error %q but got %q", errNoStartTimeMetrics, got) + } + }) +} diff --git a/receiver/prometheusreceiver/internal/prom_to_otlp.go b/receiver/prometheusreceiver/internal/prom_to_otlp.go index 18852947aa7dd..b818a391c3d99 100644 --- a/receiver/prometheusreceiver/internal/prom_to_otlp.go +++ b/receiver/prometheusreceiver/internal/prom_to_otlp.go @@ -41,7 +41,7 @@ func isDiscernibleHost(host string) bool { } // CreateNodeAndResourcePdata creates the resource data added to OTLP payloads. -func CreateNodeAndResourcePdata(job, instance, scheme string) pdata.Resource { +func CreateNodeAndResourcePdata(job, instance, scheme string) *pdata.Resource { host, port, err := net.SplitHostPort(instance) if err != nil { host = instance @@ -57,5 +57,5 @@ func CreateNodeAndResourcePdata(job, instance, scheme string) pdata.Resource { attrs.UpsertString(portAttr, port) attrs.UpsertString(schemeAttr, scheme) - return resource + return &resource } diff --git a/receiver/prometheusreceiver/internal/prom_to_otlp_test.go b/receiver/prometheusreceiver/internal/prom_to_otlp_test.go index a0ba9adf4c9dc..0fa776b92e85d 100644 --- a/receiver/prometheusreceiver/internal/prom_to_otlp_test.go +++ b/receiver/prometheusreceiver/internal/prom_to_otlp_test.go @@ -52,7 +52,7 @@ type jobInstanceDefinition struct { job, instance, host, scheme, port string } -func makeResourceWithJobInstanceScheme(def *jobInstanceDefinition, hasHost bool) pdata.Resource { +func makeResourceWithJobInstanceScheme(def *jobInstanceDefinition, hasHost bool) *pdata.Resource { resource := pdata.NewResource() attrs := resource.Attributes() // Using hardcoded values to assert on outward expectations so that @@ -65,7 +65,7 @@ func makeResourceWithJobInstanceScheme(def *jobInstanceDefinition, hasHost bool) attrs.UpsertString("instance", def.instance) attrs.UpsertString("port", def.port) attrs.UpsertString("scheme", def.scheme) - return resource + return &resource } func TestCreateNodeAndResourcePromToOTLP(t *testing.T) { @@ -73,7 +73,7 @@ func TestCreateNodeAndResourcePromToOTLP(t *testing.T) { name, job string instance string scheme string - want pdata.Resource + want *pdata.Resource }{ { name: "all attributes proper", diff --git a/receiver/prometheusreceiver/internal/staleness_end_to_end_test.go b/receiver/prometheusreceiver/internal/staleness_end_to_end_test.go index eb900dc5f00c4..a3e3d0d99d243 100644 --- a/receiver/prometheusreceiver/internal/staleness_end_to_end_test.go +++ b/receiver/prometheusreceiver/internal/staleness_end_to_end_test.go @@ -198,6 +198,7 @@ service: // 6. Assert that we encounter the stale markers aka special NaNs for the various time series. staleMarkerCount := 0 totalSamples := 0 + require.True(t, len(wReqL) > 0, "Expecting at least one WriteRequest") for i, wReq := range wReqL { name := fmt.Sprintf("WriteRequest#%d", i) require.True(t, len(wReq.Timeseries) > 0, "Expecting at least 1 timeSeries for:: "+name) diff --git a/receiver/prometheusreceiver/metrics_receiver.go b/receiver/prometheusreceiver/metrics_receiver.go index c19cd69be8efc..13261d0914581 100644 --- a/receiver/prometheusreceiver/metrics_receiver.go +++ b/receiver/prometheusreceiver/metrics_receiver.go @@ -16,7 +16,6 @@ package prometheusreceiver // import "github.com/open-telemetry/opentelemetry-co import ( "context" - "time" "github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/scrape" @@ -71,21 +70,17 @@ func (r *pReceiver) Start(_ context.Context, host component.Host) error { } }() - var jobsMap *internal.JobsMap - if !r.cfg.UseStartTimeMetric { - jobsMap = internal.NewJobsMap(2 * time.Minute) - } // Per component.Component Start instructions, for async operations we should not use the // incoming context, it may get cancelled. r.ocaStore = internal.NewOcaStore( context.Background(), r.consumer, r.settings, - jobsMap, r.cfg.UseStartTimeMetric, r.cfg.StartTimeMetricRegex, r.cfg.ID(), r.cfg.PrometheusConfig.GlobalConfig.ExternalLabels, + r.cfg.pdataDirect, ) r.scrapeManager = scrape.NewManager(logger, r.ocaStore) r.ocaStore.SetScrapeManager(r.scrapeManager) diff --git a/receiver/prometheusreceiver/metrics_receiver_helper_test.go b/receiver/prometheusreceiver/metrics_receiver_helper_test.go index 1b0c2ba5481d7..117981119c44e 100644 --- a/receiver/prometheusreceiver/metrics_receiver_helper_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_helper_test.go @@ -40,20 +40,20 @@ import ( ) type mockPrometheusResponse struct { - code int - data string + code int + data string + useOpenMetrics bool } type mockPrometheus struct { - mu sync.Mutex // mu protects the fields below. - endpoints map[string][]mockPrometheusResponse - accessIndex map[string]*int32 - wg *sync.WaitGroup - srv *httptest.Server - useOpenMetrics bool + mu sync.Mutex // mu protects the fields below. + endpoints map[string][]mockPrometheusResponse + accessIndex map[string]*int32 + wg *sync.WaitGroup + srv *httptest.Server } -func newMockPrometheus(endpoints map[string][]mockPrometheusResponse, openMetricsContentType bool) *mockPrometheus { +func newMockPrometheus(endpoints map[string][]mockPrometheusResponse) *mockPrometheus { accessIndex := make(map[string]*int32) wg := &sync.WaitGroup{} wg.Add(len(endpoints)) @@ -62,10 +62,9 @@ func newMockPrometheus(endpoints map[string][]mockPrometheusResponse, openMetric accessIndex[k] = &v } mp := &mockPrometheus{ - wg: wg, - accessIndex: accessIndex, - endpoints: endpoints, - useOpenMetrics: openMetricsContentType, + wg: wg, + accessIndex: accessIndex, + endpoints: endpoints, } srv := httptest.NewServer(mp) mp.srv = srv @@ -76,9 +75,6 @@ func (mp *mockPrometheus) ServeHTTP(rw http.ResponseWriter, req *http.Request) { mp.mu.Lock() defer mp.mu.Unlock() - if mp.useOpenMetrics { - rw.Header().Set("Content-Type", "application/openmetrics-text") - } iptr, ok := mp.accessIndex[req.URL.Path] if !ok { rw.WriteHeader(404) @@ -94,6 +90,9 @@ func (mp *mockPrometheus) ServeHTTP(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(404) return } + if pages[index].useOpenMetrics { + rw.Header().Set("Content-Type", "application/openmetrics-text") + } rw.WriteHeader(pages[index].code) _, _ = rw.Write([]byte(pages[index].data)) } @@ -111,24 +110,28 @@ var ( ) type testData struct { - name string - pages []mockPrometheusResponse - attributes pdata.AttributeMap - validateFunc func(t *testing.T, td *testData, result []*pdata.ResourceMetrics) + name string + pages []mockPrometheusResponse + attributes pdata.AttributeMap + useOpenMetrics bool + validateFunc func(t *testing.T, td *testData, result []*pdata.ResourceMetrics) } // setupMockPrometheus to create a mocked prometheus based on targets, returning the server and a prometheus exporting // config -func setupMockPrometheus(openMetricsContentType bool, tds ...*testData) (*mockPrometheus, *promcfg.Config, error) { +func setupMockPrometheus(tds ...*testData) (*mockPrometheus, *promcfg.Config, error) { jobs := make([]map[string]interface{}, 0, len(tds)) endpoints := make(map[string][]mockPrometheusResponse) metricPaths := make([]string, 0) for _, t := range tds { + for i := range t.pages { + t.pages[i].useOpenMetrics = t.useOpenMetrics + } metricPath := fmt.Sprintf("/%s/metrics", t.name) endpoints[metricPath] = t.pages metricPaths = append(metricPaths, metricPath) } - mp := newMockPrometheus(endpoints, openMetricsContentType) + mp := newMockPrometheus(endpoints) u, _ := url.Parse(mp.srv.URL) for i := 0; i < len(tds); i++ { job := make(map[string]interface{}) @@ -459,77 +462,102 @@ func compareSummary(count uint64, sum float64, quantiles [][]float64) summaryPoi } } -func testComponent(t *testing.T, targets []*testData, useStartTimeMetric bool, startTimeMetricRegex string, useOpenMetrics bool) { - // 1. setup mock server - mp, cfg, err := setupMockPrometheus(useOpenMetrics, targets...) - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - defer mp.Close() - - cms := new(consumertest.MetricsSink) - rcvr := newPrometheusReceiver(componenttest.NewNopReceiverCreateSettings(), &Config{ - ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), - PrometheusConfig: cfg, - UseStartTimeMetric: useStartTimeMetric, - StartTimeMetricRegex: startTimeMetricRegex}, cms) - - require.NoError(t, rcvr.Start(context.Background(), componenttest.NewNopHost()), "Failed to invoke Start: %v", err) - t.Cleanup(func() { - // verify state after shutdown is called - assert.Lenf(t, flattenTargets(rcvr.scrapeManager.TargetsAll()), len(targets), "expected %v targets to be running", len(targets)) - require.NoError(t, rcvr.Shutdown(context.Background())) - assert.Len(t, flattenTargets(rcvr.scrapeManager.TargetsAll()), 0, "expected scrape manager to have no targets") - }) - - // wait for all provided data to be scraped - mp.wg.Wait() - metrics := cms.AllMetrics() - - // split and store results by target name - pResults := splitMetricsByTarget(metrics) - lres, lep := len(pResults), len(mp.endpoints) - assert.Equalf(t, lep, lres, "want %d targets, but got %v\n", lep, lres) - - // loop to validate outputs for each targets - for _, target := range targets { - t.Run(target.name, func(t *testing.T) { - validScrapes := pResults[target.name] - if !useOpenMetrics { - validScrapes = getValidScrapes(t, pResults[target.name]) +func testComponent(t *testing.T, targets []*testData, useStartTimeMetric bool, startTimeMetricRegex string) { + for _, pdataDirect := range []bool{false, true} { + pipelineType := "OpenCensus" + if pdataDirect { + pipelineType = "pdata" + } + t.Run(pipelineType, func(t *testing.T) { // 1. setup mock server + mp, cfg, err := setupMockPrometheus(targets...) + require.Nilf(t, err, "Failed to create Prometheus config: %v", err) + defer mp.Close() + + cms := new(consumertest.MetricsSink) + rcvr := newPrometheusReceiver(componenttest.NewNopReceiverCreateSettings(), &Config{ + ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), + PrometheusConfig: cfg, + UseStartTimeMetric: useStartTimeMetric, + StartTimeMetricRegex: startTimeMetricRegex, + pdataDirect: pdataDirect, + }, cms) + + require.NoError(t, rcvr.Start(context.Background(), componenttest.NewNopHost()), "Failed to invoke Start: %v", err) + t.Cleanup(func() { + // verify state after shutdown is called + assert.Lenf(t, flattenTargets(rcvr.scrapeManager.TargetsAll()), len(targets), "expected %v targets to be running", len(targets)) + require.NoError(t, rcvr.Shutdown(context.Background())) + assert.Len(t, flattenTargets(rcvr.scrapeManager.TargetsAll()), 0, "expected scrape manager to have no targets") + }) + + // wait for all provided data to be scraped + mp.wg.Wait() + metrics := cms.AllMetrics() + + // split and store results by target name + pResults := splitMetricsByTarget(metrics) + lres, lep := len(pResults), len(mp.endpoints) + assert.Equalf(t, lep, lres, "want %d targets, but got %v\n", lep, lres) + + // loop to validate outputs for each targets + for _, target := range targets { + t.Run(target.name, func(t *testing.T) { + validScrapes := pResults[target.name] + if !target.useOpenMetrics { + validScrapes = getValidScrapes(t, pResults[target.name]) + } + target.validateFunc(t, target, validScrapes) + }) } - target.validateFunc(t, target, validScrapes) }) } } // starts prometheus receiver with custom config, retrieves metrics from MetricsSink -func testComponentCustomConfig(t *testing.T, targets []*testData, mp *mockPrometheus, cfg *promcfg.Config) { - ctx := context.Background() - defer mp.Close() - - cms := new(consumertest.MetricsSink) - receiver := newPrometheusReceiver(componenttest.NewNopReceiverCreateSettings(), &Config{ - ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), - PrometheusConfig: cfg}, cms) - - require.NoError(t, receiver.Start(ctx, componenttest.NewNopHost())) - - // verify state after shutdown is called - t.Cleanup(func() { require.NoError(t, receiver.Shutdown(ctx)) }) - - // wait for all provided data to be scraped - mp.wg.Wait() - metrics := cms.AllMetrics() - - // split and store results by target name - pResults := splitMetricsByTarget(metrics) - lres, lep := len(pResults), len(mp.endpoints) - assert.Equalf(t, lep, lres, "want %d targets, but got %v\n", lep, lres) - - // loop to validate outputs for each targets - for _, target := range targets { - t.Run(target.name, func(t *testing.T) { - validScrapes := getValidScrapes(t, pResults[target.name]) - target.validateFunc(t, target, validScrapes) +func testComponentCustomConfig(t *testing.T, targets []*testData, cfgMut func(*promcfg.Config)) { + for _, pdataDirect := range []bool{false, true} { + pipelineType := "OpenCensus" + if pdataDirect { + pipelineType = "pdata" + } + t.Run(pipelineType, func(t *testing.T) { + ctx := context.Background() + mp, cfg, err := setupMockPrometheus(targets...) + cfgMut(cfg) + require.Nilf(t, err, "Failed to create Prometheus config: %v", err) + defer mp.Close() + + cms := new(consumertest.MetricsSink) + receiver := newPrometheusReceiver(componenttest.NewNopReceiverCreateSettings(), &Config{ + ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), + PrometheusConfig: cfg, + pdataDirect: pdataDirect, + }, cms) + + require.NoError(t, receiver.Start(ctx, componenttest.NewNopHost())) + + // verify state after shutdown is called + t.Cleanup(func() { require.NoError(t, receiver.Shutdown(ctx)) }) + + // wait for all provided data to be scraped + mp.wg.Wait() + metrics := cms.AllMetrics() + + // split and store results by target name + pResults := splitMetricsByTarget(metrics) + lres, lep := len(pResults), len(mp.endpoints) + assert.Equalf(t, lep, lres, "want %d targets, but got %v\n", lep, lres) + + // loop to validate outputs for each targets + for _, target := range targets { + t.Run(target.name, func(t *testing.T) { + validScrapes := pResults[target.name] + if !target.useOpenMetrics { + validScrapes = getValidScrapes(t, pResults[target.name]) + } + target.validateFunc(t, target, validScrapes) + }) + } }) } } @@ -559,3 +587,23 @@ func splitMetricsByTarget(metrics []pdata.Metrics) map[string][]*pdata.ResourceM } return pResults } + +func getTS(ms pdata.MetricSlice) pdata.Timestamp { + if ms.Len() == 0 { + return 0 + } + m := ms.At(0) + switch m.DataType() { + case pdata.MetricDataTypeGauge: + return m.Gauge().DataPoints().At(0).Timestamp() + case pdata.MetricDataTypeSum: + return m.Sum().DataPoints().At(0).Timestamp() + case pdata.MetricDataTypeHistogram: + return m.Histogram().DataPoints().At(0).Timestamp() + case pdata.MetricDataTypeSummary: + return m.Summary().DataPoints().At(0).Timestamp() + case pdata.MetricDataTypeExponentialHistogram: + return m.ExponentialHistogram().DataPoints().At(0).Timestamp() + } + return 0 +} diff --git a/receiver/prometheusreceiver/metrics_receiver_labels_test.go b/receiver/prometheusreceiver/metrics_receiver_labels_test.go index f2cb13a05c78c..4ff8671cec0b2 100644 --- a/receiver/prometheusreceiver/metrics_receiver_labels_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_labels_test.go @@ -17,6 +17,7 @@ package prometheusreceiver import ( "testing" + promcfg "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/pkg/labels" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/model/pdata" @@ -38,11 +39,9 @@ func TestExternalLabels(t *testing.T) { }, } - mp, cfg, err := setupMockPrometheus(false, targets...) - cfg.GlobalConfig.ExternalLabels = labels.FromStrings("key", "value") - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - - testComponentCustomConfig(t, targets, mp, cfg) + testComponentCustomConfig(t, targets, func(cfg *promcfg.Config) { + cfg.GlobalConfig.ExternalLabels = labels.FromStrings("key", "value") + }) } func verifyExternalLabels(t *testing.T, td *testData, rms []*pdata.ResourceMetrics) { @@ -130,15 +129,12 @@ func TestLabelLimitConfig(t *testing.T) { }, } - mp, cfg, err := setupMockPrometheus(false, targets...) - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - - // set label limit in scrape_config - for _, scrapeCfg := range cfg.ScrapeConfigs { - scrapeCfg.LabelLimit = 5 - } - - testComponentCustomConfig(t, targets, mp, cfg) + testComponentCustomConfig(t, targets, func(cfg *promcfg.Config) { + // set label limit in scrape_config + for _, scrapeCfg := range cfg.ScrapeConfigs { + scrapeCfg.LabelLimit = 5 + } + }) } const targetLabelLimits1 = ` @@ -174,7 +170,7 @@ func verifyLabelConfigTarget1(t *testing.T, td *testData, rms []*pdata.ResourceM want := td.attributes metrics1 := rms[0].InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("test_counter0", @@ -256,15 +252,12 @@ func TestLabelNameLimitConfig(t *testing.T) { }, } - mp, cfg, err := setupMockPrometheus(false, targets...) - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - - // set label name limit in scrape_config - for _, scrapeCfg := range cfg.ScrapeConfigs { - scrapeCfg.LabelNameLengthLimit = 20 - } - - testComponentCustomConfig(t, targets, mp, cfg) + testComponentCustomConfig(t, targets, func(cfg *promcfg.Config) { + // set label limit in scrape_config + for _, scrapeCfg := range cfg.ScrapeConfigs { + scrapeCfg.LabelNameLengthLimit = 20 + } + }) } const targetLabelValueLimit = ` @@ -295,15 +288,12 @@ func TestLabelValueLimitConfig(t *testing.T) { }, } - mp, cfg, err := setupMockPrometheus(false, targets...) - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - - //set label value length limit in scrape_config - for _, scrapeCfg := range cfg.ScrapeConfigs { - scrapeCfg.LabelValueLengthLimit = 25 - } - - testComponentCustomConfig(t, targets, mp, cfg) + testComponentCustomConfig(t, targets, func(cfg *promcfg.Config) { + // set label name limit in scrape_config + for _, scrapeCfg := range cfg.ScrapeConfigs { + scrapeCfg.LabelValueLengthLimit = 25 + } + }) } //for all metric types, testLabel has empty value @@ -339,7 +329,7 @@ func verifyEmptyLabelValuesTarget1(t *testing.T, td *testData, rms []*pdata.Reso want := td.attributes metrics1 := rms[0].InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("test_gauge0", @@ -410,7 +400,7 @@ func verifyEmptyLabelValuesTarget2(t *testing.T, td *testData, rms []*pdata.Reso want := td.attributes metrics1 := rms[0].InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("test_gauge0", @@ -470,7 +460,7 @@ func TestEmptyLabelValues(t *testing.T) { validateFunc: verifyEmptyLabelValuesTarget2, }, } - testComponent(t, targets, false, "", false) + testComponent(t, targets, false, "") } const honorLabelsTarget = ` @@ -513,7 +503,7 @@ func TestHonorLabelsFalseConfig(t *testing.T) { }, } - testComponent(t, targets, false, "", false) + testComponent(t, targets, false, "") } func verifyHonorLabelsTrue(t *testing.T, td *testData, rms []*pdata.ResourceMetrics) { @@ -560,12 +550,10 @@ func TestHonorLabelsTrueConfig(t *testing.T) { }, } - mp, cfg, err := setupMockPrometheus(false, targets...) - require.Nilf(t, err, "Failed to create Prometheus config: %v", err) - - for _, scrapeCfg := range cfg.ScrapeConfigs { - scrapeCfg.HonorLabels = true - } - - testComponentCustomConfig(t, targets, mp, cfg) + testComponentCustomConfig(t, targets, func(cfg *promcfg.Config) { + // set label name limit in scrape_config + for _, scrapeCfg := range cfg.ScrapeConfigs { + scrapeCfg.HonorLabels = true + } + }) } diff --git a/receiver/prometheusreceiver/metrics_receiver_open_metrics_test.go b/receiver/prometheusreceiver/metrics_receiver_open_metrics_test.go index afbf4b511de94..5ec7f5dc777b5 100644 --- a/receiver/prometheusreceiver/metrics_receiver_open_metrics_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_open_metrics_test.go @@ -68,12 +68,13 @@ func TestOpenMetricsPositive(t *testing.T) { pages: []mockPrometheusResponse{ {code: 200, data: v}, }, - validateFunc: verifyPositiveTarget, + validateFunc: verifyPositiveTarget, + useOpenMetrics: true, } targets = append(targets, testData) } - testComponent(t, targets, false, "", true) + testComponent(t, targets, false, "") } func verifyNegativeTarget(t *testing.T, td *testData, mds []*pdata.ResourceMetrics) { @@ -99,12 +100,13 @@ func TestOpenMetricsNegative(t *testing.T) { pages: []mockPrometheusResponse{ {code: 200, data: v}, }, - validateFunc: verifyNegativeTarget, + validateFunc: verifyNegativeTarget, + useOpenMetrics: true, } targets = append(targets, testData) } - testComponent(t, targets, false, "", true) + testComponent(t, targets, false, "") } //reads test data from testdata/openmetrics directory diff --git a/receiver/prometheusreceiver/metrics_receiver_test.go b/receiver/prometheusreceiver/metrics_receiver_test.go index e0fc5bdfd0695..00eb90ddf7d17 100644 --- a/receiver/prometheusreceiver/metrics_receiver_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_test.go @@ -95,7 +95,7 @@ func verifyTarget1(t *testing.T, td *testData, resourceMetrics []*pdata.Resource wantAttributes := td.attributes metrics1 := m1.InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -157,7 +157,7 @@ func verifyTarget1(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 9, metricsCount(m2)) metricsScrape2 := m2.InstrumentationLibraryMetrics().At(0).Metrics() - ts2 := metricsScrape2.At(0).Gauge().DataPoints().At(0).Timestamp() + ts2 := getTS(metricsScrape2) e2 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -289,7 +289,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []*pdata.Resource wantAttributes := td.attributes metrics1 := m1.InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -329,7 +329,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 7, metricsCount(m2)) metricsScrape2 := m2.InstrumentationLibraryMetrics().At(0).Metrics() - ts2 := metricsScrape2.At(0).Gauge().DataPoints().At(0).Timestamp() + ts2 := getTS(metricsScrape2) e2 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -377,7 +377,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 7, metricsCount(m3)) metricsScrape3 := m3.InstrumentationLibraryMetrics().At(0).Metrics() - ts3 := metricsScrape3.At(0).Gauge().DataPoints().At(0).Timestamp() + ts3 := getTS(metricsScrape3) e3 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -425,7 +425,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 7, metricsCount(m4)) metricsScrape4 := m4.InstrumentationLibraryMetrics().At(0).Metrics() - ts4 := metricsScrape4.At(0).Gauge().DataPoints().At(0).Timestamp() + ts4 := getTS(metricsScrape4) e4 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -473,7 +473,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 7, metricsCount(m5)) metricsScrape5 := m5.InstrumentationLibraryMetrics().At(0).Metrics() - ts5 := metricsScrape5.At(0).Gauge().DataPoints().At(0).Timestamp() + ts5 := getTS(metricsScrape5) e5 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -599,7 +599,7 @@ func verifyTarget3(t *testing.T, td *testData, resourceMetrics []*pdata.Resource wantAttributes := td.attributes metrics1 := m1.InstrumentationLibraryMetrics().At(0).Metrics() - ts1 := metrics1.At(0).Gauge().DataPoints().At(0).Timestamp() + ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -651,7 +651,7 @@ func verifyTarget3(t *testing.T, td *testData, resourceMetrics []*pdata.Resource assert.Equal(t, 8, metricsCount(m2)) metricsScrape2 := m2.InstrumentationLibraryMetrics().At(0).Metrics() - ts2 := metricsScrape2.At(0).Gauge().DataPoints().At(0).Timestamp() + ts2 := getTS(metricsScrape2) e2 := []testExpectation{ assertMetricPresent("go_threads", compareMetricType(pdata.MetricDataTypeGauge), @@ -734,7 +734,7 @@ func TestCoreMetricsEndToEnd(t *testing.T) { validateFunc: verifyTarget3, }, } - testComponent(t, targets, false, "", false) + testComponent(t, targets, false, "") } var startTimeMetricPage = ` @@ -781,26 +781,26 @@ func verifyStartTimeMetricPage(t *testing.T, td *testData, result []*pdata.Resou case pdata.MetricDataTypeGauge: timestamp = nil for j := 0; j < metrics[i].Gauge().DataPoints().Len(); j++ { - time := timestamppb.New(metrics[i].Gauge().DataPoints().At(j).StartTimestamp().AsTime()) + time := metrics[i].Gauge().DataPoints().At(j).StartTimestamp() assert.Equal(t, timestamp.AsTime(), time.AsTime()) numTimeseries++ } case pdata.MetricDataTypeSum: for j := 0; j < metrics[i].Sum().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), timestamppb.New(metrics[i].Sum().DataPoints().At(j).StartTimestamp().AsTime()).AsTime()) + assert.Equal(t, timestamp.AsTime(), metrics[i].Sum().DataPoints().At(j).StartTimestamp().AsTime()) numTimeseries++ } case pdata.MetricDataTypeHistogram: for j := 0; j < metrics[i].Histogram().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), timestamppb.New(metrics[i].Histogram().DataPoints().At(j).StartTimestamp().AsTime()).AsTime()) + assert.Equal(t, timestamp.AsTime(), metrics[i].Histogram().DataPoints().At(j).StartTimestamp().AsTime()) numTimeseries++ } case pdata.MetricDataTypeSummary: for j := 0; j < metrics[i].Summary().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), timestamppb.New(metrics[i].Summary().DataPoints().At(j).StartTimestamp().AsTime()).AsTime()) + assert.Equal(t, timestamp.AsTime(), metrics[i].Summary().DataPoints().At(j).StartTimestamp().AsTime()) numTimeseries++ } } @@ -820,7 +820,7 @@ func TestStartTimeMetric(t *testing.T) { validateFunc: verifyStartTimeMetricPage, }, } - testComponent(t, targets, true, "", false) + testComponent(t, targets, true, "") } var startTimeMetricRegexPage = ` @@ -869,5 +869,5 @@ func TestStartTimeMetricRegex(t *testing.T) { validateFunc: verifyStartTimeMetricPage, }, } - testComponent(t, targets, true, "^(.+_)*process_start_time_seconds$", false) + testComponent(t, targets, true, "^(.+_)*process_start_time_seconds$") }