Skip to content

Commit

Permalink
[receiver/tcpcheck] Add New Receiver#34458
Browse files Browse the repository at this point in the history
[receiver/tcpcheck] Change CODEOWNERS#34458

[receiver/tcpcheck] Change CODEOWNERS#34458

[receiver/tcpcheck] Make Fmt#34458

[receiver/tcpcheck] Fix Version And Test#34458

[receiver/tcpcheck] Make Fmt#34458

[receiver/tcpcheck] Temporarily Change Owner#34458

[receiver/tcpcheck] Change Version#34458

[receiver/tcpcheck] Make Fmt#34458

[receiver/tcpcheck] Rebase#34458

[receiver/tcpcheck] Fix Test#34458

[receiver/tcpcheck] Make Tidy#34458
  • Loading branch information
chengchuanpeng committed Feb 8, 2025
1 parent b589bef commit dd615eb
Show file tree
Hide file tree
Showing 36 changed files with 2,019 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .chloggen/tcp-checker.yaml
Original file line number Diff line number Diff line change
@@ -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: []
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ receiver/sshcheckreceiver/ @open-telemetry
receiver/statsdreceiver/ @open-telemetry/collector-contrib-approvers @jmacd @dmitryax
receiver/syslogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @andrzej-stencel
receiver/systemdreceiver/ @open-telemetry/collector-contrib-approvers @Hemansh31 @atoulme
receiver/tcpcheckreceiver/ @open-telemetry/collector-contrib-approvers @atoulme @michael-burt @chengchuanpeng
receiver/tcplogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
receiver/tlscheckreceiver/ @open-telemetry/collector-contrib-approvers @atoulme @michael-burt
receiver/udplogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ body:
- receiver/statsd
- receiver/syslog
- receiver/systemd
- receiver/tcpcheck
- receiver/tcplog
- receiver/tlscheck
- receiver/udplog
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ body:
- receiver/statsd
- receiver/syslog
- receiver/systemd
- receiver/tcpcheck
- receiver/tcplog
- receiver/tlscheck
- receiver/udplog
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/other.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ body:
- receiver/statsd
- receiver/syslog
- receiver/systemd
- receiver/tcpcheck
- receiver/tcplog
- receiver/tlscheck
- receiver/udplog
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/unmaintained.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ body:
- receiver/statsd
- receiver/syslog
- receiver/systemd
- receiver/tcpcheck
- receiver/tcplog
- receiver/tlscheck
- receiver/udplog
Expand Down
1 change: 1 addition & 0 deletions internal/tidylist/tidylist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ receiver/sqlserverreceiver
receiver/sshcheckreceiver
receiver/statsdreceiver
receiver/systemdreceiver
receiver/tcpcheckreceiver
receiver/tcplogreceiver
receiver/tlscheckreceiver
receiver/udplogreceiver
Expand Down
1 change: 1 addition & 0 deletions receiver/tcpcheckreceiver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../Makefile.Common
48 changes: 48 additions & 0 deletions receiver/tcpcheckreceiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# TCP Check Receiver

<!-- status autogenerated section -->
| Status | |
| ------------- |-----------|
| Stability | [development]: metrics |
| Distributions | [contrib] |
| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ftcpcheck%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Areceiver%2Ftcpcheck) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ftcpcheck%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Areceiver%2Ftcpcheck) |
| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@michael-burt](https://www.github.com/michael-burt), [@chengchuanpeng](https://www.github.com/chengchuanpeng) |

[development]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#development
[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib
<!-- end autogenerated section -->

This receiver creates stats by connecting to an TCP server.


## Configuration

The following settings are required:
- `endpoint`

The following settings are optional:

- `collection_interval` (default = `60s`): This receiver collects metrics on an interval. Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`.

## Example Configuration

Targets are

```yaml
receivers:
tcpcheck:
targets:
- endpoint: example.com:443
dialer:
timeout: 15s
- endpoint: foobar.com:8080
dialer:
timeout: 15s
- endpoint: localhost:10901
```
The full list of settings exposed for this receiver are documented [here](./config.go) with detailed sample configurations [here](./testdata/config.yaml).
## Metrics
Details about the metrics produced by this receiver can be found in [metadata.yaml](./metadata.yaml)
81 changes: 81 additions & 0 deletions receiver/tcpcheckreceiver/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package tcpcheckreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver"

import (
"errors"
"fmt"
"net"
"strconv"
"strings"

"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/scraper/scraperhelper"
"go.uber.org/multierr"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver/internal/metadata"
)

// Predefined error responses for configuration validation failures
var (
errInvalidEndpoint = errors.New(`"Endpoint" must be in the form of <hostname>:<port>`)
errMissingTargets = errors.New(`No targets specified`)
errConfigTCPCheck = errors.New(`Invalid Config`)
)

// Config defines the configuration for the various elements of the receiver agent.
type Config struct {
scraperhelper.ControllerConfig `mapstructure:",squash"`
metadata.MetricsBuilderConfig `mapstructure:",squash"`
Targets []*confignet.TCPAddrConfig `mapstructure:",targets"`
}

func validatePort(port string) error {
portNum, err := strconv.Atoi(port)
if err != nil {
return fmt.Errorf("provided port is not a number: %s", port)
}
if portNum < 1 || portNum > 65535 {
return fmt.Errorf("provided port is out of valid range (1-65535): %d", portNum)
}
return nil
}

func validateTarget(cfg *confignet.TCPAddrConfig) error {
var err error

if cfg.Endpoint == "" {
return errMissingTargets
}

if strings.Contains(cfg.Endpoint, "://") {
return fmt.Errorf("endpoint contains a scheme, which is not allowed: %s", cfg.Endpoint)
}

_, port, parseErr := net.SplitHostPort(cfg.Endpoint)
if parseErr != nil {
return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), parseErr)
}

portParseErr := validatePort(port)
if portParseErr != nil {
return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), portParseErr)
}

return err
}

func (cfg *Config) Validate() error {
var err error

if len(cfg.Targets) == 0 {
err = multierr.Append(err, errMissingTargets)
}

for _, tcpConfig := range cfg.Targets {
err = multierr.Append(err, validateTarget(tcpConfig))
}

return err
}
123 changes: 123 additions & 0 deletions receiver/tcpcheckreceiver/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package tcpcheckreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver"

import (
"fmt"
"testing"
"time"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/scraper/scraperhelper"
)

func TestValidate(t *testing.T) {
testCases := []struct {
desc string
cfg *Config
expectedErr error
}{
{
desc: "missing targets",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: errMissingTargets,
},
{
desc: "invalid endpoint",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "endpoint: 12efg",
DialerConfig: confignet.DialerConfig{
Timeout: 12 * time.Second,
},
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, "provided port is not a number: 12efg"),
},
{
desc: "invalid config with multiple targets",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "endpoint: 12efg",
},
{
Endpoint: "https://example.com:80",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is not a number: 12efg; endpoint contains a scheme, which is not allowed: https://example.com:80`),
},
{
desc: "port out of range",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "www.opentelemetry.io:67000",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is out of valid range (1-65535): 67000`),
},
{
desc: "missing port",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "www.opentelemetry.io/docs",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `address www.opentelemetry.io/docs: missing port in address`),
},
{
desc: "valid config",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "opentelemetry.io:443",
DialerConfig: confignet.DialerConfig{
Timeout: 3 * time.Second,
},
},
{
Endpoint: "opentelemetry.io:8080",
DialerConfig: confignet.DialerConfig{
Timeout: 1 * time.Second,
},
},
{
Endpoint: "111.222.33.44:10000",
DialerConfig: confignet.DialerConfig{
Timeout: 5 * time.Second,
},
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: nil,
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
actualErr := tc.cfg.Validate()
if tc.expectedErr != nil {
require.EqualError(t, actualErr, tc.expectedErr.Error())
} else {
require.NoError(t, actualErr)
}
})
}
}
6 changes: 6 additions & 0 deletions receiver/tcpcheckreceiver/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package tcpcheckreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tcpcheckreceiver"

//go:generate mdatagen metadata.yaml
56 changes: 56 additions & 0 deletions receiver/tcpcheckreceiver/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[comment]: <> (Code generated by mdatagen. DO NOT EDIT.)

# tcpcheck

## Default Metrics

The following metrics are emitted by default. Each of them can be disabled by applying the following configuration:

```yaml
metrics:
<metric_name>:
enabled: false
```
### tcpcheck.duration
Measures the duration of TCP connection.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| ms | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| tcpcheck.endpoint | TCP endpoint | Any Str |
### tcpcheck.error
Records errors occurring during TCP check.
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| {error} | Sum | Int | Cumulative | true |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| tcpcheck.endpoint | TCP endpoint | Any Str |
| error.code | Error code recorded during check | Any Str |
### tcpcheck.status
1 if the TCP client successfully connected, otherwise 0.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| 1 | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| tcpcheck.endpoint | TCP endpoint | Any Str |
Loading

0 comments on commit dd615eb

Please sign in to comment.