diff --git a/.chloggen/config.yaml b/.chloggen/config.yaml index c61856db9f130..9d9917026be1c 100644 --- a/.chloggen/config.yaml +++ b/.chloggen/config.yaml @@ -39,7 +39,6 @@ components: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.chloggen/remove_carbon_exporter.yaml b/.chloggen/remove_carbon_exporter.yaml new file mode 100644 index 0000000000000..0579cf032c67a --- /dev/null +++ b/.chloggen/remove_carbon_exporter.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog) +component: cmd/otelcontribcol + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Removing unmaintained component `exporter/carbon` + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [38913] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.codecov.yml b/.codecov.yml index 2cc218eb9a59a..4256124ea8563 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -25,6 +25,7 @@ ignore: # Use component management to get coverage for each component. # See https://docs.codecov.com/docs/components # This list is autogenerated by codecovgen. +# Run `make gencodecov` to update # Start autogenerated components list component_management: individual_components: @@ -144,10 +145,6 @@ component_management: name: exporter_bmchelix paths: - exporter/bmchelixexporter/** - - component_id: exporter_carbon - name: exporter_carbon - paths: - - exporter/carbonexporter/** - component_id: exporter_cassandra name: exporter_cassandra paths: diff --git a/.github/ALLOWLIST b/.github/ALLOWLIST index 738871638c944..65cd0761183d7 100644 --- a/.github/ALLOWLIST +++ b/.github/ALLOWLIST @@ -29,7 +29,6 @@ internal/common # Start unmaintained components list -exporter/carbonexporter receiver/bigipreceiver receiver/carbonreceiver diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0048b5ee14481..72a742b256843 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -383,7 +383,6 @@ reports/distributions/otlp.yaml @open-telemetry/collector-contrib-approvers # Start unmaintained components list -exporter/carbonexporter/ @open-telemetry/collector-contrib-approvers receiver/bigipreceiver/ @open-telemetry/collector-contrib-approvers receiver/carbonreceiver/ @open-telemetry/collector-contrib-approvers diff --git a/.github/ISSUE_TEMPLATE/beta_stability.yaml b/.github/ISSUE_TEMPLATE/beta_stability.yaml index 8458b69265882..584163ba93d48 100644 --- a/.github/ISSUE_TEMPLATE/beta_stability.yaml +++ b/.github/ISSUE_TEMPLATE/beta_stability.yaml @@ -50,7 +50,6 @@ body: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 30f148339ccfd..bff9cad407e52 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -53,7 +53,6 @@ body: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 014a8bc26adbc..b7995ce536b62 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -47,7 +47,6 @@ body: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index ac1ad5b671d2f..79d3361356096 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -47,7 +47,6 @@ body: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.github/ISSUE_TEMPLATE/unmaintained.yaml b/.github/ISSUE_TEMPLATE/unmaintained.yaml index 19a13c82bbb2f..ef7cfbb1287d8 100644 --- a/.github/ISSUE_TEMPLATE/unmaintained.yaml +++ b/.github/ISSUE_TEMPLATE/unmaintained.yaml @@ -52,7 +52,6 @@ body: - exporter/azuredataexplorer - exporter/azuremonitor - exporter/bmchelix - - exporter/carbon - exporter/cassandra - exporter/clickhouse - exporter/coralogix diff --git a/.github/component_labels.txt b/.github/component_labels.txt index 0cc4e673b273c..8708e8cf88a6b 100644 --- a/.github/component_labels.txt +++ b/.github/component_labels.txt @@ -342,6 +342,5 @@ reports/distributions/core.yaml reports/distributions/core.yaml reports/distributions/contrib.yaml reports/distributions/contrib.yaml reports/distributions/k8s.yaml reports/distributions/k8s.yaml reports/distributions/otlp.yaml reports/distributions/otlp.yaml -exporter/carbonexporter exporter/carbon receiver/bigipreceiver receiver/bigip receiver/carbonreceiver receiver/carbon diff --git a/cmd/opampsupervisor/go.mod b/cmd/opampsupervisor/go.mod index 0fad555a3e2a3..03588f6edb4ea 100644 --- a/cmd/opampsupervisor/go.mod +++ b/cmd/opampsupervisor/go.mod @@ -283,8 +283,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experiment replace github.com/open-telemetry/opentelemetry-collector-contrib/testbed/mockdatasenders/mockdatadogagentexporter => ../../testbed/mockdatasenders/mockdatadogagentexporter -replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter => ../../exporter/carbonexporter - replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry => ../../pkg/resourcetotelemetry replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver => ../../receiver/zipkinreceiver diff --git a/cmd/otelcontribcol/builder-config.yaml b/cmd/otelcontribcol/builder-config.yaml index 7fadd3d1a5b13..7b68929342d47 100644 --- a/cmd/otelcontribcol/builder-config.yaml +++ b/cmd/otelcontribcol/builder-config.yaml @@ -74,7 +74,6 @@ exporters: - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/azureblobexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/azuremonitorexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/bmchelixexporter v0.140.1 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/clickhouseexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/cassandraexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/coralogixexporter v0.140.1 diff --git a/cmd/oteltestbedcol/builder-config.yaml b/cmd/oteltestbedcol/builder-config.yaml index 5c57193572e98..49cf0d2a14981 100644 --- a/cmd/oteltestbedcol/builder-config.yaml +++ b/cmd/oteltestbedcol/builder-config.yaml @@ -19,7 +19,6 @@ exporters: - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.140.1-0.20251120204106-2e9c82787618 - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.140.1-0.20251120204106-2e9c82787618 - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.1-0.20251120204106-2e9c82787618 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opensearchexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/otelarrowexporter v0.140.1 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter v0.140.1 diff --git a/exporter/carbonexporter/Makefile b/exporter/carbonexporter/Makefile deleted file mode 100644 index ded7a36092dc3..0000000000000 --- a/exporter/carbonexporter/Makefile +++ /dev/null @@ -1 +0,0 @@ -include ../../Makefile.Common diff --git a/exporter/carbonexporter/README.md b/exporter/carbonexporter/README.md deleted file mode 100644 index ffbfe951fb279..0000000000000 --- a/exporter/carbonexporter/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Carbon Exporter - - -| Status | | -| ------------- |-----------| -| Stability | [unmaintained]: metrics | -| Distributions | [contrib] | -| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fcarbon%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Aexporter%2Fcarbon) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fcarbon%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Aexporter%2Fcarbon) | -| Code coverage | [![codecov](https://codecov.io/github/open-telemetry/opentelemetry-collector-contrib/graph/main/badge.svg?component=exporter_carbon)](https://app.codecov.io/gh/open-telemetry/opentelemetry-collector-contrib/tree/main/?components%5B0%5D=exporter_carbon&displayType=list) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | \| Seeking more code owners! | -| Emeritus | [@aboguszewski-sumo](https://www.github.com/aboguszewski-sumo) | - -[unmaintained]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#unmaintained -[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib - - -The [Carbon](https://github.com/graphite-project/carbon) exporter supports -Carbon's [plaintext -protocol](https://graphite.readthedocs.io/en/stable/feeding-carbon.html#the-plaintext-protocol). - -## Configuration - -The following settings are required: - -- `endpoint` (default = `localhost:2003`): Address and port that the - exporter should send data to. - -Example: - -```yaml -exporters: - carbon: - # by default it will export to localhost:2003 using tcp - carbon/allsettings: - # use endpoint to specify alternative destinations for the exporter, - # the default is localhost:2003 - endpoint: localhost:8080 - # timeout is the maximum duration allowed to connecting and sending the - # data to the configured endpoint. - # The default is 5 seconds. - timeout: 10s -``` - -The full list of settings exposed for this receiver are documented in [config.go](./config.go) -with detailed sample configurations in [testdata/config.yaml](./testdata/config.yaml). - -## Advanced Configuration - -Several helper files are leveraged to provide additional capabilities automatically: - -- [net settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confignet/README.md) -- [Queuing, retry and timeout settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) diff --git a/exporter/carbonexporter/config.go b/exporter/carbonexporter/config.go deleted file mode 100644 index 9123d7cf0d1fb..0000000000000 --- a/exporter/carbonexporter/config.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" - -import ( - "errors" - "fmt" - "net" - - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/config/configretry" - "go.opentelemetry.io/collector/exporter/exporterhelper" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry" -) - -// Config defines configuration for Carbon exporter. -type Config struct { - // Specifies the connection endpoint config. The default value is "localhost:2003". - confignet.TCPAddrConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. - // MaxIdleConns is used to set a limit to the maximum idle TCP connections the client can keep open. Default value is 100. - // If `sending_queue` is enabled, it is recommended to use same value as `sending_queue::num_consumers`. - MaxIdleConns int `mapstructure:"max_idle_conns"` - - // Timeout is the maximum duration allowed to connecting and sending the - // data to the Carbon/Graphite backend. The default value is 5s. - TimeoutSettings exporterhelper.TimeoutConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. - QueueConfig exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"` - RetryConfig configretry.BackOffConfig `mapstructure:"retry_on_failure"` - - // ResourceToTelemetrySettings defines configuration for converting resource attributes to metric labels. - ResourceToTelemetryConfig resourcetotelemetry.Settings `mapstructure:"resource_to_telemetry_conversion"` -} - -func (cfg *Config) Validate() error { - // Resolve TCP address just to ensure that it is a valid one. It is better - // to fail here than at when the exporter is started. - if _, err := net.ResolveTCPAddr("tcp", cfg.Endpoint); err != nil { - return fmt.Errorf("exporter has an invalid TCP endpoint: %w", err) - } - - // Negative timeouts are not acceptable, since all sends will fail. - if cfg.TimeoutSettings.Timeout < 0 { - return errors.New("'timeout' must be non-negative") - } - - if cfg.MaxIdleConns < 0 { - return errors.New("'max_idle_conns' must be non-negative") - } - - return nil -} diff --git a/exporter/carbonexporter/config_test.go b/exporter/carbonexporter/config_test.go deleted file mode 100644 index aeef0b2ab031c..0000000000000 --- a/exporter/carbonexporter/config_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter - -import ( - "path/filepath" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/config/configretry" - "go.opentelemetry.io/collector/confmap/confmaptest" - "go.opentelemetry.io/collector/confmap/xconfmap" - "go.opentelemetry.io/collector/exporter/exporterhelper" - - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter/internal/metadata" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry" -) - -func TestLoadConfig(t *testing.T) { - t.Parallel() - - cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) - require.NoError(t, err) - - tests := []struct { - id component.ID - expected component.Config - errorMessage string - }{ - { - id: component.NewIDWithName(metadata.Type, ""), - expected: createDefaultConfig(), - }, - { - id: component.NewIDWithName(metadata.Type, "allsettings"), - expected: &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{ - Endpoint: "localhost:8080", - }, - MaxIdleConns: 15, - TimeoutSettings: exporterhelper.TimeoutConfig{ - Timeout: 10 * time.Second, - }, - RetryConfig: configretry.BackOffConfig{ - Enabled: true, - InitialInterval: 10 * time.Second, - RandomizationFactor: 0.7, - Multiplier: 3.14, - MaxInterval: 1 * time.Minute, - MaxElapsedTime: 10 * time.Minute, - }, - QueueConfig: func() exporterhelper.QueueBatchConfig { - queue := exporterhelper.NewDefaultQueueConfig() - queue.Enabled = true - queue.NumConsumers = 2 - queue.QueueSize = 10 - return queue - }(), - ResourceToTelemetryConfig: resourcetotelemetry.Settings{ - Enabled: true, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.id.String(), func(t *testing.T) { - factory := NewFactory() - cfg := factory.CreateDefaultConfig() - - sub, err := cm.Sub(tt.id.String()) - require.NoError(t, err) - require.NoError(t, sub.Unmarshal(cfg)) - - assert.NoError(t, xconfmap.Validate(cfg)) - assert.Equal(t, tt.expected, cfg) - }) - } -} - -func TestValidateConfig(t *testing.T) { - tests := []struct { - name string - config *Config - wantErr bool - }{ - { - name: "default_config", - config: createDefaultConfig().(*Config), - }, - { - name: "invalid_tcp_addr", - config: &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{ - Endpoint: "http://localhost:2003", - }, - }, - wantErr: true, - }, - { - name: "invalid_timeout", - config: &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{Endpoint: defaultEndpoint}, - TimeoutSettings: exporterhelper.TimeoutConfig{ - Timeout: -5 * time.Second, - }, - }, - wantErr: true, - }, - { - name: "invalid_max_idle_conns", - config: &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{Endpoint: defaultEndpoint}, - MaxIdleConns: -1, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantErr { - assert.Error(t, tt.config.Validate()) - } else { - assert.NoError(t, tt.config.Validate()) - } - }) - } -} diff --git a/exporter/carbonexporter/doc.go b/exporter/carbonexporter/doc.go deleted file mode 100644 index db743358016ff..0000000000000 --- a/exporter/carbonexporter/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mdatagen metadata.yaml - -// Package carbonexporter implements an exporter that sends data to Carbon. -package carbonexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" diff --git a/exporter/carbonexporter/exporter.go b/exporter/carbonexporter/exporter.go deleted file mode 100644 index 1680c2c8451c0..0000000000000 --- a/exporter/carbonexporter/exporter.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" - -import ( - "context" - "net" - "sync" - "time" - - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/exporter" - "go.opentelemetry.io/collector/exporter/exporterhelper" - "go.opentelemetry.io/collector/pdata/pmetric" - "go.uber.org/multierr" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry" -) - -// newCarbonExporter returns a new Carbon exporter. -func newCarbonExporter(ctx context.Context, cfg *Config, set exporter.Settings) (exporter.Metrics, error) { - sender := carbonSender{ - writeTimeout: cfg.TimeoutSettings.Timeout, - conns: newConnPool(cfg.TCPAddrConfig, cfg.TimeoutSettings.Timeout, cfg.MaxIdleConns), - } - - exp, err := exporterhelper.NewMetrics( - ctx, - set, - cfg, - sender.pushMetricsData, - // We don't use exporterhelper.WithTimeout because the TCP connection does not accept writing with context. - exporterhelper.WithQueue(cfg.QueueConfig), - exporterhelper.WithRetry(cfg.RetryConfig), - exporterhelper.WithShutdown(sender.Shutdown)) - if err != nil { - return nil, err - } - - return resourcetotelemetry.WrapMetricsExporter(cfg.ResourceToTelemetryConfig, exp), nil -} - -// carbonSender is the struct tying the translation function and the TCP -// connections into an implementations of exporterhelper.PushMetricsData so -// the exporter can leverage the helper and get consistent observability. -type carbonSender struct { - writeTimeout time.Duration - conns connPool -} - -func (cs *carbonSender) pushMetricsData(_ context.Context, md pmetric.Metrics) error { - lines := metricDataToPlaintext(md) - - // There is no way to do a call equivalent to recvfrom with an empty buffer - // to check if the connection was terminated (if the size of the buffer is - // 0 the Read call doesn't call lower level). So due to buffer sizes it is - // possible that a write will succeed on a connection that was already - // closed by the server. - // - // At least on Darwin it is possible to work around this by configuring the - // buffer on each call, ie.: - // - // if err = conn.SetWriteBuffer(len(bytes)-1); err != nil { - // return 0, err - // } - // - // However, this causes a performance penalty of ~10% cpu and it is not - // present in various implementations of Carbon clients. Considering these - // facts this "workaround" is not being added at this moment. If it is - // needed in some scenarios the workaround should be validated on other - // platforms and offered as a configuration setting. - conn, err := cs.conns.get() - if err != nil { - return err - } - - if err = conn.SetWriteDeadline(time.Now().Add(cs.writeTimeout)); err != nil { - // Do not re-enqueue the connection since it failed to set a deadline. - return multierr.Append(err, conn.Close()) - } - - // If we did not write all bytes will get an error, so no need to check for that. - _, err = conn.Write([]byte(lines)) - if err != nil { - // Do not re-enqueue the connection since it failed to write. - return multierr.Append(err, conn.Close()) - } - - // Even if we close the connection because of the max idle connections, - cs.conns.put(conn) - return nil -} - -func (cs *carbonSender) Shutdown(context.Context) error { - return cs.conns.close() -} - -// connPool is a very simple implementation of a pool of net.Conn instances. -type connPool interface { - get() (net.Conn, error) - put(conn net.Conn) - close() error -} - -func newConnPool( - tcpConfig confignet.TCPAddrConfig, - timeout time.Duration, - maxIdleConns int, -) connPool { - if maxIdleConns == 0 { - return &nopConnPool{ - timeout: timeout, - tcpConfig: tcpConfig, - } - } - return &connPoolWithIdle{ - timeout: timeout, - tcpConfig: tcpConfig, - maxIdleConns: maxIdleConns, - } -} - -// nopConnPool is a very simple implementation that does not cache any net.Conn. -type nopConnPool struct { - timeout time.Duration - tcpConfig confignet.TCPAddrConfig -} - -func (cp *nopConnPool) get() (net.Conn, error) { - return createTCPConn(cp.tcpConfig, cp.timeout) -} - -func (*nopConnPool) put(conn net.Conn) { - _ = conn.Close() -} - -func (*nopConnPool) close() error { - return nil -} - -// connPool is a very simple implementation of a pool of net.Conn instances. -// -// It keeps at most maxIdleConns net.Conn and always "popping" the most -// recently returned to the pool. There is no accounting to terminating old -// unused connections. -type connPoolWithIdle struct { - timeout time.Duration - maxIdleConns int - mtx sync.Mutex - conns []net.Conn - tcpConfig confignet.TCPAddrConfig -} - -func (cp *connPoolWithIdle) get() (net.Conn, error) { - if conn := cp.getFromCache(); conn != nil { - return conn, nil - } - - return createTCPConn(cp.tcpConfig, cp.timeout) -} - -func (cp *connPoolWithIdle) put(conn net.Conn) { - cp.mtx.Lock() - defer cp.mtx.Unlock() - // Do not cache if above limit. - if len(cp.conns) > cp.maxIdleConns { - _ = conn.Close() - return - } - cp.conns = append(cp.conns, conn) -} - -func (cp *connPoolWithIdle) getFromCache() net.Conn { - cp.mtx.Lock() - defer cp.mtx.Unlock() - lastIdx := len(cp.conns) - 1 - if lastIdx < 0 { - return nil - } - conn := cp.conns[lastIdx] - cp.conns = cp.conns[0:lastIdx] - return conn -} - -func (cp *connPoolWithIdle) close() error { - cp.mtx.Lock() - defer cp.mtx.Unlock() - - var errs error - for _, conn := range cp.conns { - errs = multierr.Append(errs, conn.Close()) - } - cp.conns = nil - return errs -} - -func createTCPConn(tcpConfig confignet.TCPAddrConfig, timeout time.Duration) (net.Conn, error) { - c, err := net.DialTimeout("tcp", tcpConfig.Endpoint, timeout) - if err != nil { - return nil, err - } - return c, err -} diff --git a/exporter/carbonexporter/exporter_test.go b/exporter/carbonexporter/exporter_test.go deleted file mode 100644 index 4797c15576641..0000000000000 --- a/exporter/carbonexporter/exporter_test.go +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter - -import ( - "bufio" - "errors" - "io" - "net" - "runtime" - "strconv" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/exporter/exporterhelper" - "go.opentelemetry.io/collector/exporter/exportertest" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/pmetric" - conventions "go.opentelemetry.io/otel/semconv/v1.27.0" - - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter/internal/metadata" - "github.com/open-telemetry/opentelemetry-collector-contrib/internal/common/testutil" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry" -) - -func TestNewWithDefaultConfig(t *testing.T) { - cfg := createDefaultConfig().(*Config) - got, err := newCarbonExporter(t.Context(), cfg, exportertest.NewNopSettings(metadata.Type)) - assert.NotNil(t, got) - assert.NoError(t, err) -} - -func TestConsumeMetricsNoServer(t *testing.T) { - exp, err := newCarbonExporter( - t.Context(), - &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{Endpoint: testutil.GetAvailableLocalAddress(t)}, - TimeoutSettings: exporterhelper.TimeoutConfig{Timeout: 5 * time.Second}, - }, - exportertest.NewNopSettings(metadata.Type)) - require.NoError(t, err) - require.NoError(t, exp.Start(t.Context(), componenttest.NewNopHost())) - require.Error(t, exp.ConsumeMetrics(t.Context(), generateSmallBatch())) - require.NoError(t, exp.Shutdown(t.Context())) -} - -func TestConsumeMetricsWithResourceToTelemetry(t *testing.T) { - addr := testutil.GetAvailableLocalAddress(t) - cs := newCarbonServer(t, addr, "test_0;key_0=value_0;key_1=value_1;key_2=value_2;service.name=carbon 0") - // Each metric point will generate one Carbon line, set up the wait - // for all of them. - cs.start(t, 1) - - exp, err := newCarbonExporter( - t.Context(), - &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{Endpoint: addr}, - TimeoutSettings: exporterhelper.TimeoutConfig{Timeout: 5 * time.Second}, - ResourceToTelemetryConfig: resourcetotelemetry.Settings{Enabled: true}, - }, - exportertest.NewNopSettings(metadata.Type)) - require.NoError(t, err) - require.NoError(t, exp.Start(t.Context(), componenttest.NewNopHost())) - require.NoError(t, exp.ConsumeMetrics(t.Context(), generateSmallBatch())) - assert.NoError(t, exp.Shutdown(t.Context())) - cs.shutdownAndVerify(t) -} - -func TestConsumeMetrics(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping test on windows, see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/10147") - } - - tests := []struct { - name string - md pmetric.Metrics - numProducers int - writesPerProducer int - }{ - { - name: "small_batch", - md: generateSmallBatch(), - numProducers: 1, - writesPerProducer: 5, - }, - { - name: "large_batch", - md: generateLargeBatch(), - numProducers: 1, - writesPerProducer: 5, - }, - { - name: "concurrent_small_batch", - md: generateSmallBatch(), - numProducers: 5, - writesPerProducer: 5, - }, - { - name: "concurrent_large_batch", - md: generateLargeBatch(), - numProducers: 5, - writesPerProducer: 5, - }, - { - name: "high_concurrency", - md: generateLargeBatch(), - numProducers: 10, - writesPerProducer: 200, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - addr := testutil.GetAvailableLocalAddress(t) - cs := newCarbonServer(t, addr, "") - // Each metric point will generate one Carbon line, set up the wait - // for all of them. - cs.start(t, tt.numProducers*tt.writesPerProducer*tt.md.DataPointCount()) - - exp, err := newCarbonExporter( - t.Context(), - &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{Endpoint: addr}, - MaxIdleConns: tt.numProducers, - TimeoutSettings: exporterhelper.TimeoutConfig{Timeout: 5 * time.Second}, - }, - exportertest.NewNopSettings(metadata.Type)) - require.NoError(t, err) - require.NoError(t, exp.Start(t.Context(), componenttest.NewNopHost())) - - startCh := make(chan struct{}) - var writersWG sync.WaitGroup - writersWG.Add(tt.numProducers) - for i := 0; i < tt.numProducers; i++ { - go func() { - defer writersWG.Done() - <-startCh - for j := 0; j < tt.writesPerProducer; j++ { - assert.NoError(t, exp.ConsumeMetrics(t.Context(), tt.md)) - } - }() - } - - // Release all senders. - close(startCh) - // Wait for all senders to finish. - writersWG.Wait() - - assert.NoError(t, exp.Shutdown(t.Context())) - cs.shutdownAndVerify(t) - }) - } -} - -func TestNewConnectionPool(t *testing.T) { - assert.IsType(t, &nopConnPool{}, newConnPool(confignet.TCPAddrConfig{Endpoint: defaultEndpoint}, 10*time.Second, 0)) - assert.IsType(t, &connPoolWithIdle{}, newConnPool(confignet.TCPAddrConfig{Endpoint: defaultEndpoint}, 10*time.Second, 10)) -} - -func TestNopConnPool(t *testing.T) { - addr := testutil.GetAvailableLocalAddress(t) - cs := newCarbonServer(t, addr, "") - // Each metric point will generate one Carbon line, set up the wait - // for all of them. - cs.start(t, 2) - - cp := &nopConnPool{ - timeout: 1 * time.Second, - tcpConfig: confignet.TCPAddrConfig{Endpoint: addr}, - } - - conn, err := cp.get() - require.NoError(t, err) - _, err = conn.Write([]byte(metricDataToPlaintext(generateSmallBatch()))) - assert.NoError(t, err) - cp.put(conn) - - // Get a new connection and confirm is not the same. - conn2, err2 := cp.get() - require.NoError(t, err2) - assert.NotSame(t, conn, conn2) - _, err = conn2.Write([]byte(metricDataToPlaintext(generateSmallBatch()))) - assert.NoError(t, err) - cp.put(conn2) - - require.NoError(t, cp.close()) - cs.shutdownAndVerify(t) -} - -func TestConnPoolWithIdle(t *testing.T) { - addr := testutil.GetAvailableLocalAddress(t) - cs := newCarbonServer(t, addr, "") - // Each metric point will generate one Carbon line, set up the wait - // for all of them. - cs.start(t, 2) - - cp := &connPoolWithIdle{ - timeout: 1 * time.Second, - tcpConfig: confignet.TCPAddrConfig{Endpoint: addr}, - maxIdleConns: 4, - } - - conn, err := cp.get() - require.NoError(t, err) - _, err = conn.Write([]byte(metricDataToPlaintext(generateSmallBatch()))) - assert.NoError(t, err) - cp.put(conn) - - // Get a new connection and confirm it is the same as the first one. - conn2, err2 := cp.get() - require.NoError(t, err2) - assert.Same(t, conn, conn2) - _, err = conn2.Write([]byte(metricDataToPlaintext(generateSmallBatch()))) - assert.NoError(t, err) - cp.put(conn2) - - require.NoError(t, cp.close()) - cs.shutdownAndVerify(t) -} - -func TestConnPoolWithIdleMaxConnections(t *testing.T) { - addr := testutil.GetAvailableLocalAddress(t) - cs := newCarbonServer(t, addr, "") - const maxIdleConns = 4 - // Each metric point will generate one Carbon line, set up the wait - // for all of them. - cs.start(t, maxIdleConns+1) - - cp := &connPoolWithIdle{ - timeout: 1 * time.Second, - tcpConfig: confignet.TCPAddrConfig{Endpoint: addr}, - maxIdleConns: maxIdleConns, - } - - // Create connections and - var conns []net.Conn - for i := range maxIdleConns { - conn, err := cp.get() - require.NoError(t, err) - conns = append(conns, conn) - if i != 0 { - assert.NotSame(t, conn, conns[i-1]) - } - } - for _, conn := range conns { - cp.put(conn) - } - - for i := range maxIdleConns + 1 { - conn, err := cp.get() - require.NoError(t, err) - _, err = conn.Write([]byte(metricDataToPlaintext(generateSmallBatch()))) - assert.NoError(t, err) - if i != maxIdleConns { - assert.Same(t, conn, conns[maxIdleConns-i-1]) - } else { - // this should be a new connection - for _, cachedConn := range conns { - assert.NotSame(t, conn, cachedConn) - } - cp.put(conn) - } - } - for _, conn := range conns { - cp.put(conn) - } - require.NoError(t, cp.close()) - cs.shutdownAndVerify(t) -} - -func generateSmallBatch() pmetric.Metrics { - return generateMetricsBatch(1) -} - -func generateLargeBatch() pmetric.Metrics { - return generateMetricsBatch(1024) -} - -func generateMetricsBatch(size int) pmetric.Metrics { - ts := time.Now() - metrics := pmetric.NewMetrics() - rm := metrics.ResourceMetrics().AppendEmpty() - rm.Resource().Attributes().PutStr(string(conventions.ServiceNameKey), "carbon") - ms := rm.ScopeMetrics().AppendEmpty().Metrics() - - for i := range size { - m := ms.AppendEmpty() - m.SetName("test_" + strconv.Itoa(i)) - dp := m.SetEmptyGauge().DataPoints().AppendEmpty() - dp.Attributes().PutStr("key_0", "value_0") - dp.Attributes().PutStr("key_1", "value_1") - dp.Attributes().PutStr("key_2", "value_2") - dp.SetTimestamp(pcommon.NewTimestampFromTime(ts)) - dp.SetIntValue(int64(i)) - } - - return metrics -} - -type carbonServer struct { - ln *net.TCPListener - doneServer *atomic.Bool - wg sync.WaitGroup - expectedContainsValue string -} - -func newCarbonServer(t *testing.T, addr, expectedContainsValue string) *carbonServer { - laddr, err := net.ResolveTCPAddr("tcp", addr) - require.NoError(t, err) - ln, err := net.ListenTCP("tcp", laddr) - require.NoError(t, err) - return &carbonServer{ - ln: ln, - doneServer: &atomic.Bool{}, - expectedContainsValue: expectedContainsValue, - } -} - -func (cs *carbonServer) start(t *testing.T, numExpectedReq int) { - cs.wg.Add(numExpectedReq) - go func() { - for { - conn, err := cs.ln.Accept() - if cs.doneServer.Load() { - // Close is expected to cause error. - return - } - assert.NoError(t, err) - go func(conn net.Conn) { - defer func() { - assert.NoError(t, conn.Close()) - }() - - reader := bufio.NewReader(conn) - for { - buf, err := reader.ReadBytes(byte('\n')) - if errors.Is(err, io.EOF) { - return - } - assert.NoError(t, err) - - if cs.expectedContainsValue != "" { - assert.Contains(t, string(buf), cs.expectedContainsValue) - } - - cs.wg.Done() - } - }(conn) - } - }() - <-time.After(100 * time.Millisecond) -} - -func (cs *carbonServer) shutdownAndVerify(t *testing.T) { - cs.wg.Wait() - cs.doneServer.Store(true) - require.NoError(t, cs.ln.Close()) -} diff --git a/exporter/carbonexporter/factory.go b/exporter/carbonexporter/factory.go deleted file mode 100644 index 5622d86274829..0000000000000 --- a/exporter/carbonexporter/factory.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" - -import ( - "context" - - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/config/configretry" - "go.opentelemetry.io/collector/exporter" - "go.opentelemetry.io/collector/exporter/exporterhelper" - - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter/internal/metadata" -) - -// Defaults for not specified configuration settings. -const ( - defaultEndpoint = "localhost:2003" -) - -// NewFactory creates a factory for Carbon exporter. -func NewFactory() exporter.Factory { - return exporter.NewFactory( - metadata.Type, - createDefaultConfig, - exporter.WithMetrics(createMetricsExporter, metadata.MetricsStability)) -} - -func createDefaultConfig() component.Config { - return &Config{ - TCPAddrConfig: confignet.TCPAddrConfig{ - Endpoint: defaultEndpoint, - }, - MaxIdleConns: 100, - TimeoutSettings: exporterhelper.NewDefaultTimeoutConfig(), - QueueConfig: exporterhelper.NewDefaultQueueConfig(), - RetryConfig: configretry.NewDefaultBackOffConfig(), - } -} - -func createMetricsExporter( - ctx context.Context, - params exporter.Settings, - config component.Config, -) (exporter.Metrics, error) { - exp, err := newCarbonExporter(ctx, config.(*Config), params) - if err != nil { - return nil, err - } - - return exp, nil -} diff --git a/exporter/carbonexporter/factory_test.go b/exporter/carbonexporter/factory_test.go deleted file mode 100644 index 20ffc1ff45de3..0000000000000 --- a/exporter/carbonexporter/factory_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" - "go.opentelemetry.io/collector/exporter/exportertest" - - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter/internal/metadata" -) - -func TestCreateDefaultConfig(t *testing.T) { - cfg := createDefaultConfig() - assert.NotNil(t, cfg, "failed to create default config") - assert.NoError(t, componenttest.CheckConfigStruct(cfg)) -} - -func TestCreateMetrics(t *testing.T) { - cfg := createDefaultConfig() - _, err := createMetricsExporter(t.Context(), exportertest.NewNopSettings(metadata.Type), cfg) - assert.NoError(t, err) -} - -func TestCreateInstanceViaFactory(t *testing.T) { - factory := NewFactory() - - cfg := factory.CreateDefaultConfig() - exp, err := factory.CreateMetrics( - t.Context(), - exportertest.NewNopSettings(metadata.Type), - cfg) - assert.NoError(t, err) - assert.NotNil(t, exp) - - // Set values that don't have a valid default. - // expCfg := cfg.(*Config) - - exp, err = factory.CreateMetrics( - t.Context(), - exportertest.NewNopSettings(metadata.Type), - cfg) - assert.NoError(t, err) - require.NotNil(t, exp) - - assert.NoError(t, exp.Shutdown(t.Context())) -} diff --git a/exporter/carbonexporter/generated_component_test.go b/exporter/carbonexporter/generated_component_test.go deleted file mode 100644 index 6c08c79ce3580..0000000000000 --- a/exporter/carbonexporter/generated_component_test.go +++ /dev/null @@ -1,152 +0,0 @@ -// Code generated by mdatagen. DO NOT EDIT. - -package carbonexporter - -import ( - "context" - "testing" - "time" - - "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/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" -) - -var typ = component.MustNewType("carbon") - -func TestComponentFactoryType(t *testing.T) { - require.Equal(t, typ, NewFactory().Type()) -} - -func TestComponentConfigStruct(t *testing.T) { - require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig())) -} - -func TestComponentLifecycle(t *testing.T) { - factory := NewFactory() - - tests := []struct { - createFn func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error) - name string - }{ - - { - name: "metrics", - createFn: func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error) { - return factory.CreateMetrics(ctx, set, cfg) - }, - }, - } - - 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 _, tt := range tests { - t.Run(tt.name+"-shutdown", func(t *testing.T) { - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg) - require.NoError(t, err) - err = c.Shutdown(context.Background()) - require.NoError(t, err) - }) - t.Run(tt.name+"-lifecycle", func(t *testing.T) { - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg) - require.NoError(t, err) - host := newMdatagenNopHost() - err = c.Start(context.Background(), host) - require.NoError(t, err) - require.NotPanics(t, func() { - switch tt.name { - case "logs": - e, ok := c.(exporter.Logs) - require.True(t, ok) - logs := generateLifecycleTestLogs() - if !e.Capabilities().MutatesData { - logs.MarkReadOnly() - } - err = e.ConsumeLogs(context.Background(), logs) - case "metrics": - e, ok := c.(exporter.Metrics) - require.True(t, ok) - metrics := generateLifecycleTestMetrics() - if !e.Capabilities().MutatesData { - metrics.MarkReadOnly() - } - err = e.ConsumeMetrics(context.Background(), metrics) - case "traces": - e, ok := c.(exporter.Traces) - require.True(t, ok) - traces := generateLifecycleTestTraces() - if !e.Capabilities().MutatesData { - traces.MarkReadOnly() - } - err = e.ConsumeTraces(context.Background(), traces) - } - }) - - err = c.Shutdown(context.Background()) - require.NoError(t, err) - }) - } -} - -func generateLifecycleTestLogs() plog.Logs { - logs := plog.NewLogs() - rl := logs.ResourceLogs().AppendEmpty() - rl.Resource().Attributes().PutStr("resource", "R1") - l := rl.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty() - l.Body().SetStr("test log message") - l.SetTimestamp(pcommon.NewTimestampFromTime(time.Now())) - return logs -} - -func generateLifecycleTestMetrics() pmetric.Metrics { - metrics := pmetric.NewMetrics() - rm := metrics.ResourceMetrics().AppendEmpty() - rm.Resource().Attributes().PutStr("resource", "R1") - m := rm.ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() - m.SetName("test_metric") - dp := m.SetEmptyGauge().DataPoints().AppendEmpty() - dp.Attributes().PutStr("test_attr", "value_1") - dp.SetIntValue(123) - dp.SetTimestamp(pcommon.NewTimestampFromTime(time.Now())) - return metrics -} - -func generateLifecycleTestTraces() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - rs.Resource().Attributes().PutStr("resource", "R1") - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("test_attr", "value_1") - span.SetName("test_span") - span.SetStartTimestamp(pcommon.NewTimestampFromTime(time.Now().Add(-1 * time.Second))) - span.SetEndTimestamp(pcommon.NewTimestampFromTime(time.Now())) - return traces -} - -var _ component.Host = (*mdatagenNopHost)(nil) - -type mdatagenNopHost struct{} - -func newMdatagenNopHost() component.Host { - return &mdatagenNopHost{} -} - -func (mnh *mdatagenNopHost) GetExtensions() map[component.ID]component.Component { - return nil -} - -func (mnh *mdatagenNopHost) GetFactory(_ component.Kind, _ component.Type) component.Factory { - return nil -} diff --git a/exporter/carbonexporter/generated_package_test.go b/exporter/carbonexporter/generated_package_test.go deleted file mode 100644 index ad22b23641036..0000000000000 --- a/exporter/carbonexporter/generated_package_test.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by mdatagen. DO NOT EDIT. - -package carbonexporter - -import ( - "testing" - - "go.uber.org/goleak" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m) -} diff --git a/exporter/carbonexporter/go.mod b/exporter/carbonexporter/go.mod deleted file mode 100644 index 69788eedf0150..0000000000000 --- a/exporter/carbonexporter/go.mod +++ /dev/null @@ -1,88 +0,0 @@ -module github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter - -go 1.24.0 - -require ( - github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.140.1 - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.140.1 - github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/component/componenttest v0.140.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/config/confignet v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/config/configretry v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/confmap v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/exporter v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/exporter/exportertest v0.140.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/collector/pdata v1.46.1-0.20251120204106-2e9c82787618 - go.opentelemetry.io/otel v1.38.0 - go.uber.org/goleak v1.3.0 - go.uber.org/multierr v1.11.0 -) - -require ( - github.com/cenkalti/backoff/v5 v5.0.3 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v1.4.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/gobwas/glob v0.2.3 // 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/knadh/koanf/maps v0.1.2 // indirect - github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // 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.3-0.20250322232337-35a7c28c31ee // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/client v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/consumer v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/extension v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/extension/xextension v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/featuregate v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/pdata/xpdata v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/pipeline v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/receiver v1.46.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.1-0.20251120204106-2e9c82787618 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - go.uber.org/zap v1.27.1 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.37.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/common => ../../internal/common - -retract ( - v0.76.2 - v0.76.1 - v0.65.0 -) - -replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry => ../../pkg/resourcetotelemetry - -replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal - -replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil - -replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest - -replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden diff --git a/exporter/carbonexporter/go.sum b/exporter/carbonexporter/go.sum deleted file mode 100644 index 571b3288bc723..0000000000000 --- a/exporter/carbonexporter/go.sum +++ /dev/null @@ -1,152 +0,0 @@ -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= -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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/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.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= -github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= -github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= -github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= -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/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= -go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/collector/client v1.46.1-0.20251120204106-2e9c82787618 h1:xIU4szXwM+ausU1ZATfAGOiIAJLLDwnf6aSiL9X5LFs= -go.opentelemetry.io/collector/client v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:/Y2bm0RdD8LKIEQOX5YqqjglKNb8AYCdDuKb04/fURw= -go.opentelemetry.io/collector/component v1.46.1-0.20251120204106-2e9c82787618 h1:xIx6z5BadxNXT/1ZOeQNS8fcGkBBoS9gAPXlWOnfsJY= -go.opentelemetry.io/collector/component v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:Zp+JaUgGrPvt4JNzJU1MD7KcZhauab9W0pCykgGPSN0= -go.opentelemetry.io/collector/component/componenttest v0.140.1-0.20251120204106-2e9c82787618 h1:u5wbaLO4iOv6ym0sI2JmwKM0CidLm/wRo1wuKAdBI08= -go.opentelemetry.io/collector/component/componenttest v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:6u5eMJozhiF1p3sllc2p/07iqZMqkpHPvF/HZ0sRl9o= -go.opentelemetry.io/collector/config/confignet v1.46.1-0.20251120204106-2e9c82787618 h1:qByNo90PX0uSJhEDK36y4dVgtohhVxVNCKrRJwazHzk= -go.opentelemetry.io/collector/config/confignet v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:4jJWdoe1MmpqxMzxrIILcS5FK2JPocXYZGUvv5ZQVKE= -go.opentelemetry.io/collector/config/configoptional v1.46.1-0.20251120204106-2e9c82787618 h1:qCZBVjIIdgOodNnIPY4vjElWg52HLRTcBvWqNU5xHZw= -go.opentelemetry.io/collector/config/configoptional v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:XgGvHiFtro2MpPWbo4ExQ7CLnSBqzWAANfBIPv4QSVg= -go.opentelemetry.io/collector/config/configretry v1.46.1-0.20251120204106-2e9c82787618 h1:zM+7A+LEi5TZa1fu0xVLC+ir7/axuDqdYRkt+fiHgHk= -go.opentelemetry.io/collector/config/configretry v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:ZSTYqAJCq4qf+/4DGoIxCElDIl5yHt8XxEbcnpWBbMM= -go.opentelemetry.io/collector/confmap v1.46.1-0.20251120204106-2e9c82787618 h1:jlgrDds/sD1WZ7uLnvRrDk32OvJh/BP1dvbhA7kdJrg= -go.opentelemetry.io/collector/confmap v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:uqrwOuf+1PeZ9Zo/IDV9hJlvFy2eRKYUajkM1Lsmyto= -go.opentelemetry.io/collector/confmap/xconfmap v0.140.1-0.20251120204106-2e9c82787618 h1:FFT5OWG1bHYTCFUOoQozVsgN1723kBWZQOyNBgEsB4E= -go.opentelemetry.io/collector/confmap/xconfmap v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:KInqGVGClR7dDDJLkHsl3riO03et7TaBrGKVD5pD4i0= -go.opentelemetry.io/collector/consumer v1.46.1-0.20251120204106-2e9c82787618 h1:oVj1/83ioZC1nXbL6dubVg8Dvz9S+++T3CXur3a9NpU= -go.opentelemetry.io/collector/consumer v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:3hjV46vdz8zExuTKlxRge3VdeVUr0PJETqIMewKThNc= -go.opentelemetry.io/collector/consumer/consumererror v0.140.1-0.20251120204106-2e9c82787618 h1:ee9840Er+vNXKO+ULhG9VYOorESJDxfaerlEDvdlh8U= -go.opentelemetry.io/collector/consumer/consumererror v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:iBRUV6Pvm00HE5EI2+t2wNlP6MoGAAK9xMKLPeA+PZ4= -go.opentelemetry.io/collector/consumer/consumertest v0.140.1-0.20251120204106-2e9c82787618 h1:bondxHiwLGmSrJ3WiUaUwx5bvaUwP1b6/AvMUPqDoV0= -go.opentelemetry.io/collector/consumer/consumertest v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:LvDaKM5A7hUg7LWZBqk69sE0q5GrdM8BmLqX6kCP3WQ= -go.opentelemetry.io/collector/consumer/xconsumer v0.140.1-0.20251120204106-2e9c82787618 h1:F5We4BryZ1N3/pDdEqefIIZQzKPT7GaoOkTTGpfkd5w= -go.opentelemetry.io/collector/consumer/xconsumer v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:CtwSgAXVisCEJ+ElKeDa0yDo/Oie7l1vWAx1elFyWZc= -go.opentelemetry.io/collector/exporter v1.46.1-0.20251120204106-2e9c82787618 h1:fgbGpYDCRFHXe9NDI8YQY+Dif3GiPmQKWXkO/6gakos= -go.opentelemetry.io/collector/exporter v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:kpLf41bsppVa3IOCtavGG724DRK6AGT++PMnejp+FjA= -go.opentelemetry.io/collector/exporter/exporterhelper v0.140.1-0.20251120204106-2e9c82787618 h1:OjNN8y5sctrdoOs8R82zAMtKNWGMQm8eQbJmg3aP1UU= -go.opentelemetry.io/collector/exporter/exporterhelper v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:qmOnlpZ43k8y5xjeThMm5JmBYgwfO0Fyn7jys3azLxQ= -go.opentelemetry.io/collector/exporter/exportertest v0.140.1-0.20251120204106-2e9c82787618 h1:+S2kVxZdOgVNJOExhBoSA4MaDrNh7vPSXRv/SKO+VjA= -go.opentelemetry.io/collector/exporter/exportertest v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:ut6WpmCj7+10NqBFgZZfPF1gClMINEc8XKrnnAcBT84= -go.opentelemetry.io/collector/exporter/xexporter v0.140.1-0.20251120204106-2e9c82787618 h1:o6TAfHNqM6NXFzOpAyvGl8s86/9uVLUKeuiw7NP3ZA0= -go.opentelemetry.io/collector/exporter/xexporter v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:KIn0RaW66ifb6tXKz5XU+icFBVpn2QDH5QqaKdZDEJA= -go.opentelemetry.io/collector/extension v1.46.1-0.20251120204106-2e9c82787618 h1:dEOdTe91ephosris+SqcCNMigbTAVKVeTH5y/RKFWok= -go.opentelemetry.io/collector/extension v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:/NGiZQFF7hTyfRULTgtYw27cIW8i0hWUTp12lDftZS0= -go.opentelemetry.io/collector/extension/extensiontest v0.140.0 h1:a4ggfsp73GA9oGCxBtmQJE827SRq36E+YQIZ0MGIKVQ= -go.opentelemetry.io/collector/extension/extensiontest v0.140.0/go.mod h1:TKR1zB0CtJ3tedNyUUaeCw5O2qPlFNjHKmh2ri53uTU= -go.opentelemetry.io/collector/extension/xextension v0.140.1-0.20251120204106-2e9c82787618 h1:MSyc7Y/pAl+HYhGNe+xEnGQoCNkSjZLEhbtY5wjxUng= -go.opentelemetry.io/collector/extension/xextension v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:avzOyx3eIOr/AYcfsaBF9iMZVJnnp/UsdtJUNemYgcs= -go.opentelemetry.io/collector/featuregate v1.46.1-0.20251120204106-2e9c82787618 h1:kVcNLQHeTacufSIPasBJG7WbR02qxEBUWfrMAu/Un40= -go.opentelemetry.io/collector/featuregate v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4= -go.opentelemetry.io/collector/pdata v1.46.1-0.20251120204106-2e9c82787618 h1:w4Sd8D+T6wdekkBJlfjAsa7wpXDUmb3wQicikJ8vI9M= -go.opentelemetry.io/collector/pdata v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:AqZXTFkj01IxuiHZ1/I7UcGqaljvF5xiUXNYGxRqVp8= -go.opentelemetry.io/collector/pdata/pprofile v0.140.1-0.20251120204106-2e9c82787618 h1:EPM+f1DSlHtcTT32N2tfIwXY58N5lOChdYNEEgBk5uA= -go.opentelemetry.io/collector/pdata/pprofile v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:01EwjIBpIcmJva7IoXPmHPmACGzsGxFi9xhZhY7W4q8= -go.opentelemetry.io/collector/pdata/testdata v0.140.0 h1:jMhHRS8HbiYwXeElnuTNT+17QGUF+5A5MPgdSOjpJrw= -go.opentelemetry.io/collector/pdata/testdata v0.140.0/go.mod h1:4BZo10Ua0sbxrqMOPzVU4J/EJdE3js472lskyPW4re8= -go.opentelemetry.io/collector/pdata/xpdata v0.140.1-0.20251120204106-2e9c82787618 h1:ucCtCZIzRute6Mx7CE5RqgHNNT950uRdow5HtfbtJCg= -go.opentelemetry.io/collector/pdata/xpdata v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:yKJQ+zPe6c9teCbRwJ+1kK3Fw+pgtKgDXPLCKleZLJI= -go.opentelemetry.io/collector/pipeline v1.46.1-0.20251120204106-2e9c82787618 h1:shpb1oV7YQgGaPP59WC/A72B+wdki9DfdJ315O2UtnY= -go.opentelemetry.io/collector/pipeline v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI= -go.opentelemetry.io/collector/receiver v1.46.1-0.20251120204106-2e9c82787618 h1:lEhxCaW1jtBwV3lTPErL2YhfzH8J9FOn2zLtU6aqJt0= -go.opentelemetry.io/collector/receiver v1.46.1-0.20251120204106-2e9c82787618/go.mod h1:6AXBeYTN2iK2f8yNWPI7gz/3xpDLgF4L5DInhYeWBhE= -go.opentelemetry.io/collector/receiver/receivertest v0.140.1-0.20251120204106-2e9c82787618 h1:gKeCA1TJYgRUftF3mV2e3Cz4sd727vr2ZJBDODMiZr8= -go.opentelemetry.io/collector/receiver/receivertest v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:AhZsaTZ8CBeCd0m4WYycciOYltjw/E8AH6b7kKZIeTA= -go.opentelemetry.io/collector/receiver/xreceiver v0.140.1-0.20251120204106-2e9c82787618 h1:HIDI1rbOfXhuO6LUVZ9C7//rF6GloYcylIoC44102Cw= -go.opentelemetry.io/collector/receiver/xreceiver v0.140.1-0.20251120204106-2e9c82787618/go.mod h1:he6Lbg4S8T8dpwBTGwvRiR6SRMLB6iv0ZTWsOqGZ4iM= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= -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.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/exporter/carbonexporter/internal/metadata/generated_status.go b/exporter/carbonexporter/internal/metadata/generated_status.go deleted file mode 100644 index f5e74171783dd..0000000000000 --- a/exporter/carbonexporter/internal/metadata/generated_status.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by mdatagen. DO NOT EDIT. - -package metadata - -import ( - "go.opentelemetry.io/collector/component" -) - -var ( - Type = component.MustNewType("carbon") - ScopeName = "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" -) - -const ( - MetricsStability = component.StabilityLevelUnmaintained -) diff --git a/exporter/carbonexporter/metadata.yaml b/exporter/carbonexporter/metadata.yaml deleted file mode 100644 index 9fe6074aedc32..0000000000000 --- a/exporter/carbonexporter/metadata.yaml +++ /dev/null @@ -1,14 +0,0 @@ -type: carbon - -status: - class: exporter - stability: - unmaintained: [metrics] - distributions: [contrib] - codeowners: - active: [] - emeritus: [aboguszewski-sumo] - seeking_new: true - -tests: - expect_consumer_error: true \ No newline at end of file diff --git a/exporter/carbonexporter/metricdata_to_plaintext.go b/exporter/carbonexporter/metricdata_to_plaintext.go deleted file mode 100644 index b10259bcfe946..0000000000000 --- a/exporter/carbonexporter/metricdata_to_plaintext.go +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" - -import ( - "bytes" - "strconv" - "strings" - "sync" - - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/pmetric" -) - -const ( - // sanitizedRune is used to replace any invalid char per Carbon format. - sanitizedRune = '_' - - // Tag related constants per Carbon plaintext protocol. - tagPrefix = ";" - tagKeyValueSeparator = "=" - tagValueEmptyPlaceholder = "" - tagLineEmptySpace = " " - tagLineNewLine = "\n" - - // Constants used when converting from distribution metrics to Carbon format. - distributionBucketSuffix = ".bucket" - distributionUpperBoundTagKey = "upper_bound" - distributionUpperBoundTagBeforeValue = tagPrefix + distributionUpperBoundTagKey + tagKeyValueSeparator - - // Constants used when converting from summary metrics to Carbon format. - summaryQuantileSuffix = ".quantile" - summaryQuantileTagKey = "quantile" - summaryQuantileTagBeforeValue = tagPrefix + summaryQuantileTagKey + tagKeyValueSeparator - - // Suffix to be added to original metric name for a Carbon metric representing - // a count metric for either distribution or summary metrics. - countSuffix = ".count" - - // Textual representation for positive infinity valid in Carbon, ie.: - // positive infinity as represented in Python. - infinityCarbonValue = "inf" -) - -var writerPool = sync.Pool{ - New: func() any { - // Start with a buffer of 1KB. - return bytes.NewBuffer(make([]byte, 0, 1024)) - }, -} - -// metricDataToPlaintext converts internal metrics data to the Carbon plaintext -// format as defined in https://graphite.readthedocs.io/en/latest/feeding-carbon.html#the-plaintext-protocol) -// and https://graphite.readthedocs.io/en/latest/tags.html#carbon. See details -// below. -// -// Each metric point becomes a single string with the following format: -// -// " " -// -// The contains the metric name and its tags and has the following, -// format: -// -// [;tag0;...;tagN] -// -// is the name of the metric and terminates either at the first ';' -// or at the end of the path. -// -// is of the form "key=val", where key can contain any char except ";!^=" and -// val can contain any char except ";~". -// -// The is the textual representation of the metric value. -// -// The is the Unix time text of when the measurement was made. -// -// The returned values are: -// - a string concatenating all generated "lines" (each single one representing -// a single Carbon metric. -// - number of time series successfully converted to carbon. -// - number of time series that could not be converted to Carbon. -func metricDataToPlaintext(md pmetric.Metrics) string { - if md.DataPointCount() == 0 { - return "" - } - - buf := writerPool.Get().(*bytes.Buffer) - buf.Reset() - defer writerPool.Put(buf) - - for i := 0; i < md.ResourceMetrics().Len(); i++ { - rm := md.ResourceMetrics().At(i) - for j := 0; j < rm.ScopeMetrics().Len(); j++ { - sm := rm.ScopeMetrics().At(j) - for k := 0; k < sm.Metrics().Len(); k++ { - metric := sm.Metrics().At(k) - if metric.Name() == "" { - // TODO: log error info - continue - } - switch metric.Type() { - case pmetric.MetricTypeGauge: - writeNumberDataPoints(buf, metric.Name(), metric.Gauge().DataPoints()) - case pmetric.MetricTypeSum: - writeNumberDataPoints(buf, metric.Name(), metric.Sum().DataPoints()) - case pmetric.MetricTypeHistogram: - formatHistogramDataPoints(buf, metric.Name(), metric.Histogram().DataPoints()) - case pmetric.MetricTypeSummary: - formatSummaryDataPoints(buf, metric.Name(), metric.Summary().DataPoints()) - } - } - } - } - - return buf.String() -} - -func writeNumberDataPoints(buf *bytes.Buffer, metricName string, dps pmetric.NumberDataPointSlice) { - for i := 0; i < dps.Len(); i++ { - dp := dps.At(i) - var valueStr string - switch dp.ValueType() { - case pmetric.NumberDataPointValueTypeEmpty: - continue // skip this data point - otherwise an empty string will be used as the value and the backend will use the timestamp as the metric value - case pmetric.NumberDataPointValueTypeInt: - valueStr = formatInt64(dp.IntValue()) - case pmetric.NumberDataPointValueTypeDouble: - valueStr = formatFloatForValue(dp.DoubleValue()) - } - writeLine( - buf, - buildPath(metricName, dp.Attributes()), - valueStr, - formatTimestamp(dp.Timestamp())) - } -} - -// formatHistogramDataPoints transforms a slice of histogram data points into a series -// of Carbon metrics and injects them into the string builder. -// -// Carbon doesn't have direct support to distribution metrics they will be -// translated into a series of Carbon metrics: -// -// 1. The total count will be represented by a metric named ".count". -// -// 2. The total sum will be represented by a metric with the original "". -// -// 3. Each histogram bucket is represented by a metric named ".bucket" -// and will include a dimension "upper_bound" that specifies the maximum value in -// that bucket. This metric specifies the number of events with a value that is -// less than or equal to the upper bound. -func formatHistogramDataPoints( - buf *bytes.Buffer, - metricName string, - dps pmetric.HistogramDataPointSlice, -) { - for i := 0; i < dps.Len(); i++ { - dp := dps.At(i) - - timestampStr := formatTimestamp(dp.Timestamp()) - formatCountAndSum(buf, metricName, dp.Attributes(), dp.Count(), dp.Sum(), timestampStr) - if dp.ExplicitBounds().Len() == 0 { - continue - } - - bounds := dp.ExplicitBounds().AsRaw() - carbonBounds := make([]string, len(bounds)+1) - for i := range bounds { - carbonBounds[i] = formatFloatForLabel(bounds[i]) - } - carbonBounds[len(carbonBounds)-1] = infinityCarbonValue - - bucketPath := buildPath(metricName+distributionBucketSuffix, dp.Attributes()) - for j := 0; j < dp.BucketCounts().Len(); j++ { - writeLine( - buf, - bucketPath+distributionUpperBoundTagBeforeValue+carbonBounds[j], - formatUint64(dp.BucketCounts().At(j)), - timestampStr) - } - } -} - -// formatSummaryDataPoints transforms a slice of summary data points into a series -// of Carbon metrics and injects them into the string builder. -// -// Carbon doesn't have direct support to summary metrics they will be -// translated into a series of Carbon metrics: -// -// 1. The total count will be represented by a metric named ".count". -// -// 2. The total sum will be represented by a metric with the original "". -// -// 3. Each quantile is represented by a metric named ".quantile" -// and will include a tag key "quantile" that specifies the quantile value. -func formatSummaryDataPoints( - buf *bytes.Buffer, - metricName string, - dps pmetric.SummaryDataPointSlice, -) { - for i := 0; i < dps.Len(); i++ { - dp := dps.At(i) - - timestampStr := formatTimestamp(dp.Timestamp()) - formatCountAndSum(buf, metricName, dp.Attributes(), dp.Count(), dp.Sum(), timestampStr) - - if dp.QuantileValues().Len() == 0 { - continue - } - - quantilePath := buildPath(metricName+summaryQuantileSuffix, dp.Attributes()) - for j := 0; j < dp.QuantileValues().Len(); j++ { - writeLine( - buf, - quantilePath+summaryQuantileTagBeforeValue+formatFloatForLabel(dp.QuantileValues().At(j).Quantile()*100), - formatFloatForValue(dp.QuantileValues().At(j).Value()), - timestampStr) - } - } -} - -// Carbon doesn't have direct support to distribution or summary metrics in both -// cases it needs to create a "count" and a "sum" metric. This function creates -// both, as follows: -// -// 1. The total count will be represented by a metric named ".count". -// -// 2. The total sum will be represented by a metruc with the original "". -func formatCountAndSum( - buf *bytes.Buffer, - metricName string, - attributes pcommon.Map, - count uint64, - sum float64, - timestampStr string, -) { - // Write count and sum metrics. - writeLine( - buf, - buildPath(metricName+countSuffix, attributes), - formatUint64(count), - timestampStr) - - writeLine( - buf, - buildPath(metricName, attributes), - formatFloatForValue(sum), - timestampStr) -} - -// buildPath is used to build the per description above. -func buildPath(name string, attributes pcommon.Map) string { - if attributes.Len() == 0 { - return name - } - - buf := writerPool.Get().(*bytes.Buffer) - buf.Reset() - defer writerPool.Put(buf) - - buf.WriteString(name) - for k, v := range attributes.All() { - value := v.AsString() - if value == "" { - value = tagValueEmptyPlaceholder - } - buf.WriteString(tagPrefix) - buf.WriteString(sanitizeTagKey(k)) - buf.WriteString(tagKeyValueSeparator) - buf.WriteString(value) - } - - return buf.String() -} - -// writeLine builds a single Carbon metric textual line, ie.: it already adds -// a new-line character at the end of the string. -func writeLine(buf *bytes.Buffer, path, value, timestamp string) { - buf.WriteString(path) - buf.WriteString(tagLineEmptySpace) - buf.WriteString(value) - buf.WriteString(tagLineEmptySpace) - buf.WriteString(timestamp) - buf.WriteString(tagLineNewLine) -} - -// sanitizeTagKey removes any invalid character from the tag key, the invalid -// characters are ";!^=". -func sanitizeTagKey(key string) string { - mapRune := func(r rune) rune { - switch r { - case ';', '!', '^', '=': - return sanitizedRune - default: - return r - } - } - - return strings.Map(mapRune, key) -} - -// sanitizeTagValue removes any invalid character from the tag value, the invalid -// characters are ";~". -func sanitizeTagValue(value string) string { - mapRune := func(r rune) rune { - switch r { - case ';', '~': - return sanitizedRune - default: - return r - } - } - - return strings.Map(mapRune, value) -} - -// Formats a float64 per Prometheus label value. This is an attempt to keep other -// the label values with different formats of metrics. -func formatFloatForLabel(f float64) string { - return strconv.FormatFloat(f, 'g', -1, 64) -} - -// Formats a float64 per Carbon plaintext format. -func formatFloatForValue(f float64) string { - return strconv.FormatFloat(f, 'f', -1, 64) -} - -func formatUint64(i uint64) string { - return strconv.FormatUint(i, 10) -} - -func formatInt64(i int64) string { - return strconv.FormatInt(i, 10) -} - -func formatTimestamp(timestamp pcommon.Timestamp) string { - return formatUint64(uint64(timestamp) / 1e9) -} diff --git a/exporter/carbonexporter/metricdata_to_plaintext_test.go b/exporter/carbonexporter/metricdata_to_plaintext_test.go deleted file mode 100644 index 8cd23605a9b85..0000000000000 --- a/exporter/carbonexporter/metricdata_to_plaintext_test.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package carbonexporter - -import ( - "strconv" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/pmetric" -) - -func TestSanitizeTagKey(t *testing.T) { - tests := []struct { - name string - key string - want string - }{ - { - name: "no_changes", - key: "a valid tag key", - want: "a valid tag key", - }, - { - name: "remove_tag_set", - key: "a" + tagKeyValueSeparator + "c", - want: "a" + string(sanitizedRune) + "c", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := sanitizeTagKey(tt.key) - assert.Equal(t, tt.want, got) - }) - } -} - -func TestSanitizeTagValue(t *testing.T) { - tests := []struct { - name string - value string - want string - }{ - { - name: "no_changes", - value: "a valid tag value", - want: "a valid tag value", - }, - { - name: "replace_tilde", - value: "a~c", - want: "a" + string(sanitizedRune) + "c", - }, - { - name: "replace_semicol", - value: "a;c", - want: "a" + string(sanitizedRune) + "c", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := sanitizeTagValue(tt.value) - assert.Equal(t, tt.want, got) - }) - } -} - -func TestBuildPath(t *testing.T) { - tests := []struct { - name string - attributes pcommon.Map - want string - }{ - { - name: "happy_path", - attributes: func() pcommon.Map { - attr := pcommon.NewMap() - attr.PutStr("key0", "val0") - return attr - }(), - want: "happy_path;key0=val0", - }, - { - name: "empty_value", - attributes: func() pcommon.Map { - attr := pcommon.NewMap() - attr.PutStr("k0", "") - attr.PutStr("k1", "v1") - return attr - }(), - want: "empty_value;k0=" + tagValueEmptyPlaceholder + ";k1=v1", - }, - { - name: "int_value", - attributes: func() pcommon.Map { - attr := pcommon.NewMap() - attr.PutInt("k", 1) - return attr - }(), - want: "int_value;k=1", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := buildPath(tt.name, tt.attributes) - assert.Equal(t, tt.want, got) - }) - } -} - -func TestToPlaintext(t *testing.T) { - unixSecs := int64(1574092046) - expectedUnixSecsStr := strconv.FormatInt(unixSecs, 10) - unixNSecs := int64(11 * time.Millisecond) - tsUnix := time.Unix(unixSecs, unixNSecs) - - doubleVal := 1234.5678 - expectedDobuleValStr := strconv.FormatFloat(doubleVal, 'g', -1, 64) - int64Val := int64(123) - expectedInt64ValStr := "123" - - distributionCount := uint64(16) - distributionSum := float64(34.56) - distributionBounds := []float64{1.5, 2, 4} - distributionCounts := []uint64{4, 2, 3, 7} - - summaryCount := uint64(11) - summarySum := float64(111) - summaryQuantiles := []float64{90, 95, 99, 99.9} - summaryQuantileValues := []float64{100, 6, 4, 1} - tests := []struct { - name string - metricsDataFn func() pmetric.Metrics - wantLines []string - wantExtraLinesCount int - }{ - { - name: "gauge", - metricsDataFn: func() pmetric.Metrics { - md := pmetric.NewMetrics() - ms := md.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics() - ms.AppendEmpty().SetName("gauge_double_no_dims") - dps1 := ms.At(0).SetEmptyGauge().DataPoints() - dps1.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps1.At(0).SetDoubleValue(doubleVal) - ms.AppendEmpty().SetName("gauge_int_no_dims") - dps2 := ms.At(1).SetEmptyGauge().DataPoints() - dps2.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps2.At(0).SetIntValue(int64Val) - ms.AppendEmpty().SetName("gauge_double_with_dims") - dps3 := ms.At(2).SetEmptyGauge().DataPoints() - dps3.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps3.At(0).Attributes().PutStr("k0", "v0") - dps3.At(0).Attributes().PutStr("k1", "v1") - dps3.At(0).SetDoubleValue(doubleVal) - ms.AppendEmpty().SetName("gauge_int_with_dims") - dps4 := ms.At(3).SetEmptyGauge().DataPoints() - dps4.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps4.At(0).Attributes().PutStr("k0", "v0") - dps4.At(0).Attributes().PutStr("k1", "v1") - dps4.At(0).SetIntValue(int64Val) - ms.AppendEmpty().SetName("gauge_no_value") - dps5 := ms.At(4).SetEmptyGauge().DataPoints() - dps5.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - return md - }, - wantLines: []string{ - "gauge_double_no_dims " + expectedDobuleValStr + " " + expectedUnixSecsStr, - "gauge_int_no_dims " + expectedInt64ValStr + " " + expectedUnixSecsStr, - "gauge_double_with_dims;k0=v0;k1=v1 " + expectedDobuleValStr + " " + expectedUnixSecsStr, - "gauge_int_with_dims;k0=v0;k1=v1 " + expectedInt64ValStr + " " + expectedUnixSecsStr, - }, - }, - { - name: "cumulative_monotonic_sum", - metricsDataFn: func() pmetric.Metrics { - md := pmetric.NewMetrics() - ms := md.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics() - ms.AppendEmpty().SetName("cumulative_double_no_dims") - ms.At(0).SetEmptySum().SetIsMonotonic(true) - dps1 := ms.At(0).Sum().DataPoints() - dps1.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps1.At(0).SetDoubleValue(doubleVal) - ms.AppendEmpty().SetName("cumulative_int_no_dims") - ms.At(1).SetEmptySum().SetIsMonotonic(true) - dps2 := ms.At(1).Sum().DataPoints() - dps2.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps2.At(0).SetIntValue(int64Val) - ms.AppendEmpty().SetName("cumulative_double_with_dims") - ms.At(2).SetEmptySum().SetIsMonotonic(true) - dps3 := ms.At(2).Sum().DataPoints() - dps3.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps3.At(0).Attributes().PutStr("k0", "v0") - dps3.At(0).Attributes().PutStr("k1", "v1") - dps3.At(0).SetDoubleValue(doubleVal) - ms.AppendEmpty().SetName("cumulative_int_with_dims") - ms.At(3).SetEmptySum().SetIsMonotonic(true) - dps4 := ms.At(3).Sum().DataPoints() - dps4.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dps4.At(0).Attributes().PutStr("k0", "v0") - dps4.At(0).Attributes().PutStr("k1", "v1") - dps4.At(0).SetIntValue(int64Val) - ms.AppendEmpty().SetName("cumulative_no_value") - ms.At(4).SetEmptySum().SetIsMonotonic(true) - dps5 := ms.At(4).Sum().DataPoints() - dps5.AppendEmpty().SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - return md - }, - wantLines: []string{ - "cumulative_double_no_dims " + expectedDobuleValStr + " " + expectedUnixSecsStr, - "cumulative_int_no_dims " + expectedInt64ValStr + " " + expectedUnixSecsStr, - "cumulative_double_with_dims;k0=v0;k1=v1 " + expectedDobuleValStr + " " + expectedUnixSecsStr, - "cumulative_int_with_dims;k0=v0;k1=v1 " + expectedInt64ValStr + " " + expectedUnixSecsStr, - }, - }, - { - name: "histogram", - metricsDataFn: func() pmetric.Metrics { - md := pmetric.NewMetrics() - ms := md.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics() - ms.AppendEmpty().SetName("distrib") - ms.At(0).SetEmptyHistogram().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) - dp := ms.At(0).SetEmptyHistogram().DataPoints().AppendEmpty() - dp.SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dp.Attributes().PutStr("k0", "v0") - dp.Attributes().PutStr("k1", "v1") - dp.SetCount(distributionCount) - dp.SetSum(distributionSum) - dp.ExplicitBounds().FromRaw(distributionBounds) - dp.BucketCounts().FromRaw(distributionCounts) - return md - }, - wantLines: expectedDistributionLines( - "distrib", ";k0=v0;k1=v1", expectedUnixSecsStr, - distributionSum, - distributionCount, - distributionBounds, - distributionCounts), - }, - { - name: "summary", - metricsDataFn: func() pmetric.Metrics { - md := pmetric.NewMetrics() - ms := md.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics() - ms.AppendEmpty().SetName("summary") - dp := ms.At(0).SetEmptySummary().DataPoints().AppendEmpty() - dp.SetTimestamp(pcommon.NewTimestampFromTime(tsUnix)) - dp.Attributes().PutStr("k0", "v0") - dp.Attributes().PutStr("k1", "v1") - dp.SetCount(summaryCount) - dp.SetSum(summarySum) - for i := range summaryQuantiles { - qv := dp.QuantileValues().AppendEmpty() - qv.SetQuantile(summaryQuantiles[i] / 100) - qv.SetValue(summaryQuantileValues[i]) - } - return md - }, - wantLines: expectedSummaryLines( - "summary", ";k0=v0;k1=v1", expectedUnixSecsStr, - summarySum, - summaryCount, - summaryQuantiles, - summaryQuantileValues), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotLines := metricDataToPlaintext(tt.metricsDataFn()) - got := strings.Split(gotLines, "\n") - got = got[:len(got)-1] - assert.Len(t, got, len(tt.wantLines)+tt.wantExtraLinesCount) - assert.Subset(t, tt.wantLines, got) - }) - } -} - -func expectedDistributionLines( - metricName string, - tags string, - timestampStr string, - sum float64, - count uint64, - bounds []float64, - counts []uint64, -) []string { - var lines []string - lines = append(lines, - metricName+".count"+tags+" "+formatInt64(int64(count))+" "+timestampStr, - metricName+tags+" "+formatFloatForLabel(sum)+" "+timestampStr, - metricName+".bucket"+tags+";upper_bound=inf "+formatInt64(int64(counts[len(bounds)]))+" "+timestampStr, - ) - for i, bound := range bounds { - lines = append(lines, - metricName+".bucket"+tags+";upper_bound="+formatFloatForLabel(bound)+" "+formatInt64(int64(counts[i]))+" "+timestampStr) - } - - return lines -} - -func expectedSummaryLines( - metricName string, - tags string, - timestampStr string, - sum float64, - count uint64, - summaryQuantiles []float64, - summaryQuantileValues []float64, -) []string { - var lines []string - lines = append(lines, - metricName+".count"+tags+" "+formatInt64(int64(count))+" "+timestampStr, - metricName+tags+" "+formatFloatForValue(sum)+" "+timestampStr, - ) - for i := range summaryQuantiles { - lines = append(lines, - metricName+".quantile"+tags+";quantile="+formatFloatForLabel(summaryQuantiles[i])+" "+formatFloatForValue(summaryQuantileValues[i])+" "+timestampStr) - } - return lines -} - -func BenchmarkConsumeMetricsDefault(b *testing.B) { - md := generateSmallBatch() - - b.ReportAllocs() - for b.Loop() { - assert.Len(b, metricDataToPlaintext(md), 62) - } -} diff --git a/exporter/carbonexporter/testdata/config.yaml b/exporter/carbonexporter/testdata/config.yaml deleted file mode 100644 index a0d330fbf5954..0000000000000 --- a/exporter/carbonexporter/testdata/config.yaml +++ /dev/null @@ -1,24 +0,0 @@ -carbon: -# by default it will export to localhost:2003 using tcp -carbon/allsettings: - # use endpoint to specify alternative destinations for the exporter, - # the default is localhost:2003 - endpoint: localhost:8080 - max_idle_conns: 15 - # timeout is the maximum duration allowed to connecting and sending the - # data to the Carbon/Graphite backend. - # The default is 5 seconds. - timeout: 10s - sending_queue: - enabled: true - num_consumers: 2 - queue_size: 10 - retry_on_failure: - enabled: true - initial_interval: 10s - randomization_factor: 0.7 - multiplier: 3.14 - max_interval: 60s - max_elapsed_time: 10m - resource_to_telemetry_conversion: - enabled: true diff --git a/exporter/elasticsearchexporter/integrationtest/go.mod b/exporter/elasticsearchexporter/integrationtest/go.mod index 984b76af1254f..5f9b27cfc8524 100644 --- a/exporter/elasticsearchexporter/integrationtest/go.mod +++ b/exporter/elasticsearchexporter/integrationtest/go.mod @@ -315,8 +315,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperre replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/datadogreceiver => ../../../receiver/datadogreceiver -replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter => ../../carbonexporter - replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter => ../../splunkhecexporter replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter => ../../prometheusexporter diff --git a/internal/tidylist/tidylist.txt b/internal/tidylist/tidylist.txt index feac0d24ce542..76e427a21a4a6 100644 --- a/internal/tidylist/tidylist.txt +++ b/internal/tidylist/tidylist.txt @@ -8,9 +8,6 @@ pkg/ottl connector/routingconnector internal/pdatautil connector/spanmetricsconnector -internal/common -pkg/resourcetotelemetry -exporter/carbonexporter internal/grpcutil internal/sharedcomponent receiver/otelarrowreceiver @@ -20,6 +17,8 @@ receiver/otelarrowreceiver internal/otelarrow exporter/otelarrowexporter receiver/otelarrowreceiver +internal/common +pkg/resourcetotelemetry pkg/translator/prometheus pkg/translator/prometheusremotewrite exporter/prometheusremotewriteexporter diff --git a/reports/distributions/contrib.yaml b/reports/distributions/contrib.yaml index 2661429cfd286..04432f4181d51 100644 --- a/reports/distributions/contrib.yaml +++ b/reports/distributions/contrib.yaml @@ -26,7 +26,6 @@ components: - azuredataexplorer - azuremonitor - bmchelix - - carbon - cassandra - clickhouse - coralogix diff --git a/testbed/datasenders/carbon.go b/testbed/datasenders/carbon.go deleted file mode 100644 index 785c6a305c47a..0000000000000 --- a/testbed/datasenders/carbon.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package datasenders // import "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/datasenders" - -import ( - "context" - "fmt" - "time" - - "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/consumer" - "go.opentelemetry.io/collector/exporter/exporterhelper" - "go.opentelemetry.io/collector/exporter/exportertest" - "go.uber.org/zap" - - "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter" - "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed" -) - -// CarbonDataSender implements MetricDataSender for Carbon metrics protocol. -type CarbonDataSender struct { - testbed.DataSenderBase - consumer.Metrics -} - -// Ensure CarbonDataSender implements MetricDataSenderOld. -var _ testbed.MetricDataSender = (*CarbonDataSender)(nil) - -// NewCarbonDataSender creates a new Carbon metric protocol sender that will send -// to the specified port after Start is called. -func NewCarbonDataSender(port int) *CarbonDataSender { - return &CarbonDataSender{ - DataSenderBase: testbed.DataSenderBase{ - Port: port, - Host: testbed.DefaultHost, - }, - } -} - -// Start the sender. -func (cs *CarbonDataSender) Start() error { - factory := carbonexporter.NewFactory() - cfg := &carbonexporter.Config{ - TCPAddrConfig: confignet.TCPAddrConfig{ - Endpoint: cs.GetEndpoint().String(), - }, - TimeoutSettings: exporterhelper.TimeoutConfig{ - Timeout: 5 * time.Second, - }, - } - params := exportertest.NewNopSettings(factory.Type()) - params.Logger = zap.L() - - exporter, err := factory.CreateMetrics(context.Background(), params, cfg) - if err != nil { - return err - } - - cs.Metrics = exporter - return nil -} - -// GenConfigYAMLStr returns receiver config for the agent. -func (cs *CarbonDataSender) GenConfigYAMLStr() string { - // Note that this generates a receiver config for agent. - return fmt.Sprintf(` - carbon: - endpoint: %s`, cs.GetEndpoint()) -} - -// ProtocolName returns protocol name as it is specified in Collector config. -func (*CarbonDataSender) ProtocolName() string { - return "carbon" -} diff --git a/testbed/go.mod b/testbed/go.mod index bb82316f15d91..5b69d3a21118f 100644 --- a/testbed/go.mod +++ b/testbed/go.mod @@ -7,7 +7,6 @@ require ( github.com/jaegertracing/jaeger-idl v0.6.0 github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector v0.140.1 github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.140.1 - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter v0.140.1 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/otelarrowexporter v0.140.1 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter v0.140.1 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/signalfxexporter v0.140.1 @@ -432,8 +431,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/connector/span replace github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector => ../connector/routingconnector -replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter => ../exporter/carbonexporter - replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter => ../exporter/prometheusexporter replace github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusremotewriteexporter => ../exporter/prometheusremotewriteexporter diff --git a/testbed/stabilitytests/metric_test.go b/testbed/stabilitytests/metric_test.go index a16abba531bbc..f49ac5a8e47b0 100644 --- a/testbed/stabilitytests/metric_test.go +++ b/testbed/stabilitytests/metric_test.go @@ -30,23 +30,6 @@ func TestStabilityMetricsOTLP(t *testing.T) { ) } -func TestStabilityMetricsCarbon(t *testing.T) { - scenarios.Scenario10kItemsPerSecond( - t, - datasenders.NewCarbonDataSender(testutil.GetAvailablePort(t)), - datareceivers.NewCarbonDataReceiver(testutil.GetAvailablePort(t)), - testbed.ResourceSpec{ - ExpectedMaxCPU: 237, - ExpectedMaxRAM: 120, - ResourceCheckPeriod: resourceCheckPeriod, - }, - contribPerfResultsSummary, - nil, - nil, - nil, - ) -} - func TestStabilityMetricsSignalFx(t *testing.T) { scenarios.Scenario10kItemsPerSecond( t, diff --git a/testbed/tests/metric_test.go b/testbed/tests/metric_test.go index 6409b02bc6f85..c45092051edeb 100644 --- a/testbed/tests/metric_test.go +++ b/testbed/tests/metric_test.go @@ -28,15 +28,6 @@ func TestMetric10kDPS(t *testing.T) { resourceSpec testbed.ResourceSpec skipMessage string }{ - { - name: "Carbon", - sender: datasenders.NewCarbonDataSender(testutil.GetAvailablePort(t)), - receiver: datareceivers.NewCarbonDataReceiver(testutil.GetAvailablePort(t)), - resourceSpec: testbed.ResourceSpec{ - ExpectedMaxCPU: 237, - ExpectedMaxRAM: 150, - }, - }, { name: "OTLP", sender: testbed.NewOTLPMetricDataSender(testbed.DefaultHost, testutil.GetAvailablePort(t)), diff --git a/versions.yaml b/versions.yaml index de96a800ce0e0..b2126ae2a96fd 100644 --- a/versions.yaml +++ b/versions.yaml @@ -39,7 +39,6 @@ module-sets: - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/azuredataexplorerexporter - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/azuremonitorexporter - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/bmchelixexporter - - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/cassandraexporter - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/clickhouseexporter - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/coralogixexporter