From 3c5a021c7d60011a1c5cccd8dbcd9051f3f9556f Mon Sep 17 00:00:00 2001 From: Narcis Gemene <7252787+narcis96@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:21:53 +0300 Subject: [PATCH] Implementat huaweicloud ces receiver (#25) * adding go mod and huaweicloudreceiver folder * (config): add validation and config tests * add CES api calls --------- Co-authored-by: Heitor Ganzeli --- cmd/otelcontribcol/components.go | 2 + cmd/otelcontribcol/go.mod | 21 +- cmd/otelcontribcol/go.sum | 37 ++- receiver/huaweicloudcesreceiver/Makefile | 1 + receiver/huaweicloudcesreceiver/README.md | 205 ++++++++++++ receiver/huaweicloudcesreceiver/config.go | 130 ++++++++ .../huaweicloudcesreceiver/config_test.go | 150 +++++++++ receiver/huaweicloudcesreceiver/factory.go | 47 +++ .../generated_component_test.go | 69 +++++ .../generated_package_test.go | 12 + receiver/huaweicloudcesreceiver/go.mod | 75 +++++ receiver/huaweicloudcesreceiver/go.sum | 291 ++++++++++++++++++ .../internal/ces_to_otlp.go | 61 ++++ .../internal/ces_to_otlp_test.go | 135 ++++++++ .../internal/metadata/generated_status.go | 15 + receiver/huaweicloudcesreceiver/metadata.yaml | 9 + receiver/huaweicloudcesreceiver/receiver.go | 236 ++++++++++++++ 17 files changed, 1472 insertions(+), 24 deletions(-) create mode 100644 receiver/huaweicloudcesreceiver/Makefile create mode 100644 receiver/huaweicloudcesreceiver/README.md create mode 100644 receiver/huaweicloudcesreceiver/config.go create mode 100644 receiver/huaweicloudcesreceiver/config_test.go create mode 100644 receiver/huaweicloudcesreceiver/factory.go create mode 100644 receiver/huaweicloudcesreceiver/generated_component_test.go create mode 100644 receiver/huaweicloudcesreceiver/generated_package_test.go create mode 100644 receiver/huaweicloudcesreceiver/go.mod create mode 100644 receiver/huaweicloudcesreceiver/go.sum create mode 100644 receiver/huaweicloudcesreceiver/internal/ces_to_otlp.go create mode 100644 receiver/huaweicloudcesreceiver/internal/ces_to_otlp_test.go create mode 100644 receiver/huaweicloudcesreceiver/internal/metadata/generated_status.go create mode 100644 receiver/huaweicloudcesreceiver/metadata.yaml create mode 100644 receiver/huaweicloudcesreceiver/receiver.go diff --git a/cmd/otelcontribcol/components.go b/cmd/otelcontribcol/components.go index 2ca7c997d6d9..1d286f4d838b 100644 --- a/cmd/otelcontribcol/components.go +++ b/cmd/otelcontribcol/components.go @@ -156,6 +156,7 @@ import ( haproxyreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/haproxyreceiver" hostmetricsreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver" httpcheckreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/httpcheckreceiver" + huaweicloudcesreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver" iisreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" influxdbreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver" jaegerreceiver "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver" @@ -291,6 +292,7 @@ func components() (otelcol.Factories, error) { haproxyreceiver.NewFactory(), hostmetricsreceiver.NewFactory(), httpcheckreceiver.NewFactory(), + huaweicloudcesreceiver.NewFactory(), influxdbreceiver.NewFactory(), iisreceiver.NewFactory(), jaegerreceiver.NewFactory(), diff --git a/cmd/otelcontribcol/go.mod b/cmd/otelcontribcol/go.mod index 2a8ec664f9ca..bde411d40e87 100644 --- a/cmd/otelcontribcol/go.mod +++ b/cmd/otelcontribcol/go.mod @@ -146,6 +146,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/receiver/haproxyreceiver v0.102.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.102.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/httpcheckreceiver v0.102.0 + github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver v0.0.0-00010101000000-000000000000 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver v0.102.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver v0.102.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.102.0 @@ -205,7 +206,7 @@ require ( github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.102.1 go.opentelemetry.io/collector/config/configgrpc v0.102.1 - go.opentelemetry.io/collector/config/confighttp v0.102.0 + go.opentelemetry.io/collector/config/confighttp v0.102.1 go.opentelemetry.io/collector/config/configopaque v1.9.0 go.opentelemetry.io/collector/confmap v0.102.1 go.opentelemetry.io/collector/confmap/converter/expandconverter v0.102.0 @@ -230,7 +231,7 @@ require ( go.opentelemetry.io/collector/processor v0.102.0 go.opentelemetry.io/collector/processor/batchprocessor v0.102.0 go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.102.0 - go.opentelemetry.io/collector/receiver v0.102.0 + go.opentelemetry.io/collector/receiver v0.102.1 go.opentelemetry.io/collector/receiver/nopreceiver v0.102.0 go.opentelemetry.io/collector/receiver/otlpreceiver v0.102.0 golang.org/x/sys v0.21.0 @@ -462,7 +463,7 @@ require ( github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -470,7 +471,7 @@ require ( github.com/go-openapi/swag v0.22.9 // indirect github.com/go-resty/resty/v2 v2.12.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0 // indirect github.com/go-zookeeper/zk v1.0.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.2 // indirect @@ -527,6 +528,7 @@ require ( github.com/hashicorp/serf v0.10.1 // indirect github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect github.com/hetznercloud/hcloud-go/v2 v2.6.0 // indirect + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -715,6 +717,7 @@ require ( github.com/tidwall/wal v1.1.7 // indirect github.com/tilinna/clock v1.1.0 // indirect github.com/tinylib/msgp v1.1.9 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect github.com/valyala/fastjson v1.6.4 // indirect @@ -789,10 +792,10 @@ require ( golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.182.0 // indirect - google.golang.org/genproto v0.0.0-20240513163218-0867130af1f8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect - google.golang.org/grpc v1.64.1 // indirect + google.golang.org/genproto v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -841,6 +844,8 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/httpc replace github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/dockerobserver => ../../extension/observer/dockerobserver +replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver => ../../receiver/huaweicloudcesreceiver + replace github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/k8sobserver => ../../extension/observer/k8sobserver replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sentryexporter => ../../exporter/sentryexporter diff --git a/cmd/otelcontribcol/go.sum b/cmd/otelcontribcol/go.sum index 119aa2512b86..8cec51ea712d 100644 --- a/cmd/otelcontribcol/go.sum +++ b/cmd/otelcontribcol/go.sum @@ -1323,8 +1323,8 @@ github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7 github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -1358,8 +1358,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c= -github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -1641,6 +1641,8 @@ github.com/hetznercloud/hcloud-go/v2 v2.6.0/go.mod h1:4J1cSE57+g0WS93IiHLV7ubTHI github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104 h1:mCjW876Kx+y7LYxvbXVUxacN42AH2EJe715iZyPP1Fk= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104/go.mod h1:lhdEO9Bbb3hZ0wG+JeK9/GqMOp/sgc92mFmVk5tNSCk= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -2218,8 +2220,8 @@ github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU= github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= -github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM= -github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= @@ -2303,6 +2305,7 @@ go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsX go.mongodb.org/atlas v0.36.0 h1:m05S3AO7zkl+bcG1qaNsEKBnAqnKx2FDwLooHpIG3j4= go.mongodb.org/atlas v0.36.0/go.mod h1:nfPldE9dSama6G2IbIzmEza02Ly7yFZjMMVscaM0uEc= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -2324,8 +2327,8 @@ go.opentelemetry.io/collector/config/configcompression v1.9.0 h1:B2q6XMO6xiF2s+1 go.opentelemetry.io/collector/config/configcompression v1.9.0/go.mod h1:6+m0GKCv7JKzaumn7u80A2dLNCuYf5wdR87HWreoBO0= go.opentelemetry.io/collector/config/configgrpc v0.102.1 h1:6Plnfx+xw/JH8k11MkljGoysPfn1u7hHbO2evteOTeE= go.opentelemetry.io/collector/config/configgrpc v0.102.1/go.mod h1:Kk3XOSar3QTzGDS8N8M38DVlOzUD7STS2obczO9q43I= -go.opentelemetry.io/collector/config/confighttp v0.102.0 h1:rWdOoyChzyUnEPKJFLhvE69ztS7xwq4QZxCk+b78gsc= -go.opentelemetry.io/collector/config/confighttp v0.102.0/go.mod h1:gnpwVekcqmJB7Ljubs/aw8z8cwvB+crxxU/wfkTDtr4= +go.opentelemetry.io/collector/config/confighttp v0.102.1 h1:tPw1Xf2PfDdrXoBKLY5Sd4Dh8FNm5i+6DKuky9XraIM= +go.opentelemetry.io/collector/config/confighttp v0.102.1/go.mod h1:k4qscfjxuaDQmcAzioxmPujui9VSgW6oal3WLxp9CzI= go.opentelemetry.io/collector/config/confignet v0.102.1 h1:nSiAFQMzNCO4sDBztUxY73qFw4Vh0hVePq8+3wXUHtU= go.opentelemetry.io/collector/config/confignet v0.102.1/go.mod h1:pfOrCTfSZEB6H2rKtx41/3RN4dKs+X2EKQbw3MGRh0E= go.opentelemetry.io/collector/config/configopaque v1.9.0 h1:jocenLdK/rVG9UoGlnpiBxXLXgH5NhIXCrVSTyKVYuA= @@ -2392,8 +2395,8 @@ go.opentelemetry.io/collector/processor/batchprocessor v0.102.0 h1:lJSIMwip+Po5j go.opentelemetry.io/collector/processor/batchprocessor v0.102.0/go.mod h1:e71Y6SnrCjD19dPjxWWi/kXa5tb0J8rC+9xl/72mLo4= go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.102.0 h1:osoITPX0RITC8gJkyaNC6rqSKFl9wCeOqagjdNZUL70= go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.102.0/go.mod h1:2OVM2IJOWVdxkOOt0WCyQSMv2T19OSKNIy1KCqHGXyY= -go.opentelemetry.io/collector/receiver v0.102.0 h1:8rHNjWjV90bL0dgvKVc/7D10NCbM7bXCiqpcLRz5jBI= -go.opentelemetry.io/collector/receiver v0.102.0/go.mod h1:bYDwYItMrj7Drx0Pn4wZQ8Ii67lp9Nta62gbau93FhA= +go.opentelemetry.io/collector/receiver v0.102.1 h1:353t4U3o0RdU007JcQ4sRRzl72GHCJZwXDr8cCOcEbI= +go.opentelemetry.io/collector/receiver v0.102.1/go.mod h1:pYjMzUkvUlxJ8xt+VbI1to8HMtVlv8AW/K/2GQQOTB0= go.opentelemetry.io/collector/receiver/nopreceiver v0.102.0 h1:k2ExzXMqMXvV4g6OORziPDd0rxnZqxThAQ7SPFI6P2E= go.opentelemetry.io/collector/receiver/nopreceiver v0.102.0/go.mod h1:917QcjiKspazQBiuv3rS4Z7h0dkZEaKiZdJW4/VmpZc= go.opentelemetry.io/collector/receiver/otlpreceiver v0.102.0 h1:eLc+AK0IQDDysrMt3SLwKaOFIjEwdO8ipwSck3+TUXE= @@ -2481,6 +2484,7 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -2595,6 +2599,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/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-20201010224723-4f7140c49acb/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= @@ -3159,12 +3164,12 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20240513163218-0867130af1f8 h1:XpH03M6PDRKTo1oGfZBXu2SzwcbfxUokgobVinuUZoU= -google.golang.org/genproto v0.0.0-20240513163218-0867130af1f8/go.mod h1:OLh2Ylz+WlYAJaSBRpJIJLP8iQP+8da+fpxbwNEAV/o= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto v0.0.0-20240604185151-ef581f913117 h1:HCZ6DlkKtCDAtD8ForECsY3tKuaR+p4R3grlK80uCCc= +google.golang.org/genproto v0.0.0-20240604185151-ef581f913117/go.mod h1:lesfX/+9iA+3OdqeCpoDddJaNxVB1AB6tD7EfqMmprc= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/receiver/huaweicloudcesreceiver/Makefile b/receiver/huaweicloudcesreceiver/Makefile new file mode 100644 index 000000000000..c1496226e590 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/Makefile @@ -0,0 +1 @@ +include ../../Makefile.Common \ No newline at end of file diff --git a/receiver/huaweicloudcesreceiver/README.md b/receiver/huaweicloudcesreceiver/README.md new file mode 100644 index 000000000000..1656b13386b6 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/README.md @@ -0,0 +1,205 @@ +# Huawei Cloud CES Receiver + + +| Status | | +| ------------- |-----------| +| Stability | [development]: metrics | +| Distributions | [] | +| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fhuaweicloudces%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Areceiver%2Fhuaweicloudces) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fhuaweicloudces%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Areceiver%2Fhuaweicloudces) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@heitorganzeli](https://www.github.com/heitorganzeli), [@narcis96](https://www.github.com/narcis96) | + +[development]: https://github.com/open-telemetry/opentelemetry-collector#development + + +This receiver contains the implementation of the Huawei Cloud [Cloud Eye Service](https://www.huaweicloud.com/intl/en-us/product/ces.html) (CES) receiver for the OpenTelemetry Collector. The receiver collects metrics from Huawei Cloud's CES service and sends them to the OpenTelemetry Collector for processing and exporting. + +## Configuration + +The following settings are required: + +- `region_name`: The name of the Huawei Cloud region from which metrics are collected. For example, `eu-west-101`. The full list of the available regions can be found [here](https://pkg.go.dev/github.com/huaweicloud/huaweicloud-sdk-go-v3@v0.1.104/services/ces/v1/region). + +- `project_id`: The ID of the project in Huawei Cloud. This is used to identify which project's metrics are to be collected. See [Obtaining a Project ID](https://support.huaweicloud.com/intl/en-us/devg-apisign/api-sign-provide-proid.html). + +- `period`: The aggregation granularity of metrics retrieved from CES in seconds. For details about the aggregation, see [What Is Rollup?](https://support.huaweicloud.com/intl/en-us/ces_faq/ces_faq_0009.html). Possible values are 1, 300, 1200, 3600, 14400, and 86400. + - 1: Cloud Eye performs no aggregation and displays raw data. + - 300: Cloud Eye aggregates data every 5 minutes. + - 1200: Cloud Eye aggregates data every 20 minutes. + - 3600: Cloud Eye aggregates data every hour. + - 14400: Cloud Eye aggregates data every 4 hours. + - 86400: Cloud Eye aggregates data every 24 hours. +- `filter`: The filter field determines the aggregation method used for the metrics. This aggregation is applied to the data points within the specified period. Valid values for filter include: + + - `average`: Calculates the average value over the period. + - `min`: Retrieves the minimum value within the period. + - `max`: Retrieves the maximum value within the period. + - `sum`: Computes the sum of all data points within the period. + - `variance`: Calculates the variance (square of the standard deviation) for the data points. + +- `no_verify_ssl`: A boolean flag indicating whether SSL verification should be disabled. Set to True to disable SSL verification. + +The following settings are optional: + +- `initial_delay`: The delay before the first collection of metrics begins. This is a duration field, such as 5s for 5 seconds. + +- `collection_interval` (default = `60s`): This is the interval at which this receiver collects metrics. This value must be a string readable by Golang's [time.ParseDuration](https://pkg.go.dev/time#ParseDuration). Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. + +### Example Configuration + +```yaml +receivers: + huaweicloudcesreceiver: + collection_interval: 3h + initial_delay: 5s + region_name: eu-west-101 + project_id: "project_1" + period: 300 + filter: average + no_verify_ssl: True +``` + +The full list of settings exposed for this receiver are documented [here](./config.go). + +### Huawei Cloud SDK Authentication Setup + + +To ensure secure authentication, the Access Key (AK) and Secret Key (SK) used by the Huawei Cloud SDK must be stored in environment variables. See [Obtaining an AK/SK](https://support.huaweicloud.com/intl/en-us/devg-apisign/api-sign-provide-aksk.html). + +Before running the application, you need to set the environment variables `HUAWEICLOUD_SDK_AK` and `HUAWEICLOUD_SDK_SK` in your local environment. Here’s how you can do it: + +1. Open your terminal. +2. Set the environment variables by executing the following commands: + + ```sh + export HUAWEICLOUD_SDK_AK=your-access-key + export HUAWEICLOUD_SDK_SK=your-secret-key + ``` + +3. Verify that the variables are set correctly: + + ```sh + echo $HUAWEICLOUD_SDK_AK + echo $HUAWEICLOUD_SDK_SK + ``` + +## Converting CES metric representation to Open Telementery metric representation + + +| Source Field | Target Field | Description | +|---------------------------------------------|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------| +| **metric_name** | `metrics.name` | The name of the metric. | +| **unit** | `metrics.unit` | The unit of the metric, e.g., `%`, `bit/s`. | +| **datapoints.value** | `metrics.gauge.dataPoints.asDouble` | The value of the metric at the specified timestamp. | +| **datapoints.timestamp** | `metrics.gauge.dataPoints.timeUnixNano` | The timestamp of the metric in nanoseconds. Converted from milliseconds by multiplying by 1,000,000. | +| **namespace** | `metrics.metadata` | The namespace of the metric, e.g., `SYS.VPC` is stored in the metadata map using the key `namespace`. | +| **dimensions.name** | key of `metrics.metadata` | The dimension name stored as metadata key. | +| **dimensions.value** | value of `metrics.metadata` | The dimension value stored as metadata value. | +| **Receiver Config** | `resource.attributes.project.id` | The project id used in the configuration file of the receiver. | +| **Receiver Config** | `resource.attributes.region` | The region name used in the configuration file of the receiver. | +| *N/A* | `resource.attributes.cloud.provider` | Set to `"huawei_cloud"` as the cloud provider. | +| *N/A* | `resource.attributes.service.name` | Set to `"ces_service"` to indicate the service name. | +| *N/A* | `resource.attributes.service.version` | Set to `"v1"` as the service version. | +| *N/A* | `scopeMetrics.scope.name` | Set to `"huawei_cloud_ces"` as the scope name. | +| *N/A* | `scopeMetrics.scope.version` | Set to `"v1"` as the scope version. | + +### Notes + +- The `timestamp` field in the source is converted from milliseconds to nanoseconds in the target field. +- Some fields are added in the target format with constant values to provide additional context and metadata. + +### Example: + +```json +[ + { + "unit": "%", + "datapoints": [ + { "average": 10, "timestamp": 1722580500000 }, + { "average": 20, "timestamp": 1722580800000 } + ], + "namespace": "SYS.VPC", + "metric_name": "upstream_bandwidth_usage", + "dimensions": [ + { + "name": "publicip_id", + "value": "test-baae-4dd9-ad3f-1234" + } + ] + }, + { + "unit": "bit/s", + "datapoints": [ + { "average": 1024, "timestamp": 1722580500000}, + { "average": 2048, "timestamp": 1722580800000} + ], + "namespace": "SYS.VPC", + "metric_name": "downstream_bandwidth", + "dimensions": [ + { + "name": "publicip_id", + "value": "test-baae-4dd9-ad3f-1234" + } + ] + } +] +``` + +converts to + +```json +{ + "resourceMetrics": [ + { + "resource": { + "attributes": { + "cloud.provider": "huawei_cloud", + "service.name": "ces_service", + "service.version": "v1", + "project.id": "project_1", + "region": "eu-west-101" + } + }, + "scopeMetrics": [ + { + "scope": { "name": "huawei_cloud_ces", "version": "v1" }, + "metrics": [ + { + "name": "upstream_bandwidth_usage", + "unit": "%", + "gauge": { + "dataPoints": [ + { "timeUnixNano": "1722580500000000000", "asDouble": 10 }, + { "timeUnixNano": "1722580800000000000", "asDouble": 20 } + ] + }, + "metadata": { + "publicip_id": "test-baae-4dd9-ad3f-1234", + "namespace" : "SYS.VPC" + } + } + ] + }, + { + "scope": { "name": "huawei_cloud_ces", "version": "v1" }, + "metrics": [ + { + "name": "downstream_bandwidth_usage", + "unit": "%", + "gauge": { + "dataPoints": [ + { "timeUnixNano": "1722580500000000000", "asDouble": 1024 }, + { "timeUnixNano": "1722580800000000000", "asDouble": 2048 } + ] + }, + "metadata": { + "publicip_id": "test-baae-4dd9-ad3f-1234", + "namespace":"SYS.VPC" + } + } + ] + } + ] + } + ] +} +``` \ No newline at end of file diff --git a/receiver/huaweicloudcesreceiver/config.go b/receiver/huaweicloudcesreceiver/config.go new file mode 100644 index 000000000000..b87f17b4fc96 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/config.go @@ -0,0 +1,130 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package huaweicloudcesreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver" + +import ( + "errors" + "fmt" + "regexp" + "slices" + "strings" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/receiver/scraperhelper" + "go.uber.org/multierr" +) + +const ( + maxDimensions = 4 + maxMetricRetention = 604800 +) + +var ( + namespaceRegex = regexp.MustCompile(`[A-Za-z][a-zA-Z_0-9]{0,29}\.[a-zA-Z_0-9]{1,30}`) + namespaceForbiddenServices = map[string]any{ + "SYS": struct{}{}, + "AGT": struct{}{}, + "SRE": struct{}{}, + } + forbiddenNamespace = "SERVICE.BMS" +) + +var ( + // Predefined error responses for configuration validation failures + errMissingRegionName = errors.New(`"region_name" is not specified in config`) + errMissingProjectID = errors.New(`"project_id" is not specified in config`) + errInvalidCollectionInterval = errors.New(`invalid period; must be less than "collection_interval"`) + errInvalidProxy = errors.New(`"proxy_address" must be specified if "proxy_user" or "proxy_password" is set"`) +) + +// Config represent a configuration for the CloudWatch logs exporter. +type Config struct { + scraperhelper.ControllerConfig `mapstructure:",squash"` + confighttp.ClientConfig `mapstructure:",squash"` + // Nodes defines the nodes to scrape. + // See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/cluster.html#cluster-nodes for which selectors may be used here. + // If Nodes is empty, no nodes will be scraped. + Nodes []string `mapstructure:"nodes"` + // SkipClusterMetrics indicates whether cluster level metrics from /_cluster/* endpoints should be scraped or not. + SkipClusterMetrics bool `mapstructure:"skip_cluster_metrics"` + // Indices defines the indices to scrape. + // See https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-stats.html#index-stats-api-path-params + // for which names are viable. + // If Indices is empty, no indices will be scraped. + Indices []string `mapstructure:"indices"` + // Set of attributes used to configure huawei's CES SDK connection + HuaweiSessionConfig `mapstructure:",squash"` + + // ProjectId is a string to reference project where metrics should be associated with. + // If ProjectId is not filled in, the SDK will automatically call the IAM service to query the project id corresponding to the region. + ProjectId string `mapstructure:"project_id"` + // How retrieved data from Cloud Eye is aggregated. + // Possible values are 1, 300, 1200, 3600, 14400, and 86400. + // 1: Cloud Eye performs no aggregation and displays raw data. + // 300: Cloud Eye aggregates data every 5 minutes. + // 1200: Cloud Eye aggregates data every 20 minutes. + // 3600: Cloud Eye aggregates data every hour. + // 14400: Cloud Eye aggregates data every 4 hours. + // 86400: Cloud Eye aggregates data every 24 hours. + // For details about the aggregation, see https://support.huaweicloud.com/intl/en-us/ces_faq/ces_faq_0009.html + Period int `mapstructure:"period"` + + // Data aggregation method. The supported values ​​are max, min, average, sum, variance. + Filter string `mapstructure:"filter"` +} + +type HuaweiSessionConfig struct { + // RegionName is the full name of the CES region exporter should send metrics to + RegionName string `mapstructure:"region_name"` + // Number of seconds before timing out a request. + NoVerifySSL bool `mapstructure:"no_verify_ssl"` + // Upload segments to AWS X-Ray through a proxy. + ProxyAddress string `mapstructure:"proxy_address"` + ProxyUser string `mapstructure:"proxy_user"` + ProxyPassword string `mapstructure:"proxy_password"` +} + +var _ component.Config = (*Config)(nil) + +var validPeriods = []int{1, 300, 1200, 3600, 14400, 86400} + +var validFilters = []string{"max", "min", "average", "sum", "variance"} + +// Validate config +func (config *Config) Validate() error { + var err error = nil + if config.RegionName == "" { + err = multierr.Append(err, errMissingRegionName) + } + + if config.ProjectId == "" { + err = multierr.Append(err, errMissingProjectID) + } + if index := slices.Index(validPeriods, config.Period); index == -1 { + err = multierr.Append(err, fmt.Errorf("invalid period: got %d; must be one of %v", config.Period, validPeriods)) + } + + if index := slices.Index(validFilters, config.Filter); index == -1 { + err = multierr.Append(err, fmt.Errorf("invalid filter: got %s; must be one of %v", config.Filter, validFilters)) + } + if config.Period >= int(config.CollectionInterval.Seconds()) { + err = multierr.Append(err, errInvalidCollectionInterval) + } + + // Validate that ProxyAddress is provided if ProxyUser or ProxyPassword is set + if (config.ProxyUser != "" || config.ProxyPassword != "") && config.ProxyAddress == "" { + err = multierr.Append(err, errInvalidProxy) + } + + return err +} + +func KeysString(m map[string]any) string { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + return "[" + strings.Join(keys, ", ") + "]" +} diff --git a/receiver/huaweicloudcesreceiver/config_test.go b/receiver/huaweicloudcesreceiver/config_test.go new file mode 100644 index 000000000000..c69b12a2a56b --- /dev/null +++ b/receiver/huaweicloudcesreceiver/config_test.go @@ -0,0 +1,150 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package huaweicloudcesreceiver + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/receiver/scraperhelper" +) + +func TestConfig_Validate(t *testing.T) { + tests := []struct { + name string + config Config + expectedError string + }{ + { + name: "Valid config", + config: Config{ + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + }, + ProjectId: "my_project", + Period: 300, + Filter: "min", + }, + expectedError: "", + }, + { + name: "Invalid Period", + config: Config{ + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + }, + ProjectId: "my_project", + Period: 100, + Filter: "min", + }, + expectedError: "invalid period", + }, + { + name: "Invalid Filter", + config: Config{ + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + }, + ProjectId: "my_project", + Period: 300, + Filter: "invalid", + }, + expectedError: "invalid filter", + }, + { + name: "Missing region name", + config: Config{ + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + ProjectId: "my_project", + Period: 300, + Filter: "min", + }, + expectedError: errMissingRegionName.Error(), + }, + { + name: "Missing project id", + config: Config{ + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + }, + Period: 300, + Filter: "min", + }, + expectedError: errMissingProjectID.Error(), + }, + { + name: "Proxy user without proxy address", + config: Config{ + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + ProxyUser: "user", + }, + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + ProjectId: "my_project", + Period: 300, + Filter: "min", + }, + expectedError: errInvalidProxy.Error(), + }, + { + name: "Proxy password without proxy address", + config: Config{ + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + ProxyPassword: "password", + }, + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + ProjectId: "my_project", + Period: 300, + Filter: "min", + }, + expectedError: errInvalidProxy.Error(), + }, + { + name: "Proxy address with proxy user and password", + config: Config{ + HuaweiSessionConfig: HuaweiSessionConfig{ + RegionName: "cn-north-1", + ProxyAddress: "http://proxy.example.com", + ProxyUser: "user", + ProxyPassword: "password", + }, + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + }, + ProjectId: "my_project", + Period: 300, + Filter: "min", + }, + expectedError: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.config.Validate() + if tt.expectedError == "" { + assert.NoError(t, err) + } else { + assert.ErrorContains(t, err, tt.expectedError) + } + }) + } +} diff --git a/receiver/huaweicloudcesreceiver/factory.go b/receiver/huaweicloudcesreceiver/factory.go new file mode 100644 index 000000000000..6cb218721e20 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/factory.go @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:generate mdatagen metadata.yaml + +// Package huaweicloudexporter provides a metrics exporter for the OpenTelemetry collector. +// This package is subject to change and may break configuration settings and behavior. +package huaweicloudcesreceiver + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver" + + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver/internal/metadata" +) + +func NewFactory() receiver.Factory { + return receiver.NewFactory( + metadata.Type, + createDefaultConfig, + receiver.WithMetrics(createMetricsReceiver, metadata.MetricsStability)) +} + +func createDefaultConfig() component.Config { + return &Config{ + HuaweiSessionConfig: HuaweiSessionConfig{ + NoVerifySSL: false, + }, + } +} + +func createMetricsReceiver( + _ context.Context, + params receiver.CreateSettings, + cfg component.Config, + next consumer.Metrics) (receiver.Metrics, error) { + + cesCfg := cfg.(*Config) + + cesReceiver := newHuaweiCloudCesReceiver(params, cesCfg, next) + + return cesReceiver, nil + +} diff --git a/receiver/huaweicloudcesreceiver/generated_component_test.go b/receiver/huaweicloudcesreceiver/generated_component_test.go new file mode 100644 index 000000000000..fcd782791cdb --- /dev/null +++ b/receiver/huaweicloudcesreceiver/generated_component_test.go @@ -0,0 +1,69 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package huaweicloudcesreceiver + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func TestComponentFactoryType(t *testing.T) { + require.Equal(t, "huaweicloudcesreceiver", NewFactory().Type().String()) +} + +func TestComponentConfigStruct(t *testing.T) { + require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig())) +} + +func TestComponentLifecycle(t *testing.T) { + factory := NewFactory() + + tests := []struct { + name string + createFn func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) + }{ + + { + name: "metrics", + createFn: func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) { + return factory.CreateMetricsReceiver(ctx, set, cfg, consumertest.NewNop()) + }, + }, + } + + cm, err := confmaptest.LoadConf("metadata.yaml") + require.NoError(t, err) + cfg := factory.CreateDefaultConfig() + sub, err := cm.Sub("tests::config") + require.NoError(t, err) + require.NoError(t, sub.Unmarshal(&cfg)) + + for _, test := range tests { + t.Run(test.name+"-shutdown", func(t *testing.T) { + c, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + err = c.Shutdown(context.Background()) + require.NoError(t, err) + }) + t.Run(test.name+"-lifecycle", func(t *testing.T) { + firstRcvr, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + host := componenttest.NewNopHost() + require.NoError(t, err) + require.NoError(t, firstRcvr.Start(context.Background(), host)) + require.NoError(t, firstRcvr.Shutdown(context.Background())) + secondRcvr, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + require.NoError(t, secondRcvr.Start(context.Background(), host)) + require.NoError(t, secondRcvr.Shutdown(context.Background())) + }) + } +} diff --git a/receiver/huaweicloudcesreceiver/generated_package_test.go b/receiver/huaweicloudcesreceiver/generated_package_test.go new file mode 100644 index 000000000000..ebacfa323d23 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/generated_package_test.go @@ -0,0 +1,12 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package huaweicloudcesreceiver + +import ( + "go.uber.org/goleak" + "testing" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/receiver/huaweicloudcesreceiver/go.mod b/receiver/huaweicloudcesreceiver/go.mod new file mode 100644 index 000000000000..6a2ad853160a --- /dev/null +++ b/receiver/huaweicloudcesreceiver/go.mod @@ -0,0 +1,75 @@ +module github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver + +go 1.21.0 + +require ( + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104 + github.com/stretchr/testify v1.9.0 + go.opentelemetry.io/collector/component v0.102.1 + go.opentelemetry.io/collector/config/confighttp v0.102.1 + go.opentelemetry.io/collector/confmap v0.102.1 + go.opentelemetry.io/collector/consumer v0.102.1 + go.opentelemetry.io/collector/pdata v1.9.0 + go.opentelemetry.io/collector/receiver v0.102.1 + go.uber.org/goleak v1.3.0 + go.uber.org/multierr v1.11.0 + go.uber.org/zap v1.27.0 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/knadh/koanf/maps v0.1.1 // indirect + github.com/knadh/koanf/providers/confmap v0.1.0 // indirect + github.com/knadh/koanf/v2 v2.1.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect + github.com/rs/cors v1.11.0 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect + go.mongodb.org/mongo-driver v1.15.0 // indirect + go.opentelemetry.io/collector v0.102.1 // indirect + go.opentelemetry.io/collector/config/configauth v0.102.1 // indirect + go.opentelemetry.io/collector/config/configcompression v1.9.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.9.0 // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.102.1 // indirect + go.opentelemetry.io/collector/config/configtls v0.102.1 // indirect + go.opentelemetry.io/collector/config/internal v0.102.1 // indirect + go.opentelemetry.io/collector/extension v0.102.1 // indirect + go.opentelemetry.io/collector/extension/auth v0.102.1 // indirect + go.opentelemetry.io/collector/featuregate v1.9.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.49.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/sdk v1.27.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/receiver/huaweicloudcesreceiver/go.sum b/receiver/huaweicloudcesreceiver/go.sum new file mode 100644 index 000000000000..5830795a603a --- /dev/null +++ b/receiver/huaweicloudcesreceiver/go.sum @@ -0,0 +1,291 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104 h1:mCjW876Kx+y7LYxvbXVUxacN42AH2EJe715iZyPP1Fk= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.104/go.mod h1:lhdEO9Bbb3hZ0wG+JeK9/GqMOp/sgc92mFmVk5tNSCk= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= +github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= +github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= +github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= +github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM= +github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= +go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.opentelemetry.io/collector v0.102.1 h1:M/ciCcReQsSDYG9bJ2Qwqk7pQILDJ2bM/l0MdeCAvJE= +go.opentelemetry.io/collector v0.102.1/go.mod h1:yF1lDRgL/Eksb4/LUnkMjvLvHHpi6wqBVlzp+dACnPM= +go.opentelemetry.io/collector/component v0.102.1 h1:66z+LN5dVCXhvuVKD1b56/3cYLK+mtYSLIwlskYA9IQ= +go.opentelemetry.io/collector/component v0.102.1/go.mod h1:XfkiSeImKYaewT2DavA80l0VZ3JjvGndZ8ayPXfp8d0= +go.opentelemetry.io/collector/config/configauth v0.102.1 h1:LuzijaZulMu4xmAUG8WA00ZKDlampH+ERjxclb40Q9g= +go.opentelemetry.io/collector/config/configauth v0.102.1/go.mod h1:kTzfI5fnbMJpm2wycVtQeWxFAtb7ns4HksSb66NIhX8= +go.opentelemetry.io/collector/config/configcompression v1.9.0 h1:B2q6XMO6xiF2s+14XjqAQHGY5UefR+PtkZ0WAlmSqpU= +go.opentelemetry.io/collector/config/configcompression v1.9.0/go.mod h1:6+m0GKCv7JKzaumn7u80A2dLNCuYf5wdR87HWreoBO0= +go.opentelemetry.io/collector/config/confighttp v0.102.1 h1:tPw1Xf2PfDdrXoBKLY5Sd4Dh8FNm5i+6DKuky9XraIM= +go.opentelemetry.io/collector/config/confighttp v0.102.1/go.mod h1:k4qscfjxuaDQmcAzioxmPujui9VSgW6oal3WLxp9CzI= +go.opentelemetry.io/collector/config/configopaque v1.9.0 h1:jocenLdK/rVG9UoGlnpiBxXLXgH5NhIXCrVSTyKVYuA= +go.opentelemetry.io/collector/config/configopaque v1.9.0/go.mod h1:8v1yaH4iYjcigbbyEaP/tzVXeFm4AaAsKBF9SBeqaG4= +go.opentelemetry.io/collector/config/configtelemetry v0.102.1 h1:f/CYcrOkaHd+COIJ2lWnEgBCHfhEycpbow4ZhrGwAlA= +go.opentelemetry.io/collector/config/configtelemetry v0.102.1/go.mod h1:WxWKNVAQJg/Io1nA3xLgn/DWLE/W1QOB2+/Js3ACi40= +go.opentelemetry.io/collector/config/configtls v0.102.1 h1:7fr+PU9BRg0HRc1Pn3WmDW/4WBHRjuo7o1CdG2vQKoA= +go.opentelemetry.io/collector/config/configtls v0.102.1/go.mod h1:KHdrvo3cwosgDxclyiLWmtbovIwqvaIGeTXr3p5721A= +go.opentelemetry.io/collector/config/internal v0.102.1 h1:HFsFD3xpHUuNHb8/UTz5crJw1cMHzsJQf/86sgD44hw= +go.opentelemetry.io/collector/config/internal v0.102.1/go.mod h1:Vig3dfeJJnuRe1kBNpszBzPoj5eYnR51wXbeq36Zfpg= +go.opentelemetry.io/collector/confmap v0.102.1 h1:wZuH+d/P11Suz8wbp+xQCJ0BPE9m5pybtUe74c+rU7E= +go.opentelemetry.io/collector/confmap v0.102.1/go.mod h1:KgpS7UxH5rkd69CzAzlY2I1heH8Z7eNCZlHmwQBMxNg= +go.opentelemetry.io/collector/consumer v0.102.1 h1:0CkgHhxwx4lI/m+hWjh607xyjooW5CObZ8hFQy5vvo0= +go.opentelemetry.io/collector/consumer v0.102.1/go.mod h1:HoXqmrRV13jLnP3/Gg3fYNdRkDPoO7UW58hKiLyFF60= +go.opentelemetry.io/collector/extension v0.102.1 h1:gAvE3w15q+Vv0Tj100jzcDpeMTyc8dAiemHRtJbspLg= +go.opentelemetry.io/collector/extension v0.102.1/go.mod h1:XBxUOXjZpwYLZYOK5u3GWlbBTOKmzStY5eU1R/aXkIo= +go.opentelemetry.io/collector/extension/auth v0.102.1 h1:GP6oBmpFJjxuVruPb9X40bdf6PNu9779i8anxa+wW6U= +go.opentelemetry.io/collector/extension/auth v0.102.1/go.mod h1:U2JWz8AW1QXX2Ap3ofzo5Dn2fZU/Lglld97Vbh8BZS0= +go.opentelemetry.io/collector/featuregate v1.9.0 h1:mC4/HnR5cx/kkG1RKOQAvHxxg5Ktmd9gpFdttPEXQtA= +go.opentelemetry.io/collector/featuregate v1.9.0/go.mod h1:PsOINaGgTiFc+Tzu2K/X2jP+Ngmlp7YKGV1XrnBkH7U= +go.opentelemetry.io/collector/pdata v1.9.0 h1:qyXe3HEVYYxerIYu0rzgo1Tx2d1Zs6iF+TCckbHLFOw= +go.opentelemetry.io/collector/pdata v1.9.0/go.mod h1:vk7LrfpyVpGZrRWcpjyy0DDZzL3SZiYMQxfap25551w= +go.opentelemetry.io/collector/pdata/testdata v0.102.1 h1:S3idZaJxy8M7mCC4PG4EegmtiSaOuh6wXWatKIui8xU= +go.opentelemetry.io/collector/pdata/testdata v0.102.1/go.mod h1:JEoSJTMgeTKyGxoMRy48RMYyhkA5vCCq/abJq9B6vXs= +go.opentelemetry.io/collector/receiver v0.102.1 h1:353t4U3o0RdU007JcQ4sRRzl72GHCJZwXDr8cCOcEbI= +go.opentelemetry.io/collector/receiver v0.102.1/go.mod h1:pYjMzUkvUlxJ8xt+VbI1to8HMtVlv8AW/K/2GQQOTB0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/exporters/prometheus v0.49.0 h1:Er5I1g/YhfYv9Affk9nJLfH/+qCCVVg1f2R9AbJfqDQ= +go.opentelemetry.io/otel/exporters/prometheus v0.49.0/go.mod h1:KfQ1wpjf3zsHjzP149P4LyAwWRupc6c7t1ZJ9eXpKQM= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/receiver/huaweicloudcesreceiver/internal/ces_to_otlp.go b/receiver/huaweicloudcesreceiver/internal/ces_to_otlp.go new file mode 100644 index 000000000000..633d339255fd --- /dev/null +++ b/receiver/huaweicloudcesreceiver/internal/ces_to_otlp.go @@ -0,0 +1,61 @@ +package internal + +import ( + "time" + + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +func ConvertCESMetricsToOTLP(projectID, region, filter string, cesMetrics []model.BatchMetricData) pmetric.Metrics { + metrics := pmetric.NewMetrics() + if len(cesMetrics) == 0 { + return metrics + } + resourceMetric := metrics.ResourceMetrics().AppendEmpty() + + resource := resourceMetric.Resource() + resource.Attributes().PutStr("cloud.provider", "huawei_cloud") + resource.Attributes().PutStr("project.id", projectID) + resource.Attributes().PutStr("region", region) + + for _, cesMetric := range cesMetrics { + scopedMetric := resourceMetric.ScopeMetrics().AppendEmpty() + scopedMetric.Scope().SetName("huawei_cloud_ces") + scopedMetric.Scope().SetVersion("v1") + + metric := scopedMetric.Metrics().AppendEmpty() + metric.SetName(cesMetric.MetricName) + if cesMetric.Unit != nil { + metric.SetUnit(*cesMetric.Unit) + } + if cesMetric.Dimensions != nil { + for _, dimension := range *cesMetric.Dimensions { + metric.Metadata().PutStr(dimension.Name, dimension.Value) + } + } + if cesMetric.Namespace != nil { + metric.Metadata().PutStr("service.namespace", *cesMetric.Namespace) + } + dataPoints := metric.SetEmptyGauge().DataPoints() + for _, dataPoint := range cesMetric.Datapoints { + dp := dataPoints.AppendEmpty() + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(dataPoint.Timestamp))) + switch filter { + case "max": + dp.SetDoubleValue(*dataPoint.Max) + case "min": + dp.SetDoubleValue(*dataPoint.Min) + case "average": + dp.SetDoubleValue(*dataPoint.Average) + case "sum": + dp.SetDoubleValue(*dataPoint.Sum) + case "variance": + dp.SetDoubleValue(*dataPoint.Variance) + } + } + } + + return metrics +} diff --git a/receiver/huaweicloudcesreceiver/internal/ces_to_otlp_test.go b/receiver/huaweicloudcesreceiver/internal/ces_to_otlp_test.go new file mode 100644 index 000000000000..d2f8e3d1eaf0 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/internal/ces_to_otlp_test.go @@ -0,0 +1,135 @@ +package internal + +import ( + "testing" + "time" + + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model" + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +func stringPtr(s string) *string { + return &s +} + +func float64Ptr(f float64) *float64 { + return &f +} +func TestConvertCESMetricsToOTLP(t *testing.T) { + tests := []struct { + name string + input []model.BatchMetricData + expected func() pmetric.Metrics + }{ + { + name: "Valid Metric Conversion", + input: []model.BatchMetricData{ + { + Namespace: stringPtr("SYS.ECS"), + MetricName: "cpu_util", + Dimensions: &[]model.MetricsDimension{ + { + Name: "instance_id", + Value: "faea5b75-e390-4e2b-8733-9226a9026070", + }, + }, + Datapoints: []model.DatapointForBatchMetric{ + { + Average: float64Ptr(0.5), + Timestamp: 1556625610000, + }, + { + Average: float64Ptr(0.7), + Timestamp: 1556625715000, + }, + }, + Unit: stringPtr("%"), + }, + { + Namespace: stringPtr("SYS.ECS"), + MetricName: "network_vm_connections", + Dimensions: &[]model.MetricsDimension{ + { + Name: "instance_id", + Value: "06b4020f-461a-4a52-84da-53fa71c2f42b", + }, + }, + Datapoints: []model.DatapointForBatchMetric{ + { + Average: float64Ptr(1), + Timestamp: 1556625612000, + }, + { + Average: float64Ptr(3), + Timestamp: 1556625717000, + }, + }, + Unit: stringPtr("count"), + }, + }, + expected: func() pmetric.Metrics { + metrics := pmetric.NewMetrics() + resourceMetric := metrics.ResourceMetrics().AppendEmpty() + + resource := resourceMetric.Resource() + resource.Attributes().PutStr("cloud.provider", "huawei_cloud") + resource.Attributes().PutStr("project.id", "project_1") + resource.Attributes().PutStr("region", "eu-west-101") + + scopedMetric := resourceMetric.ScopeMetrics().AppendEmpty() + scopedMetric.Scope().SetName("huawei_cloud_ces") + scopedMetric.Scope().SetVersion("v1") + + metric := scopedMetric.Metrics().AppendEmpty() + metric.SetName("cpu_util") + metric.SetUnit("%") + metric.Metadata().PutStr("instance_id", "faea5b75-e390-4e2b-8733-9226a9026070") + metric.Metadata().PutStr("service.namespace", "SYS.ECS") + + dataPoints := metric.SetEmptyGauge().DataPoints() + dp := dataPoints.AppendEmpty() + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(1556625610000))) + dp.SetDoubleValue(0.5) + + dp = dataPoints.AppendEmpty() + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(1556625715000))) + dp.SetDoubleValue(0.7) + + scopedMetric = resourceMetric.ScopeMetrics().AppendEmpty() + scopedMetric.Scope().SetName("huawei_cloud_ces") + scopedMetric.Scope().SetVersion("v1") + + metric = scopedMetric.Metrics().AppendEmpty() + metric.SetName("network_vm_connections") + metric.SetUnit("count") + metric.Metadata().PutStr("instance_id", "06b4020f-461a-4a52-84da-53fa71c2f42b") + metric.Metadata().PutStr("service.namespace", "SYS.ECS") + + dataPoints = metric.SetEmptyGauge().DataPoints() + dp = dataPoints.AppendEmpty() + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(1556625612000))) + dp.SetDoubleValue(1) + + dp = dataPoints.AppendEmpty() + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(1556625717000))) + dp.SetDoubleValue(3) + return metrics + }, + }, + { + name: "Empty Metric Data", + input: []model.BatchMetricData{}, + expected: func() pmetric.Metrics { + return pmetric.NewMetrics() + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected(), ConvertCESMetricsToOTLP("project_1", "eu-west-101", "average", tt.input)) + }) + } +} diff --git a/receiver/huaweicloudcesreceiver/internal/metadata/generated_status.go b/receiver/huaweicloudcesreceiver/internal/metadata/generated_status.go new file mode 100644 index 000000000000..b88757e87c3d --- /dev/null +++ b/receiver/huaweicloudcesreceiver/internal/metadata/generated_status.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/component" +) + +var ( + Type = component.MustNewType("huaweicloudcesreceiver") +) + +const ( + MetricsStability = component.StabilityLevelDevelopment +) diff --git a/receiver/huaweicloudcesreceiver/metadata.yaml b/receiver/huaweicloudcesreceiver/metadata.yaml new file mode 100644 index 000000000000..a812525a9ee2 --- /dev/null +++ b/receiver/huaweicloudcesreceiver/metadata.yaml @@ -0,0 +1,9 @@ +type: huaweicloudcesreceiver + +status: + class: receiver + stability: + development: [metrics] + distributions: [] + codeowners: + active: [heitorganzeli, narcis96] diff --git a/receiver/huaweicloudcesreceiver/receiver.go b/receiver/huaweicloudcesreceiver/receiver.go new file mode 100644 index 000000000000..be4235b0051f --- /dev/null +++ b/receiver/huaweicloudcesreceiver/receiver.go @@ -0,0 +1,236 @@ +package huaweicloudcesreceiver + +import ( + "context" + "errors" + "net/url" + "os" + "strconv" + "time" + + "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic" + "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config" + ces "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1" + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model" + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/region" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver/internal" +) + +type cesReceiver struct { + logger *zap.Logger + client *ces.CesClient + cancel context.CancelFunc + + host component.Host + nextConsumer consumer.Metrics + lastUsedFinishTs time.Time + config *Config +} + +func newHuaweiCloudCesReceiver(settings receiver.CreateSettings, cfg *Config, next consumer.Metrics) *cesReceiver { + rcvr := &cesReceiver{ + logger: settings.Logger, + config: cfg, + nextConsumer: next, + } + return rcvr +} + +func (rcvr *cesReceiver) Start(ctx context.Context, host component.Host) (err error) { + rcvr.host = host + ctx, rcvr.cancel = context.WithCancel(ctx) + + if rcvr.client == nil { + rcvr.client, err = rcvr.createClient() + if err != nil { + rcvr.logger.Error(err.Error()) + return + } + } + + go func() { + if rcvr.config.InitialDelay > 0 { + <-time.After(rcvr.config.InitialDelay) + } + if err := rcvr.pollMetricsAndConsume(ctx); err != nil { + rcvr.logger.Error(err.Error()) + } + ticker := time.NewTicker(rcvr.config.CollectionInterval) + + defer ticker.Stop() + for { + select { + case <-ticker.C: + // TODO: Improve error handling for client-server interactions + // The current implementation lacks robust error handling, especially for + // scenarios such as service unavailability, timeouts, and request errors. + // - Investigate how to handle service unavailability or timeouts gracefully. + // - Implement appropriate actions or retries for different types of request errors. + // - Refer to the Huawei SDK documentation to identify + // all possible client/request errors and determine how to manage them. + // - Consider implementing custom error messages or fallback mechanisms for critical failures. + + if err := rcvr.pollMetricsAndConsume(ctx); err != nil { + rcvr.logger.Error(err.Error()) + } + case <-ctx.Done(): + return + } + } + }() + return nil +} + +func (rcvr *cesReceiver) createClient() (*ces.CesClient, error) { + auth, err := basic.NewCredentialsBuilder(). + // Authentication can be configured through environment variables and other methods. + // Please refer to Chapter 2.4 Authentication Management + WithAk(os.Getenv("HUAWEICLOUD_SDK_AK")). + WithSk(os.Getenv("HUAWEICLOUD_SDK_SK")). + WithProjectId(rcvr.config.ProjectId). + SafeBuild() + + if err != nil { + return nil, err + } + + httpConfig := config.DefaultHttpConfig(). + WithIgnoreSSLVerification(rcvr.config.NoVerifySSL) + + if rcvr.config.ProxyAddress != "" { + proxy, err := rcvr.configureHttpProxy() + if err != nil { + return nil, err + } + httpConfig = config.DefaultHttpConfig().WithProxy(proxy) + } + + r, err := region.SafeValueOf(rcvr.config.RegionName) + if err != nil { + return nil, err + } + + hcHttpConfig, err := ces.CesClientBuilder(). + WithRegion(r). + WithCredential(auth). + WithHttpConfig(httpConfig). + SafeBuild() + + if err != nil { + return nil, err + } + + client := ces.NewCesClient(hcHttpConfig) + + return client, nil +} + +func (rcvr *cesReceiver) pollMetricsAndConsume(ctx context.Context) error { + metricDefinitions, err := rcvr.listMetricDefinitions() + if err != nil { + return err + } + cesMetrics, err := rcvr.listDataPoints(metricDefinitions) + if err != nil { + rcvr.logger.Error(err.Error()) + return err + } + metrics := internal.ConvertCESMetricsToOTLP(rcvr.config.ProjectId, rcvr.config.RegionName, rcvr.config.Filter, cesMetrics) + if err := rcvr.nextConsumer.ConsumeMetrics(ctx, metrics); err != nil { + return err + } + return nil +} + +func (rcvr *cesReceiver) listMetricDefinitions() ([]model.MetricInfoList, error) { + response, err := rcvr.client.ListMetrics(&model.ListMetricsRequest{}) + if err != nil { + return []model.MetricInfoList{}, err + } + if response.Metrics == nil || len((*response.Metrics)) == 0 { + return []model.MetricInfoList{}, errors.New("empty list of metric definitions") + } + + return *response.Metrics, nil +} + +func convertMetricInfoListArrayToMetricInfoArray(infoListArray []model.MetricInfoList) []model.MetricInfo { + infoArray := make([]model.MetricInfo, len(infoListArray)) + for i, infoList := range infoListArray { + infoArray[i] = model.MetricInfo{ + Namespace: infoList.Namespace, + MetricName: infoList.MetricName, + Dimensions: infoList.Dimensions, + } + } + return infoArray +} + +func (rcvr *cesReceiver) listDataPoints(metricDefinitions []model.MetricInfoList) ([]model.BatchMetricData, error) { + // TODO: Handle delayed metrics. CES accepts metrics with up to a 30-minute delay. + // If the request is based on the current time ('now'), it may miss metrics delayed by a minute or more, + // as the next request would exclude them. Consider adding a delay configuration to account for this. + // TODO: Implement deduplication: There may be a need for deduplication, possibly using a Processor to ensure unique metrics are processed. + to := time.Now() + var from time.Time + if rcvr.lastUsedFinishTs.IsZero() { + from = to.Add(-1 * rcvr.config.CollectionInterval) + } else { + from = rcvr.lastUsedFinishTs + } + rcvr.lastUsedFinishTs = to + metrics := convertMetricInfoListArrayToMetricInfoArray(metricDefinitions) + + response, err := rcvr.client.BatchListMetricData(&model.BatchListMetricDataRequest{ + Body: &model.BatchListMetricDataRequestBody{ + Metrics: metrics, + Period: strconv.Itoa(rcvr.config.Period), + Filter: rcvr.config.Filter, + From: from.UnixMilli(), + To: to.UnixMilli(), + }, + }) + if err != nil { + return []model.BatchMetricData{}, err + } + if response.Metrics == nil || len(*response.Metrics) == 0 { + return []model.BatchMetricData{}, errors.New("empty list of metric data") + } + return *response.Metrics, nil +} + +func (rcvr *cesReceiver) configureHttpProxy() (*config.Proxy, error) { + proxyUrl, err := url.Parse(rcvr.config.ProxyAddress) + if err != nil { + return nil, err + } + + proxy := config.NewProxy(). + WithSchema(proxyUrl.Scheme). + WithHost(proxyUrl.Hostname()) + if len(proxyUrl.Port()) > 0 { + if i, err := strconv.Atoi(proxyUrl.Port()); err == nil { + proxy = proxy.WithPort(i) + } + } + + // Configure the username and password if the proxy requires authentication + if len(rcvr.config.ProxyUser) > 0 { + proxy = proxy. + WithUsername(rcvr.config.ProxyUser). + WithPassword(rcvr.config.ProxyPassword) + } + return proxy, nil +} + +func (rcvr *cesReceiver) Shutdown(ctx context.Context) error { + if rcvr.cancel != nil { + rcvr.cancel() + } + return nil +}