From ac801dee811cc5a842b4ffebb425ce11baba3e7f Mon Sep 17 00:00:00 2001 From: "Zeno (Cheng-Chuan) Peng" Date: Sat, 25 Jan 2025 18:20:11 -0700 Subject: [PATCH] [receiver/tcpcheck] Rebase Latest Version open-telemetry#34458 --- .chloggen/tcp-checker.yaml | 27 ++++++++ .../internal/configtcp/configtcp.go | 44 +++++++++++++ .../internal/configtcp/configtcp_test.go | 62 +++++++++++++++++++ .../expected_metrics/metrics_golden.yaml | 31 ++++++++++ versions.yaml | 1 + 5 files changed, 165 insertions(+) create mode 100644 .chloggen/tcp-checker.yaml create mode 100644 receiver/tcpcheckreceiver/internal/configtcp/configtcp.go create mode 100644 receiver/tcpcheckreceiver/internal/configtcp/configtcp_test.go create mode 100644 receiver/tcpcheckreceiver/testdata/expected_metrics/metrics_golden.yaml diff --git a/.chloggen/tcp-checker.yaml b/.chloggen/tcp-checker.yaml new file mode 100644 index 000000000000..23d1fe7a0da6 --- /dev/null +++ b/.chloggen/tcp-checker.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: new_component + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: tcpcheckreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Introducing new component tcpcheck receiver + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [34414] + +# (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: [] diff --git a/receiver/tcpcheckreceiver/internal/configtcp/configtcp.go b/receiver/tcpcheckreceiver/internal/configtcp/configtcp.go new file mode 100644 index 000000000000..facdc97da0ec --- /dev/null +++ b/receiver/tcpcheckreceiver/internal/configtcp/configtcp.go @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package configtcp // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver/internal/configtcp" + +import ( + "context" + "net" + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confignet" +) + +type TCPClientSettings struct { + // Endpoint is always required + Endpoint string `mapstructure:"endpoint"` + Timeout time.Duration `mapstructure:"timeout"` +} + +type Client struct { + net.Conn + TCPAddrConfig confignet.TCPAddrConfig +} + +// Dial starts a TCP session. +func (c *Client) Dial() (err error) { + c.Conn, err = c.TCPAddrConfig.Dial(context.Background()) + if err != nil { + return err + } + return nil +} + +func (tcs *TCPClientSettings) ToClient(_ component.Host, _ component.TelemetrySettings) (*Client, error) { + return &Client{ + TCPAddrConfig: confignet.TCPAddrConfig{ + Endpoint: tcs.Endpoint, + DialerConfig: confignet.DialerConfig{ + Timeout: tcs.Timeout, + }, + }, + }, nil +} diff --git a/receiver/tcpcheckreceiver/internal/configtcp/configtcp_test.go b/receiver/tcpcheckreceiver/internal/configtcp/configtcp_test.go new file mode 100644 index 000000000000..0cee34af3107 --- /dev/null +++ b/receiver/tcpcheckreceiver/internal/configtcp/configtcp_test.go @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package configtcp // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver/internal/configtcp" + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/extension/auth/authtest" +) + +type mockHost struct { + component.Host + ext map[component.ID]extension.Extension +} + +func TestAllTCPClientSettings(t *testing.T) { + host := &mockHost{ + ext: map[component.ID]extension.Extension{ + component.MustNewID("testauth"): &authtest.MockClient{}, + }, + } + + endpoint := "localhost:8080" + timeout := time.Second * 5 + + tests := []struct { + name string + settings TCPClientSettings + shouldError bool + }{ + { + name: "valid_settings_endpoint", + settings: TCPClientSettings{ + Endpoint: endpoint, + Timeout: timeout, + }, + shouldError: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tt := componenttest.NewNopTelemetrySettings() + tt.TracerProvider = nil + + client, err := test.settings.ToClient(host, tt) + if test.shouldError { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + assert.EqualValues(t, client.TCPAddrConfig.Endpoint, test.settings.Endpoint) + assert.EqualValues(t, client.TCPAddrConfig.DialerConfig.Timeout, test.settings.Timeout) + }) + } +} diff --git a/receiver/tcpcheckreceiver/testdata/expected_metrics/metrics_golden.yaml b/receiver/tcpcheckreceiver/testdata/expected_metrics/metrics_golden.yaml new file mode 100644 index 000000000000..477fa4bf455b --- /dev/null +++ b/receiver/tcpcheckreceiver/testdata/expected_metrics/metrics_golden.yaml @@ -0,0 +1,31 @@ +resourceMetrics: + - resource: {} + scopeMetrics: + - metrics: + - description: Measures the duration of TCP connection. + gauge: + dataPoints: + - asInt: "36" + attributes: + - key: tcp.endpoint + value: + stringValue: 127.0.0.1:8080 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: tcpcheck.duration + unit: ns + - description: 1 if the TCP client successfully connected, otherwise 0. + name: tcpcheck.status + gauge: + dataPoints: + - asInt: "1" + attributes: + - key: tcp.endpoint + value: + stringValue: 127.0.0.1:8080 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: "1" + scope: + name: otelcol/tcpcheckreceiver + version: latest diff --git a/versions.yaml b/versions.yaml index 2f15b1d7eb99..b28d79f50ff1 100644 --- a/versions.yaml +++ b/versions.yaml @@ -287,6 +287,7 @@ module-sets: - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/statsdreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/syslogreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/systemdreceiver + - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcplogreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/udplogreceiver