diff --git a/exporter/sumologicexporter/documentation.md b/exporter/sumologicexporter/documentation.md new file mode 100644 index 000000000000..496f2364e084 --- /dev/null +++ b/exporter/sumologicexporter/documentation.md @@ -0,0 +1,39 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# sumologic + +## Internal Telemetry + +The following telemetry is emitted by this component. + +### exporter_requests_bytes + +Total size of requests (in bytes) + +| Unit | Metric Type | Value Type | Monotonic | +| ---- | ----------- | ---------- | --------- | +| By | Sum | Int | true | + +### exporter_requests_duration + +Duration of HTTP requests (in milliseconds) + +| Unit | Metric Type | Value Type | Monotonic | +| ---- | ----------- | ---------- | --------- | +| ms | Sum | Int | true | + +### exporter_requests_records + +Total size of requests (in number of records) + +| Unit | Metric Type | Value Type | Monotonic | +| ---- | ----------- | ---------- | --------- | +| {records} | Sum | Int | true | + +### exporter_requests_sent + +Number of requests + +| Unit | Metric Type | Value Type | Monotonic | +| ---- | ----------- | ---------- | --------- | +| 1 | Sum | Int | true | diff --git a/exporter/sumologicexporter/exporter.go b/exporter/sumologicexporter/exporter.go index 83c5da079c15..e710fe37fa13 100644 --- a/exporter/sumologicexporter/exporter.go +++ b/exporter/sumologicexporter/exporter.go @@ -23,6 +23,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/metadata" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/sumologicextension" ) @@ -55,18 +56,24 @@ type sumologicexporter struct { stickySessionCookieLock sync.RWMutex stickySessionCookie string - id component.ID - sender *sender + id component.ID + sender *sender + telemetryBuilder *metadata.TelemetryBuilder } -func initExporter(cfg *Config, createSettings exporter.Settings) *sumologicexporter { +func initExporter(cfg *Config, set exporter.Settings) (*sumologicexporter, error) { + telemetryBuilder, err := metadata.NewTelemetryBuilder(set.TelemetrySettings) + if err != nil { + return nil, err + } se := &sumologicexporter{ config: cfg, - logger: createSettings.Logger, + logger: set.Logger, // NOTE: client is now set in start() prometheusFormatter: newPrometheusFormatter(), - id: createSettings.ID, + id: set.ID, foundSumologicExtension: false, + telemetryBuilder: telemetryBuilder, } se.logger.Info( @@ -75,7 +82,7 @@ func initExporter(cfg *Config, createSettings exporter.Settings) *sumologicexpor zap.String("metric_format", string(cfg.MetricFormat)), ) - return se + return se, nil } func newLogsExporter( @@ -83,7 +90,10 @@ func newLogsExporter( params exporter.Settings, cfg *Config, ) (exporter.Logs, error) { - se := initExporter(cfg, params) + se, err := initExporter(cfg, params) + if err != nil { + return nil, err + } return exporterhelper.NewLogsExporter( ctx, @@ -105,7 +115,10 @@ func newMetricsExporter( params exporter.Settings, cfg *Config, ) (exporter.Metrics, error) { - se := initExporter(cfg, params) + se, err := initExporter(cfg, params) + if err != nil { + return nil, err + } return exporterhelper.NewMetricsExporter( ctx, @@ -127,7 +140,10 @@ func newTracesExporter( params exporter.Settings, cfg *Config, ) (exporter.Traces, error) { - se := initExporter(cfg, params) + se, err := initExporter(cfg, params) + if err != nil { + return nil, err + } return exporterhelper.NewTracesExporter( ctx, @@ -243,6 +259,7 @@ func (se *sumologicexporter) configure(ctx context.Context) error { se.StickySessionCookie, se.SetStickySessionCookie, se.id, + se.telemetryBuilder, ) return nil diff --git a/exporter/sumologicexporter/exporter_test.go b/exporter/sumologicexporter/exporter_test.go index 3f2dbf381fc0..421bc7839c1a 100644 --- a/exporter/sumologicexporter/exporter_test.go +++ b/exporter/sumologicexporter/exporter_test.go @@ -21,12 +21,11 @@ import ( "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/consumer/consumererror" - "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/ptrace" - "go.uber.org/zap" ) func logRecordsToLogs(records []plog.LogRecord) plog.Logs { @@ -54,14 +53,6 @@ func createTestConfig() *Config { return config } -func createExporterCreateSettings() exporter.Settings { - return exporter.Settings{ - TelemetrySettings: component.TelemetrySettings{ - Logger: zap.NewNop(), - }, - } -} - // prepareExporterTest prepares an exporter test object using provided config // and a slice of callbacks to be called for subsequent requests coming being // sent to the server. @@ -91,7 +82,8 @@ func prepareExporterTest(t *testing.T, cfg *Config, cb []func(w http.ResponseWri cfg.ClientConfig.Endpoint = testServer.URL cfg.ClientConfig.Auth = nil - exp := initExporter(cfg, createExporterCreateSettings()) + exp, err := initExporter(cfg, exportertest.NewNopSettings()) + require.NoError(t, err) require.NoError(t, exp.start(context.Background(), componenttest.NewNopHost())) @@ -244,7 +236,7 @@ func TestPartiallyFailed(t *testing.T) { } func TestInvalidHTTPCLient(t *testing.T) { - exp := initExporter(&Config{ + exp, err := initExporter(&Config{ ClientConfig: confighttp.ClientConfig{ Endpoint: "test_endpoint", TLSSetting: configtls.ClientConfig{ @@ -253,7 +245,8 @@ func TestInvalidHTTPCLient(t *testing.T) { }, }, }, - }, createExporterCreateSettings()) + }, exportertest.NewNopSettings()) + require.NoError(t, err) assert.EqualError(t, exp.start(context.Background(), componenttest.NewNopHost()), @@ -516,7 +509,8 @@ func Benchmark_ExporterPushLogs(b *testing.B) { cfg := createConfig() cfg.ClientConfig.Endpoint = testServer.URL - exp := initExporter(cfg, createExporterCreateSettings()) + exp, err := initExporter(cfg, exportertest.NewNopSettings()) + require.NoError(b, err) require.NoError(b, exp.start(context.Background(), componenttest.NewNopHost())) defer func() { require.NoError(b, exp.shutdown(context.Background())) diff --git a/exporter/sumologicexporter/generated_component_telemetry_test.go b/exporter/sumologicexporter/generated_component_telemetry_test.go new file mode 100644 index 000000000000..0acc5b16b41c --- /dev/null +++ b/exporter/sumologicexporter/generated_component_telemetry_test.go @@ -0,0 +1,76 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package sumologicexporter + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exportertest" +) + +type componentTestTelemetry struct { + reader *sdkmetric.ManualReader + meterProvider *sdkmetric.MeterProvider +} + +func (tt *componentTestTelemetry) NewSettings() exporter.Settings { + settings := exportertest.NewNopSettings() + settings.MeterProvider = tt.meterProvider + settings.ID = component.NewID(component.MustNewType("sumologic")) + + return settings +} + +func setupTestTelemetry() componentTestTelemetry { + reader := sdkmetric.NewManualReader() + return componentTestTelemetry{ + reader: reader, + meterProvider: sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)), + } +} + +func (tt *componentTestTelemetry) assertMetrics(t *testing.T, expected []metricdata.Metrics) { + var md metricdata.ResourceMetrics + require.NoError(t, tt.reader.Collect(context.Background(), &md)) + // ensure all required metrics are present + for _, want := range expected { + got := tt.getMetric(want.Name, md) + metricdatatest.AssertEqual(t, want, got, metricdatatest.IgnoreTimestamp()) + } + + // ensure no additional metrics are emitted + require.Equal(t, len(expected), tt.len(md)) +} + +func (tt *componentTestTelemetry) getMetric(name string, got metricdata.ResourceMetrics) metricdata.Metrics { + for _, sm := range got.ScopeMetrics { + for _, m := range sm.Metrics { + if m.Name == name { + return m + } + } + } + + return metricdata.Metrics{} +} + +func (tt *componentTestTelemetry) len(got metricdata.ResourceMetrics) int { + metricsCount := 0 + for _, sm := range got.ScopeMetrics { + metricsCount += len(sm.Metrics) + } + + return metricsCount +} + +func (tt *componentTestTelemetry) Shutdown(ctx context.Context) error { + return tt.meterProvider.Shutdown(ctx) +} diff --git a/exporter/sumologicexporter/generated_package_test.go b/exporter/sumologicexporter/generated_package_test.go index f18b099d8cd7..06d9480a812b 100644 --- a/exporter/sumologicexporter/generated_package_test.go +++ b/exporter/sumologicexporter/generated_package_test.go @@ -9,5 +9,5 @@ import ( ) func TestMain(m *testing.M) { - goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start")) + goleak.VerifyTestMain(m) } diff --git a/exporter/sumologicexporter/go.mod b/exporter/sumologicexporter/go.mod index 9f9b731818fb..00242a67eba7 100644 --- a/exporter/sumologicexporter/go.mod +++ b/exporter/sumologicexporter/go.mod @@ -6,18 +6,20 @@ require ( github.com/klauspost/compress v1.17.9 github.com/open-telemetry/opentelemetry-collector-contrib/extension/sumologicextension v0.104.0 github.com/stretchr/testify v1.9.0 - go.opencensus.io v0.24.0 go.opentelemetry.io/collector/component v0.104.0 go.opentelemetry.io/collector/config/configauth v0.104.0 go.opentelemetry.io/collector/config/configcompression v1.11.0 go.opentelemetry.io/collector/config/confighttp v0.104.0 go.opentelemetry.io/collector/config/configretry v1.11.0 + go.opentelemetry.io/collector/config/configtelemetry v0.104.0 go.opentelemetry.io/collector/config/configtls v0.104.0 go.opentelemetry.io/collector/confmap v0.104.0 go.opentelemetry.io/collector/consumer v0.104.0 go.opentelemetry.io/collector/exporter v0.104.0 go.opentelemetry.io/collector/pdata v1.11.0 + go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.0 @@ -37,7 +39,6 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // 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 @@ -65,17 +66,14 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/collector v0.104.0 // indirect go.opentelemetry.io/collector/config/configopaque v1.11.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.104.0 // indirect go.opentelemetry.io/collector/config/internal v0.104.0 // indirect go.opentelemetry.io/collector/extension v0.104.0 // indirect go.opentelemetry.io/collector/extension/auth v0.104.0 // indirect go.opentelemetry.io/collector/featuregate v1.11.0 // indirect go.opentelemetry.io/collector/receiver v0.104.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/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/exporter/sumologicexporter/go.sum b/exporter/sumologicexporter/go.sum index 9ead8ca03a73..20e14f900dfa 100644 --- a/exporter/sumologicexporter/go.sum +++ b/exporter/sumologicexporter/go.sum @@ -1,23 +1,14 @@ -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/Showmax/go-fqdn v1.0.0 h1:0rG5IbmVliNT5O19Mfuvna9LL7zlHyRfsSvBPZmF9tM= github.com/Showmax/go-fqdn v1.0.0/go.mod h1:SfrFBzmDCtCGrnHhoDjuvFnKsWjEQX/Q9ARZvOrJAko= 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/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -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.1-0.20191026205805-5f8ba28d4473/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= @@ -33,32 +24,12 @@ github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsM github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/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/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -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.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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/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.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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= @@ -98,7 +69,6 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= 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.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= @@ -116,12 +86,7 @@ github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= 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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -132,8 +97,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector v0.104.0 h1:R3zjM4O3K3+ttzsjPV75P80xalxRbwYTURlK0ys7uyo= go.opentelemetry.io/collector v0.104.0/go.mod h1:Tm6F3na9ajnOm6I5goU9dURKxq1fSBK1yA94nvUix3k= go.opentelemetry.io/collector/component v0.104.0 h1:jqu/X9rnv8ha0RNZ1a9+x7OU49KwSMsPbOuIEykHuQE= @@ -197,32 +160,19 @@ 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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -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/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 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/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-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -237,10 +187,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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= @@ -248,36 +194,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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 v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/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.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -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.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 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/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/exporter/sumologicexporter/internal/metadata/generated_telemetry.go b/exporter/sumologicexporter/internal/metadata/generated_telemetry.go index 569f0d965551..52a34ba5efe2 100644 --- a/exporter/sumologicexporter/internal/metadata/generated_telemetry.go +++ b/exporter/sumologicexporter/internal/metadata/generated_telemetry.go @@ -3,9 +3,14 @@ package metadata import ( - "go.opentelemetry.io/collector/component" + "errors" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configtelemetry" ) func Meter(settings component.TelemetrySettings) metric.Meter { @@ -15,3 +20,64 @@ func Meter(settings component.TelemetrySettings) metric.Meter { func Tracer(settings component.TelemetrySettings) trace.Tracer { return settings.TracerProvider.Tracer("otelcol/sumologic") } + +// TelemetryBuilder provides an interface for components to report telemetry +// as defined in metadata and user config. +type TelemetryBuilder struct { + meter metric.Meter + ExporterRequestsBytes metric.Int64Counter + ExporterRequestsDuration metric.Int64Counter + ExporterRequestsRecords metric.Int64Counter + ExporterRequestsSent metric.Int64Counter + level configtelemetry.Level +} + +// telemetryBuilderOption applies changes to default builder. +type telemetryBuilderOption func(*TelemetryBuilder) + +// WithLevel sets the current telemetry level for the component. +func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { + return func(builder *TelemetryBuilder) { + builder.level = lvl + } +} + +// NewTelemetryBuilder provides a struct with methods to update all internal telemetry +// for a component +func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { + builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + for _, op := range options { + op(&builder) + } + var err, errs error + if builder.level >= configtelemetry.LevelBasic { + builder.meter = Meter(settings) + } else { + builder.meter = noop.Meter{} + } + builder.ExporterRequestsBytes, err = builder.meter.Int64Counter( + "exporter_requests_bytes", + metric.WithDescription("Total size of requests (in bytes)"), + metric.WithUnit("By"), + ) + errs = errors.Join(errs, err) + builder.ExporterRequestsDuration, err = builder.meter.Int64Counter( + "exporter_requests_duration", + metric.WithDescription("Duration of HTTP requests (in milliseconds)"), + metric.WithUnit("ms"), + ) + errs = errors.Join(errs, err) + builder.ExporterRequestsRecords, err = builder.meter.Int64Counter( + "exporter_requests_records", + metric.WithDescription("Total size of requests (in number of records)"), + metric.WithUnit("{records}"), + ) + errs = errors.Join(errs, err) + builder.ExporterRequestsSent, err = builder.meter.Int64Counter( + "exporter_requests_sent", + metric.WithDescription("Number of requests"), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + return &builder, errs +} diff --git a/exporter/sumologicexporter/internal/metadata/generated_telemetry_test.go b/exporter/sumologicexporter/internal/metadata/generated_telemetry_test.go index 9c43a5be65fc..7f2cf8b08856 100644 --- a/exporter/sumologicexporter/internal/metadata/generated_telemetry_test.go +++ b/exporter/sumologicexporter/internal/metadata/generated_telemetry_test.go @@ -61,3 +61,16 @@ func TestProviders(t *testing.T) { require.Fail(t, "returned Meter not mockTracer") } } + +func TestNewTelemetryBuilder(t *testing.T) { + set := component.TelemetrySettings{ + MeterProvider: mockMeterProvider{}, + TracerProvider: mockTracerProvider{}, + } + applied := false + _, err := NewTelemetryBuilder(set, func(b *TelemetryBuilder) { + applied = true + }) + require.NoError(t, err) + require.True(t, applied) +} diff --git a/exporter/sumologicexporter/internal/observability/observability.go b/exporter/sumologicexporter/internal/observability/observability.go deleted file mode 100644 index 8476713bd2c7..000000000000 --- a/exporter/sumologicexporter/internal/observability/observability.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package observability // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/observability" - -import ( - "context" - "fmt" - "time" - - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -func init() { - err := view.Register( - viewRequestsSent, - viewRequestsDuration, - viewRequestsBytes, - viewRequestsRecords, - ) - if err != nil { - fmt.Printf("Failed to register sumologic exporter's views: %v\n", err) - } -} - -var ( - mRequestsSent = stats.Int64("exporter/requests/sent", "Number of requests", "1") - mRequestsDuration = stats.Int64("exporter/requests/duration", "Duration of HTTP requests (in milliseconds)", "0") - mRequestsBytes = stats.Int64("exporter/requests/bytes", "Total size of requests (in bytes)", "0") - mRequestsRecords = stats.Int64("exporter/requests/records", "Total size of requests (in number of records)", "0") - - statusKey, _ = tag.NewKey("status_code") // nolint:errcheck - endpointKey, _ = tag.NewKey("endpoint") // nolint:errcheck - pipelineKey, _ = tag.NewKey("pipeline") // nolint:errcheck - exporterKey, _ = tag.NewKey("exporter") // nolint:errcheck -) - -var viewRequestsSent = &view.View{ - Name: mRequestsSent.Name(), - Description: mRequestsSent.Description(), - Measure: mRequestsSent, - TagKeys: []tag.Key{statusKey, endpointKey, pipelineKey, exporterKey}, - Aggregation: view.Count(), -} - -var viewRequestsDuration = &view.View{ - Name: mRequestsDuration.Name(), - Description: mRequestsDuration.Description(), - Measure: mRequestsDuration, - TagKeys: []tag.Key{statusKey, endpointKey, pipelineKey, exporterKey}, - Aggregation: view.Sum(), -} - -var viewRequestsBytes = &view.View{ - Name: mRequestsBytes.Name(), - Description: mRequestsBytes.Description(), - Measure: mRequestsBytes, - TagKeys: []tag.Key{statusKey, endpointKey, pipelineKey, exporterKey}, - Aggregation: view.Sum(), -} - -var viewRequestsRecords = &view.View{ - Name: mRequestsRecords.Name(), - Description: mRequestsRecords.Description(), - Measure: mRequestsRecords, - TagKeys: []tag.Key{statusKey, endpointKey, pipelineKey, exporterKey}, - Aggregation: view.Sum(), -} - -// RecordRequestsSent increments the metric that records sent requests -func RecordRequestsSent(statusCode int, endpoint string, pipeline string, exporter string) error { - return stats.RecordWithTags( - context.Background(), - []tag.Mutator{ - tag.Insert(statusKey, fmt.Sprint(statusCode)), - tag.Insert(endpointKey, endpoint), - tag.Insert(pipelineKey, pipeline), - tag.Insert(exporterKey, exporter), - }, - mRequestsSent.M(int64(1)), - ) -} - -// RecordRequestsDuration update metric which records request duration -func RecordRequestsDuration(duration time.Duration, statusCode int, endpoint string, pipeline string, exporter string) error { - return stats.RecordWithTags( - context.Background(), - []tag.Mutator{ - tag.Insert(statusKey, fmt.Sprint(statusCode)), - tag.Insert(endpointKey, endpoint), - tag.Insert(pipelineKey, pipeline), - tag.Insert(exporterKey, exporter), - }, - mRequestsDuration.M(duration.Milliseconds()), - ) -} - -// RecordRequestsBytes update metric which records number of send bytes -func RecordRequestsBytes(bytes int64, statusCode int, endpoint string, pipeline string, exporter string) error { - return stats.RecordWithTags( - context.Background(), - []tag.Mutator{ - tag.Insert(statusKey, fmt.Sprint(statusCode)), - tag.Insert(endpointKey, endpoint), - tag.Insert(pipelineKey, pipeline), - tag.Insert(exporterKey, exporter), - }, - mRequestsBytes.M(bytes), - ) -} - -// RecordRequestsRecords update metric which records number of sent records -func RecordRequestsRecords(records int64, statusCode int, endpoint string, pipeline string, exporter string) error { - return stats.RecordWithTags( - context.Background(), - []tag.Mutator{ - tag.Insert(statusKey, fmt.Sprint(statusCode)), - tag.Insert(endpointKey, endpoint), - tag.Insert(pipelineKey, pipeline), - tag.Insert(exporterKey, exporter), - }, - mRequestsRecords.M(records), - ) -} diff --git a/exporter/sumologicexporter/internal/observability/observability_test.go b/exporter/sumologicexporter/internal/observability/observability_test.go deleted file mode 100644 index 321394115ac8..000000000000 --- a/exporter/sumologicexporter/internal/observability/observability_test.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package observability // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/observability" - -import ( - "context" - "sort" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opencensus.io/metric/metricdata" - "go.opencensus.io/metric/metricexport" -) - -type exporter struct { - pipe chan *metricdata.Metric -} - -func newExporter() *exporter { - return &exporter{ - make(chan *metricdata.Metric), - } -} - -// Run goroutine which is going to receive `after` metrics. -// Goroutine is writing to returned chan -func (e *exporter) ReturnAfter(after int) chan []*metricdata.Metric { - ch := make(chan []*metricdata.Metric) - go func() { - received := []*metricdata.Metric{} - for m := range e.pipe { - received = append(received, m) - if len(received) >= after { - break - } - } - ch <- received - }() - return ch -} - -// Write received metrics to data channel -func (e *exporter) ExportMetrics(_ context.Context, data []*metricdata.Metric) error { - for _, m := range data { - e.pipe <- m - } - return nil -} - -// Creates metrics reader and forward metrics from it to chData -// Sens empty structs to fail chan afterwards -func metricReader(chData chan []*metricdata.Metric, fail chan struct{}, count int) { - - // Add a manual retry mechanism in case there's a hiccup reading the - // metrics from producers in ReadAndExport(): we can wait for the metrics - // to come instead of failing because they didn't come right away. - for i := 0; i < 10; i++ { - e := newExporter() - ch := e.ReturnAfter(count) - go metricexport.NewReader().ReadAndExport(e) - - select { - case <-time.After(500 * time.Millisecond): - - case data := <-ch: - chData <- data - return - } - } - - fail <- struct{}{} -} - -// NOTE: -// This test can only be run with -count 1 because of static -// metricproducer.GlobalManager() used in metricexport.NewReader(). -func TestMetrics(t *testing.T) { - const ( - statusCode = 200 - endpoint = "some/uri" - pipeline = "metrics" - exporter = "sumologic/my-name" - bytesFunc = "bytes" - recordsFunc = "records" - durationFunc = "duration" - sentFunc = "sent" - ) - type testCase struct { - name string - bytes int64 - records int64 - recordFunc string - duration time.Duration - } - tests := []testCase{ - { - name: "exporter/requests/sent", - recordFunc: sentFunc, - }, - { - name: "exporter/requests/duration", - recordFunc: durationFunc, - duration: time.Millisecond, - }, - { - name: "exporter/requests/bytes", - recordFunc: bytesFunc, - bytes: 1, - }, - { - name: "exporter/requests/records", - recordFunc: recordsFunc, - records: 1, - }, - } - - var ( - fail = make(chan struct{}) - chData = make(chan []*metricdata.Metric) - ) - - go metricReader(chData, fail, len(tests)) - - for _, tt := range tests { - switch tt.recordFunc { - case sentFunc: - require.NoError(t, RecordRequestsSent(statusCode, endpoint, pipeline, exporter)) - case durationFunc: - require.NoError(t, RecordRequestsDuration(tt.duration, statusCode, endpoint, pipeline, exporter)) - case bytesFunc: - require.NoError(t, RecordRequestsBytes(tt.bytes, statusCode, endpoint, pipeline, exporter)) - case recordsFunc: - require.NoError(t, RecordRequestsRecords(tt.records, statusCode, endpoint, pipeline, exporter)) - } - } - - var data []*metricdata.Metric - select { - case <-fail: - t.Fatalf("timedout waiting for metrics to arrive") - case data = <-chData: - } - - sort.Slice(tests, func(i, j int) bool { - return tests[i].name < tests[j].name - }) - - sort.Slice(data, func(i, j int) bool { - return data[i].Descriptor.Name < data[j].Descriptor.Name - }) - - for i, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.Len(t, data, len(tests)) - d := data[i] - assert.Equal(t, tt.name, d.Descriptor.Name, "Expected %v at index %v, but got %v.", tt.name, i, d.Descriptor.Name) - require.Len(t, d.TimeSeries, 1) - require.Len(t, d.TimeSeries[0].Points, 1) - assert.Equal(t, d.TimeSeries[0].Points[0].Value, int64(1)) - - require.Len(t, d.TimeSeries[0].LabelValues, 4) - - require.True(t, d.TimeSeries[0].LabelValues[0].Present) - require.True(t, d.TimeSeries[0].LabelValues[1].Present) - require.True(t, d.TimeSeries[0].LabelValues[2].Present) - require.True(t, d.TimeSeries[0].LabelValues[3].Present) - - assert.Equal(t, d.TimeSeries[0].LabelValues[0].Value, "some/uri") - assert.Equal(t, d.TimeSeries[0].LabelValues[1].Value, "sumologic/my-name") - assert.Equal(t, d.TimeSeries[0].LabelValues[2].Value, "metrics") - assert.Equal(t, d.TimeSeries[0].LabelValues[3].Value, "200") - }) - } -} diff --git a/exporter/sumologicexporter/metadata.yaml b/exporter/sumologicexporter/metadata.yaml index b9347ba9334e..4bf0044d1791 100644 --- a/exporter/sumologicexporter/metadata.yaml +++ b/exporter/sumologicexporter/metadata.yaml @@ -12,8 +12,34 @@ status: # TODO: Update the exporter to pass the tests tests: skip_lifecycle: true - goleak: - ignore: - top: - # See https://github.com/census-instrumentation/opencensus-go/issues/1191 for more information. - - "go.opencensus.io/stats/view.(*worker).start" + +telemetry: + metrics: + exporter_requests_sent: + enabled: true + description: Number of requests + unit: "1" + sum: + value_type: int + monotonic: true + exporter_requests_duration: + enabled: true + description: Duration of HTTP requests (in milliseconds) + unit: ms + sum: + value_type: int + monotonic: true + exporter_requests_bytes: + enabled: true + description: Total size of requests (in bytes) + unit: By + sum: + value_type: int + monotonic: true + exporter_requests_records: + enabled: true + description: Total size of requests (in number of records) + unit: "{records}" + sum: + value_type: int + monotonic: true diff --git a/exporter/sumologicexporter/sender.go b/exporter/sumologicexporter/sender.go index 65dc4b2f91a8..2ab24946ff29 100644 --- a/exporter/sumologicexporter/sender.go +++ b/exporter/sumologicexporter/sender.go @@ -21,9 +21,11 @@ import ( "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/observability" + "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/metadata" ) var ( @@ -122,6 +124,7 @@ type sender struct { stickySessionCookieFunc func() string setStickySessionCookieFunc func(string) id component.ID + telemetryBuilder *metadata.TelemetryBuilder } const ( @@ -153,6 +156,7 @@ func newSender( stickySessionCookieFunc func() string, setStickySessionCookieFunc func(string), id component.ID, + telemetryBuilder *metadata.TelemetryBuilder, ) *sender { return &sender{ logger: logger, @@ -165,6 +169,7 @@ func newSender( stickySessionCookieFunc: stickySessionCookieFunc, setStickySessionCookieFunc: setStickySessionCookieFunc, id: id, + telemetryBuilder: telemetryBuilder, } } @@ -707,21 +712,16 @@ func (s *sender) recordMetrics(duration time.Duration, count int64, req *http.Re id := s.id.String() - if err := observability.RecordRequestsDuration(duration, statusCode, req.URL.String(), string(pipeline), id); err != nil { - s.logger.Debug("error for recording metric for request duration", zap.Error(err)) - } - - if err := observability.RecordRequestsBytes(req.ContentLength, statusCode, req.URL.String(), string(pipeline), id); err != nil { - s.logger.Debug("error for recording metric for sent bytes", zap.Error(err)) - } - - if err := observability.RecordRequestsRecords(count, statusCode, req.URL.String(), string(pipeline), id); err != nil { - s.logger.Debug("error for recording metric for sent records", zap.Error(err)) - } - - if err := observability.RecordRequestsSent(statusCode, req.URL.String(), string(pipeline), id); err != nil { - s.logger.Debug("error for recording metric for sent request", zap.Error(err)) - } + attrs := attribute.NewSet( + attribute.String("status_code", fmt.Sprint(statusCode)), + attribute.String("endpoint", req.URL.String()), + attribute.String("pipeline", string(pipeline)), + attribute.String("exporter", id), + ) + s.telemetryBuilder.ExporterRequestsDuration.Add(context.Background(), duration.Milliseconds(), metric.WithAttributeSet(attrs)) + s.telemetryBuilder.ExporterRequestsBytes.Add(context.Background(), req.ContentLength, metric.WithAttributeSet(attrs)) + s.telemetryBuilder.ExporterRequestsRecords.Add(context.Background(), count, metric.WithAttributeSet(attrs)) + s.telemetryBuilder.ExporterRequestsSent.Add(context.Background(), 1, metric.WithAttributeSet(attrs)) } func (s *sender) addStickySessionCookie(req *http.Request) { diff --git a/exporter/sumologicexporter/sender_test.go b/exporter/sumologicexporter/sender_test.go index 355560dd1692..66ad75ef2561 100644 --- a/exporter/sumologicexporter/sender_test.go +++ b/exporter/sumologicexporter/sender_test.go @@ -30,6 +30,8 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" "go.uber.org/zap" "go.uber.org/zap/zapcore" + + "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter/internal/metadata" ) type senderTest struct { @@ -91,6 +93,9 @@ func prepareSenderTest(t *testing.T, compression configcompression.Type, cb []fu logger, err := zap.NewDevelopment() require.NoError(t, err) + telemetryBuilder, err := metadata.NewTelemetryBuilder(componenttest.NewNopTelemetrySettings()) + require.NoError(t, err) + return &senderTest{ reqCounter: &reqCounter, srv: testServer, @@ -105,6 +110,7 @@ func prepareSenderTest(t *testing.T, compression configcompression.Type, cb []fu func() string { return "" }, func(string) {}, component.ID{}, + telemetryBuilder, ), } }