From 2863b294c074e28ea536e80aecf5c46acf3c5ab3 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Mon, 21 Oct 2024 22:10:39 -0600 Subject: [PATCH 01/20] [receiver/tlscheck] Implement Scraper --- .../tlscheckreceiver-implementation.yaml | 27 ++++ receiver/tlscheckreceiver/README.md | 4 +- receiver/tlscheckreceiver/config.go | 47 ++++-- receiver/tlscheckreceiver/config_test.go | 37 +++-- receiver/tlscheckreceiver/documentation.md | 7 +- receiver/tlscheckreceiver/factory.go | 9 +- receiver/tlscheckreceiver/go.mod | 1 - receiver/tlscheckreceiver/go.sum | 2 - .../internal/metadata/generated_config.go | 46 +----- .../metadata/generated_config_test.go | 52 +------ .../internal/metadata/generated_metrics.go | 55 ++----- .../metadata/generated_metrics_test.go | 18 +-- .../internal/metadata/generated_resource.go | 36 ----- .../metadata/generated_resource_test.go | 40 ----- .../internal/metadata/testdata/config.yaml | 18 --- receiver/tlscheckreceiver/metadata.yaml | 11 +- receiver/tlscheckreceiver/scraper.go | 72 ++++++++- receiver/tlscheckreceiver/scraper_test.go | 143 ++++++++++++++++++ 18 files changed, 331 insertions(+), 294 deletions(-) create mode 100644 .chloggen/tlscheckreceiver-implementation.yaml delete mode 100644 receiver/tlscheckreceiver/internal/metadata/generated_resource.go delete mode 100644 receiver/tlscheckreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/tlscheckreceiver/scraper_test.go diff --git a/.chloggen/tlscheckreceiver-implementation.yaml b/.chloggen/tlscheckreceiver-implementation.yaml new file mode 100644 index 000000000000..d9695418d232 --- /dev/null +++ b/.chloggen/tlscheckreceiver-implementation.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: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: tlscheckreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Implement TLS Check Receiver for host-based checks + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [35842] + +# (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/receiver/tlscheckreceiver/README.md b/receiver/tlscheckreceiver/README.md index 1a5a89bf0317..a5b617719c95 100644 --- a/receiver/tlscheckreceiver/README.md +++ b/receiver/tlscheckreceiver/README.md @@ -24,8 +24,8 @@ By default, the TLS Check Receiver will emit a single metric, `tlscheck.time_lef receivers: tlscheck: targets: - - url: https://example.com - - url: https://foobar.com:8080 + - host: example.com:443 + - host: foobar.com:8080 ``` ## Certificate Verification diff --git a/receiver/tlscheckreceiver/config.go b/receiver/tlscheckreceiver/config.go index d20c7b2e091d..dae86fc0ce94 100644 --- a/receiver/tlscheckreceiver/config.go +++ b/receiver/tlscheckreceiver/config.go @@ -6,7 +6,9 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll import ( "errors" "fmt" - "net/url" + "net" + "strconv" + "strings" "go.opentelemetry.io/collector/receiver/scraperhelper" "go.uber.org/multierr" @@ -16,8 +18,7 @@ import ( // Predefined error responses for configuration validation failures var ( - errMissingURL = errors.New(`"url" must be specified`) - errInvalidURL = errors.New(`"url" must be in the form of ://[:]`) + errInvalidHost = errors.New(`"host" must be in the form of :`) ) // Config defines the configuration for the various elements of the receiver agent. @@ -28,31 +29,49 @@ type Config struct { } type targetConfig struct { - URL string `mapstructure:"url"` + Host string `mapstructure:"host"` +} + +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 } -// Validate validates the configuration by checking for missing or invalid fields func (cfg *targetConfig) Validate() error { var err error - if cfg.URL == "" { - err = multierr.Append(err, errMissingURL) - } else { - _, parseErr := url.ParseRequestURI(cfg.URL) - if parseErr != nil { - err = multierr.Append(err, fmt.Errorf("%s: %w", errInvalidURL.Error(), parseErr)) - } + if cfg.Host == "" { + return ErrMissingTargets + } + + if strings.Contains(cfg.Host, "://") { + return fmt.Errorf("host contains a scheme, which is not allowed: %s", cfg.Host) + } + + _, port, parseErr := net.SplitHostPort(cfg.Host) + if parseErr != nil { + return fmt.Errorf("%s: %w", errInvalidHost.Error(), parseErr) + } + + portParseErr := validatePort(port) + if portParseErr != nil { + return fmt.Errorf("%s: %w", errInvalidHost.Error(), portParseErr) } return err } -// Validate validates the configuration by checking for missing or invalid fields func (cfg *Config) Validate() error { var err error if len(cfg.Targets) == 0 { - err = multierr.Append(err, errMissingURL) + err = multierr.Append(err, ErrMissingTargets) } for _, target := range cfg.Targets { diff --git a/receiver/tlscheckreceiver/config_test.go b/receiver/tlscheckreceiver/config_test.go index 54e1748352c9..e3fa89c0d877 100644 --- a/receiver/tlscheckreceiver/config_test.go +++ b/receiver/tlscheckreceiver/config_test.go @@ -23,56 +23,71 @@ func TestValidate(t *testing.T) { Targets: []*targetConfig{}, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: errMissingURL, + expectedErr: ErrMissingTargets, }, { - desc: "invalid url", + desc: "invalid host", cfg: &Config{ Targets: []*targetConfig{ { - URL: "invalid://endpoint: 12efg", + Host: "endpoint: 12efg", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "invalid://endpoint: 12efg": invalid port ": 12efg" after host`), + expectedErr: fmt.Errorf("%w: %s", errInvalidHost, "provided port is not a number: 12efg"), }, { desc: "invalid config with multiple targets", cfg: &Config{ Targets: []*targetConfig{ { - URL: "invalid://endpoint: 12efg", + Host: "endpoint: 12efg", }, { - URL: "https://example.com", + Host: "https://example.com:80", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "invalid://endpoint: 12efg": invalid port ": 12efg" after host`), + expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `provided port is not a number: 12efg; host contains a scheme, which is not allowed: https://example.com:80`), + }, + { + desc: "port out of range", + cfg: &Config{ + Targets: []*targetConfig{ + { + Host: "www.opentelemetry.io:67000", + }, + }, + ControllerConfig: scraperhelper.NewDefaultControllerConfig(), + }, + expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `provided port is out of valid range (1-65535): 67000`), }, { desc: "missing scheme", cfg: &Config{ Targets: []*targetConfig{ { - URL: "www.opentelemetry.io/docs", + Host: "www.opentelemetry.io/docs", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "www.opentelemetry.io/docs": invalid URI for request`), + expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `address www.opentelemetry.io/docs: missing port in address`), }, { desc: "valid config", cfg: &Config{ Targets: []*targetConfig{ { - URL: "https://opentelemetry.io", + Host: "opentelemetry.io:443", + }, + { + Host: "opentelemetry.io:8080", }, { - URL: "https://opentelemetry.io:80/docs", + Host: "111.222.33.44:10000", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), diff --git a/receiver/tlscheckreceiver/documentation.md b/receiver/tlscheckreceiver/documentation.md index 1b0d5e7e5cf6..cccf198f3681 100644 --- a/receiver/tlscheckreceiver/documentation.md +++ b/receiver/tlscheckreceiver/documentation.md @@ -26,9 +26,4 @@ Time in seconds until certificate expiry, as specified by `NotAfter` field in th | ---- | ----------- | ------ | | tlscheck.x509.issuer | The entity that issued the certificate. | Any Str | | tlscheck.x509.cn | The commonName in the subject of the certificate. | Any Str | - -## Resource Attributes - -| Name | Description | Values | Enabled | -| ---- | ----------- | ------ | ------- | -| tlscheck.url | Url at which the certificate was accessed. | Any Str | true | +| tlscheck.host | Host at which the certificate was accessed. | Any Str | diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index bc99c145abf7..7433fe4afdc4 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -6,6 +6,7 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll import ( "context" "errors" + "time" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" @@ -19,7 +20,6 @@ var ( errConfigNotTLSCheck = errors.New(`invalid config`) ) -// NewFactory creates a new filestats receiver factory. func NewFactory() receiver.Factory { return receiver.NewFactory( metadata.Type, @@ -28,8 +28,11 @@ func NewFactory() receiver.Factory { } func newDefaultConfig() component.Config { + cfg := scraperhelper.NewDefaultControllerConfig() + cfg.CollectionInterval = 60 * time.Second + return &Config{ - ControllerConfig: scraperhelper.NewDefaultControllerConfig(), + ControllerConfig: cfg, MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), Targets: []*targetConfig{}, } @@ -46,7 +49,7 @@ func newReceiver( return nil, errConfigNotTLSCheck } - mp := newScraper(tlsCheckConfig, settings) + mp := newScraper(tlsCheckConfig, settings, getConnectionState) s, err := scraperhelper.NewScraper(metadata.Type, mp.scrape) if err != nil { return nil, err diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 30e7601ee72a..e9b9accfb1f9 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -9,7 +9,6 @@ require ( go.opentelemetry.io/collector/confmap v1.17.1-0.20241008154146-ea48c09c31ae go.opentelemetry.io/collector/consumer v0.111.1-0.20241008154146-ea48c09c31ae go.opentelemetry.io/collector/consumer/consumertest v0.111.1-0.20241008154146-ea48c09c31ae - go.opentelemetry.io/collector/filter v0.111.1-0.20241008154146-ea48c09c31ae go.opentelemetry.io/collector/pdata v1.17.1-0.20241008154146-ea48c09c31ae go.opentelemetry.io/collector/receiver v0.111.1-0.20241008154146-ea48c09c31ae go.uber.org/goleak v1.3.0 diff --git a/receiver/tlscheckreceiver/go.sum b/receiver/tlscheckreceiver/go.sum index 968b2bb483d2..b2d1f7ab2c0f 100644 --- a/receiver/tlscheckreceiver/go.sum +++ b/receiver/tlscheckreceiver/go.sum @@ -60,8 +60,6 @@ go.opentelemetry.io/collector/consumer/consumerprofiles v0.111.1-0.2024100815414 go.opentelemetry.io/collector/consumer/consumerprofiles v0.111.1-0.20241008154146-ea48c09c31ae/go.mod h1:GK0QMMiRBWl4IhIF/7ZKgzBlR9SdRSpRlqyNInN4ZoU= go.opentelemetry.io/collector/consumer/consumertest v0.111.1-0.20241008154146-ea48c09c31ae h1:HFj6D19fJYm3KV8QidQmMApmLjzoNkzh8El5OkTGySo= go.opentelemetry.io/collector/consumer/consumertest v0.111.1-0.20241008154146-ea48c09c31ae/go.mod h1:UDZRrSgaFAwWO6I34fj0KjabVAuBCAnmizsleyIe3I4= -go.opentelemetry.io/collector/filter v0.111.1-0.20241008154146-ea48c09c31ae h1:fLRV9bU33PJWQ/eZCwzfKdV0I9ljhP84Zoq9+tBhcLU= -go.opentelemetry.io/collector/filter v0.111.1-0.20241008154146-ea48c09c31ae/go.mod h1:74Acew42eexKiuLu3tVehyMK4b5XJPWXoJyNjK2FM+U= go.opentelemetry.io/collector/internal/globalsignal v0.111.0 h1:oq0nSD+7K2Q1Fx5d3s6lPRdKZeTL0FEg4sIaR7ZJzIc= go.opentelemetry.io/collector/internal/globalsignal v0.111.0/go.mod h1:GqMXodPWOxK5uqpX8MaMXC2389y2XJTa5nPwf8FYDK8= go.opentelemetry.io/collector/pdata v1.17.1-0.20241008154146-ea48c09c31ae h1:PcwZe1RD8tC4SZExhf0f5HqK+ZuWGsowHaBBU4PiUv0= diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_config.go b/receiver/tlscheckreceiver/internal/metadata/generated_config.go index 96e738301b15..a3a498b525c1 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_config.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_config.go @@ -4,7 +4,6 @@ package metadata import ( "go.opentelemetry.io/collector/confmap" - "go.opentelemetry.io/collector/filter" ) // MetricConfig provides common config for a particular metric. @@ -39,54 +38,13 @@ func DefaultMetricsConfig() MetricsConfig { } } -// ResourceAttributeConfig provides common config for a particular resource attribute. -type ResourceAttributeConfig struct { - Enabled bool `mapstructure:"enabled"` - // Experimental: MetricsInclude defines a list of filters for attribute values. - // If the list is not empty, only metrics with matching resource attribute values will be emitted. - MetricsInclude []filter.Config `mapstructure:"metrics_include"` - // Experimental: MetricsExclude defines a list of filters for attribute values. - // If the list is not empty, metrics with matching resource attribute values will not be emitted. - // MetricsInclude has higher priority than MetricsExclude. - MetricsExclude []filter.Config `mapstructure:"metrics_exclude"` - - enabledSetByUser bool -} - -func (rac *ResourceAttributeConfig) Unmarshal(parser *confmap.Conf) error { - if parser == nil { - return nil - } - err := parser.Unmarshal(rac) - if err != nil { - return err - } - rac.enabledSetByUser = parser.IsSet("enabled") - return nil -} - -// ResourceAttributesConfig provides config for tlscheck resource attributes. -type ResourceAttributesConfig struct { - TlscheckURL ResourceAttributeConfig `mapstructure:"tlscheck.url"` -} - -func DefaultResourceAttributesConfig() ResourceAttributesConfig { - return ResourceAttributesConfig{ - TlscheckURL: ResourceAttributeConfig{ - Enabled: true, - }, - } -} - // MetricsBuilderConfig is a configuration for tlscheck metrics builder. type MetricsBuilderConfig struct { - Metrics MetricsConfig `mapstructure:"metrics"` - ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` + Metrics MetricsConfig `mapstructure:"metrics"` } func DefaultMetricsBuilderConfig() MetricsBuilderConfig { return MetricsBuilderConfig{ - Metrics: DefaultMetricsConfig(), - ResourceAttributes: DefaultResourceAttributesConfig(), + Metrics: DefaultMetricsConfig(), } } diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_config_test.go b/receiver/tlscheckreceiver/internal/metadata/generated_config_test.go index 7c84015ab981..fa7e3f38c50d 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_config_test.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_config_test.go @@ -27,9 +27,6 @@ func TestMetricsBuilderConfig(t *testing.T) { Metrics: MetricsConfig{ TlscheckTimeLeft: MetricConfig{Enabled: true}, }, - ResourceAttributes: ResourceAttributesConfig{ - TlscheckURL: ResourceAttributeConfig{Enabled: true}, - }, }, }, { @@ -38,16 +35,13 @@ func TestMetricsBuilderConfig(t *testing.T) { Metrics: MetricsConfig{ TlscheckTimeLeft: MetricConfig{Enabled: false}, }, - ResourceAttributes: ResourceAttributesConfig{ - TlscheckURL: ResourceAttributeConfig{Enabled: false}, - }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := loadMetricsBuilderConfig(t, tt.name) - if diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})); diff != "" { + if diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{})); diff != "" { t.Errorf("Config mismatch (-expected +actual):\n%s", diff) } }) @@ -63,47 +57,3 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, sub.Unmarshal(&cfg)) return cfg } - -func TestResourceAttributesConfig(t *testing.T) { - tests := []struct { - name string - want ResourceAttributesConfig - }{ - { - name: "default", - want: DefaultResourceAttributesConfig(), - }, - { - name: "all_set", - want: ResourceAttributesConfig{ - TlscheckURL: ResourceAttributeConfig{Enabled: true}, - }, - }, - { - name: "none_set", - want: ResourceAttributesConfig{ - TlscheckURL: ResourceAttributeConfig{Enabled: false}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cfg := loadResourceAttributesConfig(t, tt.name) - if diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(ResourceAttributeConfig{})); diff != "" { - t.Errorf("Config mismatch (-expected +actual):\n%s", diff) - } - }) - } -} - -func loadResourceAttributesConfig(t *testing.T, name string) ResourceAttributesConfig { - cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) - require.NoError(t, err) - sub, err := cm.Sub(name) - require.NoError(t, err) - sub, err = sub.Sub("resource_attributes") - require.NoError(t, err) - cfg := DefaultResourceAttributesConfig() - require.NoError(t, sub.Unmarshal(&cfg)) - return cfg -} diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go b/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go index 988cf4f1cdcb..7aa27a53bfaf 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go @@ -6,7 +6,6 @@ import ( "time" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/filter" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver" @@ -27,7 +26,7 @@ func (m *metricTlscheckTimeLeft) init() { m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) } -func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string) { +func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckHostAttributeValue string) { if !m.config.Enabled { return } @@ -37,6 +36,7 @@ func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pco dp.SetIntValue(val) dp.Attributes().PutStr("tlscheck.x509.issuer", tlscheckX509IssuerAttributeValue) dp.Attributes().PutStr("tlscheck.x509.cn", tlscheckX509CnAttributeValue) + dp.Attributes().PutStr("tlscheck.host", tlscheckHostAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -67,14 +67,12 @@ func newMetricTlscheckTimeLeft(cfg MetricConfig) metricTlscheckTimeLeft { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - config MetricsBuilderConfig // config of the metrics builder. - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information. - resourceAttributeIncludeFilter map[string]filter.Filter - resourceAttributeExcludeFilter map[string]filter.Filter - metricTlscheckTimeLeft metricTlscheckTimeLeft + config MetricsBuilderConfig // config of the metrics builder. + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information. + metricTlscheckTimeLeft metricTlscheckTimeLeft } // MetricBuilderOption applies changes to default metrics builder. @@ -97,19 +95,11 @@ func WithStartTime(startTime pcommon.Timestamp) MetricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...MetricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - config: mbc, - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - metricTlscheckTimeLeft: newMetricTlscheckTimeLeft(mbc.Metrics.TlscheckTimeLeft), - resourceAttributeIncludeFilter: make(map[string]filter.Filter), - resourceAttributeExcludeFilter: make(map[string]filter.Filter), - } - if mbc.ResourceAttributes.TlscheckURL.MetricsInclude != nil { - mb.resourceAttributeIncludeFilter["tlscheck.url"] = filter.CreateFilter(mbc.ResourceAttributes.TlscheckURL.MetricsInclude) - } - if mbc.ResourceAttributes.TlscheckURL.MetricsExclude != nil { - mb.resourceAttributeExcludeFilter["tlscheck.url"] = filter.CreateFilter(mbc.ResourceAttributes.TlscheckURL.MetricsExclude) + config: mbc, + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricTlscheckTimeLeft: newMetricTlscheckTimeLeft(mbc.Metrics.TlscheckTimeLeft), } for _, op := range options { @@ -118,11 +108,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt return mb } -// NewResourceBuilder returns a new resource builder that should be used to build a resource associated with for the emitted metrics. -func (mb *MetricsBuilder) NewResourceBuilder() *ResourceBuilder { - return NewResourceBuilder(mb.config.ResourceAttributes) -} - // updateCapacity updates max length of metrics and resource attributes that will be used for the slice capacity. func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { @@ -185,16 +170,6 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { for _, op := range options { op.apply(rm) } - for attr, filter := range mb.resourceAttributeIncludeFilter { - if val, ok := rm.Resource().Attributes().Get(attr); ok && !filter.Matches(val.AsString()) { - return - } - } - for attr, filter := range mb.resourceAttributeExcludeFilter { - if val, ok := rm.Resource().Attributes().Get(attr); ok && filter.Matches(val.AsString()) { - return - } - } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) @@ -213,8 +188,8 @@ func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics } // RecordTlscheckTimeLeftDataPoint adds a data point to tlscheck.time_left metric. -func (mb *MetricsBuilder) RecordTlscheckTimeLeftDataPoint(ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string) { - mb.metricTlscheckTimeLeft.recordDataPoint(mb.startTime, ts, val, tlscheckX509IssuerAttributeValue, tlscheckX509CnAttributeValue) +func (mb *MetricsBuilder) RecordTlscheckTimeLeftDataPoint(ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckHostAttributeValue string) { + mb.metricTlscheckTimeLeft.recordDataPoint(mb.startTime, ts, val, tlscheckX509IssuerAttributeValue, tlscheckX509CnAttributeValue, tlscheckHostAttributeValue) } // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go b/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go index b81713f24b82..5c37211d987f 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go @@ -42,15 +42,6 @@ func TestMetricsBuilder(t *testing.T) { resAttrsSet: testDataSetNone, expectEmpty: true, }, - { - name: "filter_set_include", - resAttrsSet: testDataSetAll, - }, - { - name: "filter_set_exclude", - resAttrsSet: testDataSetAll, - expectEmpty: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -70,11 +61,9 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ - mb.RecordTlscheckTimeLeftDataPoint(ts, 1, "tlscheck.x509.issuer-val", "tlscheck.x509.cn-val") + mb.RecordTlscheckTimeLeftDataPoint(ts, 1, "tlscheck.x509.issuer-val", "tlscheck.x509.cn-val", "tlscheck.host-val") - rb := mb.NewResourceBuilder() - rb.SetTlscheckURL("tlscheck.url-val") - res := rb.Emit() + res := pcommon.NewResource() metrics := mb.Emit(WithResource(res)) if tt.expectEmpty { @@ -114,6 +103,9 @@ func TestMetricsBuilder(t *testing.T) { attrVal, ok = dp.Attributes().Get("tlscheck.x509.cn") assert.True(t, ok) assert.EqualValues(t, "tlscheck.x509.cn-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("tlscheck.host") + assert.True(t, ok) + assert.EqualValues(t, "tlscheck.host-val", attrVal.Str()) } } }) diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_resource.go b/receiver/tlscheckreceiver/internal/metadata/generated_resource.go deleted file mode 100644 index e51961b1db39..000000000000 --- a/receiver/tlscheckreceiver/internal/metadata/generated_resource.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by mdatagen. DO NOT EDIT. - -package metadata - -import ( - "go.opentelemetry.io/collector/pdata/pcommon" -) - -// ResourceBuilder is a helper struct to build resources predefined in metadata.yaml. -// The ResourceBuilder is not thread-safe and must not to be used in multiple goroutines. -type ResourceBuilder struct { - config ResourceAttributesConfig - res pcommon.Resource -} - -// NewResourceBuilder creates a new ResourceBuilder. This method should be called on the start of the application. -func NewResourceBuilder(rac ResourceAttributesConfig) *ResourceBuilder { - return &ResourceBuilder{ - config: rac, - res: pcommon.NewResource(), - } -} - -// SetTlscheckURL sets provided value as "tlscheck.url" attribute. -func (rb *ResourceBuilder) SetTlscheckURL(val string) { - if rb.config.TlscheckURL.Enabled { - rb.res.Attributes().PutStr("tlscheck.url", val) - } -} - -// Emit returns the built resource and resets the internal builder state. -func (rb *ResourceBuilder) Emit() pcommon.Resource { - r := rb.res - rb.res = pcommon.NewResource() - return r -} diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_resource_test.go b/receiver/tlscheckreceiver/internal/metadata/generated_resource_test.go deleted file mode 100644 index 4a67d0fd5ad5..000000000000 --- a/receiver/tlscheckreceiver/internal/metadata/generated_resource_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by mdatagen. DO NOT EDIT. - -package metadata - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestResourceBuilder(t *testing.T) { - for _, tt := range []string{"default", "all_set", "none_set"} { - t.Run(tt, func(t *testing.T) { - cfg := loadResourceAttributesConfig(t, tt) - rb := NewResourceBuilder(cfg) - rb.SetTlscheckURL("tlscheck.url-val") - - res := rb.Emit() - assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return empty Resource - - switch tt { - case "default": - assert.Equal(t, 1, res.Attributes().Len()) - case "all_set": - assert.Equal(t, 1, res.Attributes().Len()) - case "none_set": - assert.Equal(t, 0, res.Attributes().Len()) - return - default: - assert.Failf(t, "unexpected test case: %s", tt) - } - - val, ok := res.Attributes().Get("tlscheck.url") - assert.True(t, ok) - if ok { - assert.EqualValues(t, "tlscheck.url-val", val.Str()) - } - }) - } -} diff --git a/receiver/tlscheckreceiver/internal/metadata/testdata/config.yaml b/receiver/tlscheckreceiver/internal/metadata/testdata/config.yaml index 7dc13e51f71c..b8974d99aa9d 100644 --- a/receiver/tlscheckreceiver/internal/metadata/testdata/config.yaml +++ b/receiver/tlscheckreceiver/internal/metadata/testdata/config.yaml @@ -3,25 +3,7 @@ all_set: metrics: tlscheck.time_left: enabled: true - resource_attributes: - tlscheck.url: - enabled: true none_set: metrics: tlscheck.time_left: enabled: false - resource_attributes: - tlscheck.url: - enabled: false -filter_set_include: - resource_attributes: - tlscheck.url: - enabled: true - metrics_include: - - regexp: ".*" -filter_set_exclude: - resource_attributes: - tlscheck.url: - enabled: true - metrics_exclude: - - strict: "tlscheck.url-val" diff --git a/receiver/tlscheckreceiver/metadata.yaml b/receiver/tlscheckreceiver/metadata.yaml index 843444b4c35f..c5cad04d1a24 100644 --- a/receiver/tlscheckreceiver/metadata.yaml +++ b/receiver/tlscheckreceiver/metadata.yaml @@ -8,14 +8,13 @@ status: codeowners: active: [atoulme, michael-burt] - resource_attributes: - tlscheck.url: - enabled: true - description: Url at which the certificate was accessed. - type: string attributes: + tlscheck.host: + enabled: true + description: Host at which the certificate was accessed. + type: string tlscheck.x509.issuer: enabled: true description: The entity that issued the certificate. @@ -32,4 +31,4 @@ metrics: gauge: value_type: int unit: "s" - attributes: [tlscheck.x509.issuer, tlscheck.x509.cn] \ No newline at end of file + attributes: [tlscheck.x509.issuer, tlscheck.x509.cn, tlscheck.host] \ No newline at end of file diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index c4807cc78eff..6e1580a54a3b 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -5,7 +5,13 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll import ( "context" + "crypto/tls" + "errors" + "sync" + "time" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver" "go.uber.org/zap" @@ -13,19 +19,71 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) +var ( + ErrMissingTargets = errors.New(`No targets specified`) +) + type scraper struct { - // include string - logger *zap.Logger - mb *metadata.MetricsBuilder + cfg *Config + settings component.TelemetrySettings + mb *metadata.MetricsBuilder + getConnectionState func(host string) (tls.ConnectionState, error) +} + +func getConnectionState(host string) (tls.ConnectionState, error) { + conn, err := tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return tls.ConnectionState{}, err + } + defer conn.Close() + return conn.ConnectionState(), nil } func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { - return pmetric.NewMetrics(), nil + if s.cfg == nil || len(s.cfg.Targets) == 0 { + return pmetric.NewMetrics(), ErrMissingTargets + } + + var wg sync.WaitGroup + wg.Add(len(s.cfg.Targets)) + var mux sync.Mutex + for _, target := range s.cfg.Targets { + go func(host string) { + defer wg.Done() + + now := pcommon.NewTimestampFromTime(time.Now()) + mux.Lock() + state, err := s.getConnectionState(target.Host) + if err != nil { + s.settings.Logger.Error("TCP connection error encountered", zap.String("host", target.Host), zap.Error(err)) + } + + s.settings.Logger.Error("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) + if len(state.PeerCertificates) == 0 { + s.settings.Logger.Error("No TLS certificates found. Verify the host serves TLS certificates.", zap.String("host", target.Host)) + } + + cert := state.PeerCertificates[0] + issuer := cert.Issuer.String() + commonName := cert.Subject.CommonName + currentTime := time.Now() + timeLeft := cert.NotAfter.Sub(currentTime).Seconds() + timeLeftInt := int64(timeLeft) + s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName, host) + mux.Unlock() + + }(target.Host) + } + + wg.Wait() + return s.mb.Emit(), nil } -func newScraper(cfg *Config, settings receiver.Settings) *scraper { +func newScraper(cfg *Config, settings receiver.Settings, getConnectionState func(host string) (tls.ConnectionState, error)) *scraper { return &scraper{ - logger: settings.TelemetrySettings.Logger, - mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), + cfg: cfg, + settings: settings.TelemetrySettings, + mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), settings), + getConnectionState: getConnectionState, } } diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go new file mode 100644 index 000000000000..9cd92270df11 --- /dev/null +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -0,0 +1,143 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package tlscheckreceiver + +import ( + "context" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func mockGetConnectionStateValid(host string) (tls.ConnectionState, error) { + cert := &x509.Certificate{ + NotBefore: time.Now().Add(-1 * time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + Subject: pkix.Name{CommonName: "valid.com"}, + Issuer: pkix.Name{CommonName: "ValidIssuer"}, + } + return tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{cert}, + }, nil +} + +func mockGetConnectionStateExpired(host string) (tls.ConnectionState, error) { + cert := &x509.Certificate{ + NotBefore: time.Now().Add(-48 * time.Hour), + NotAfter: time.Now().Add(-24 * time.Hour), + Subject: pkix.Name{CommonName: "expired.com"}, + Issuer: pkix.Name{CommonName: "ExpiredIssuer"}, + } + return tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{cert}, + }, nil +} + +func mockGetConnectionStateNotYetValid(host string) (tls.ConnectionState, error) { + cert := &x509.Certificate{ + NotBefore: time.Now().Add(48 * time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + Subject: pkix.Name{CommonName: "notyetvalid.com"}, + Issuer: pkix.Name{CommonName: "NotYetValidIssuer"}, + } + return tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{cert}, + }, nil +} + +func TestScrape_ValidCertificate(t *testing.T) { + cfg := &Config{ + Targets: []*targetConfig{ + {Host: "example.com:443"}, + }, + } + settings := receivertest.NewNopSettings() + s := newScraper(cfg, settings, mockGetConnectionStateValid) + + metrics, err := s.scrape(context.Background()) + require.NoError(t, err) + + assert.Equal(t, 1, metrics.DataPointCount()) + + rm := metrics.ResourceMetrics().At(0) + ilms := rm.ScopeMetrics().At(0) + metric := ilms.Metrics().At(0) + dp := metric.Gauge().DataPoints().At(0) + + attributes := dp.Attributes() + issuer, _ := attributes.Get("tlscheck.x509.issuer") + commonName, _ := attributes.Get("tlscheck.x509.cn") + + assert.Equal(t, "CN=ValidIssuer", issuer.AsString()) + assert.Equal(t, "valid.com", commonName.AsString()) +} + +func TestScrape_ExpiredCertificate(t *testing.T) { + cfg := &Config{ + Targets: []*targetConfig{ + {Host: "expired.com:443"}, + }, + } + settings := receivertest.NewNopSettings() + s := newScraper(cfg, settings, mockGetConnectionStateExpired) + + metrics, err := s.scrape(context.Background()) + require.NoError(t, err) + + assert.Equal(t, 1, metrics.DataPointCount()) + + rm := metrics.ResourceMetrics().At(0) + ilms := rm.ScopeMetrics().At(0) + metric := ilms.Metrics().At(0) + dp := metric.Gauge().DataPoints().At(0) + + attributes := dp.Attributes() + issuer, _ := attributes.Get("tlscheck.x509.issuer") + commonName, _ := attributes.Get("tlscheck.x509.cn") + + assert.Equal(t, "CN=ExpiredIssuer", issuer.AsString()) + assert.Equal(t, "expired.com", commonName.AsString()) + + // Ensure that timeLeft is negative for an expired cert + timeLeft := dp.IntValue() + assert.Less(t, timeLeft, int64(0), "Time left should be negative for an expired certificate") +} + +func TestScrape_NotYetValidCertificate(t *testing.T) { + cfg := &Config{ + Targets: []*targetConfig{ + {Host: "expired.com:443"}, + }, + } + settings := receivertest.NewNopSettings() + s := newScraper(cfg, settings, mockGetConnectionStateNotYetValid) + + metrics, err := s.scrape(context.Background()) + require.NoError(t, err) + + assert.Equal(t, 1, metrics.DataPointCount()) + + rm := metrics.ResourceMetrics().At(0) + ilms := rm.ScopeMetrics().At(0) + metric := ilms.Metrics().At(0) + dp := metric.Gauge().DataPoints().At(0) + + attributes := dp.Attributes() + issuer, _ := attributes.Get("tlscheck.x509.issuer") + commonName, _ := attributes.Get("tlscheck.x509.cn") + + assert.Equal(t, "CN=NotYetValidIssuer", issuer.AsString()) + assert.Equal(t, "notyetvalid.com", commonName.AsString()) + + // Ensure that timeLeft is positive for a not-yet-valid cert + timeLeft := dp.IntValue() + assert.Greater(t, timeLeft, int64(0), "Time left should be positive for a not-yet-valid cert") +} From d032cbf2ed361c7cccd9276f6d15d1b64f7d7da9 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Tue, 22 Oct 2024 22:14:38 -0600 Subject: [PATCH 02/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/scraper_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go index 9cd92270df11..304240166e81 100644 --- a/receiver/tlscheckreceiver/scraper_test.go +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -17,6 +17,7 @@ import ( "go.opentelemetry.io/collector/receiver/receivertest" ) +//nolint:revive func mockGetConnectionStateValid(host string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(-1 * time.Hour), @@ -29,6 +30,7 @@ func mockGetConnectionStateValid(host string) (tls.ConnectionState, error) { }, nil } +//nolint:revive func mockGetConnectionStateExpired(host string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(-48 * time.Hour), @@ -41,6 +43,7 @@ func mockGetConnectionStateExpired(host string) (tls.ConnectionState, error) { }, nil } +//nolint:revive func mockGetConnectionStateNotYetValid(host string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(48 * time.Hour), From df87bdb7d142d80639ca76be508562e87b590929 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Tue, 22 Oct 2024 22:29:22 -0600 Subject: [PATCH 03/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/scraper_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go index 304240166e81..fe6291331a0f 100644 --- a/receiver/tlscheckreceiver/scraper_test.go +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -111,7 +111,7 @@ func TestScrape_ExpiredCertificate(t *testing.T) { // Ensure that timeLeft is negative for an expired cert timeLeft := dp.IntValue() - assert.Less(t, timeLeft, int64(0), "Time left should be negative for an expired certificate") + assert.Negative(t, timeLeft, int64(0), "Time left should be negative for an expired certificate") } func TestScrape_NotYetValidCertificate(t *testing.T) { @@ -142,5 +142,5 @@ func TestScrape_NotYetValidCertificate(t *testing.T) { // Ensure that timeLeft is positive for a not-yet-valid cert timeLeft := dp.IntValue() - assert.Greater(t, timeLeft, int64(0), "Time left should be positive for a not-yet-valid cert") + assert.Positive(t, timeLeft, "Time left should be positive for a not-yet-valid cert") } From 9f0718d7a36fad851566b11899e8bc3c169748cc Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Tue, 22 Oct 2024 22:49:46 -0600 Subject: [PATCH 04/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/scraper_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go index fe6291331a0f..6b4dacc6a888 100644 --- a/receiver/tlscheckreceiver/scraper_test.go +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -8,7 +8,6 @@ import ( "crypto/tls" "crypto/x509" "crypto/x509/pkix" - "testing" "time" From e6e627d398e6d82cb7bffe4b97a66a59873779c1 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 24 Oct 2024 14:27:40 -0600 Subject: [PATCH 05/20] use confignet tcp client --- receiver/tlscheckreceiver/README.md | 11 ++++- receiver/tlscheckreceiver/config.go | 24 +++++----- receiver/tlscheckreceiver/config_test.go | 56 ++++++++++++++--------- receiver/tlscheckreceiver/factory.go | 3 +- receiver/tlscheckreceiver/factory_test.go | 3 +- receiver/tlscheckreceiver/go.mod | 1 + receiver/tlscheckreceiver/go.sum | 2 + receiver/tlscheckreceiver/scraper.go | 8 ++-- receiver/tlscheckreceiver/scraper_test.go | 13 +++--- 9 files changed, 75 insertions(+), 46 deletions(-) diff --git a/receiver/tlscheckreceiver/README.md b/receiver/tlscheckreceiver/README.md index a5b617719c95..432ba6c6d4fd 100644 --- a/receiver/tlscheckreceiver/README.md +++ b/receiver/tlscheckreceiver/README.md @@ -20,12 +20,19 @@ By default, the TLS Check Receiver will emit a single metric, `tlscheck.time_lef ## Example Configuration +Targets are + ```yaml receivers: tlscheck: targets: - - host: example.com:443 - - host: foobar.com:8080 + - endpoint: example.com:443 + dialer: + timeout: 15s + - endpoint: foobar.com:8080 + dialer: + timeout: 15s + - endpoint: localhost:10901 ``` ## Certificate Verification diff --git a/receiver/tlscheckreceiver/config.go b/receiver/tlscheckreceiver/config.go index dae86fc0ce94..3fb7c56a28ea 100644 --- a/receiver/tlscheckreceiver/config.go +++ b/receiver/tlscheckreceiver/config.go @@ -10,6 +10,8 @@ import ( "strconv" "strings" + "go.opentelemetry.io/collector/config/confignet" + "go.opentelemetry.io/collector/receiver/scraperhelper" "go.uber.org/multierr" @@ -18,18 +20,18 @@ import ( // Predefined error responses for configuration validation failures var ( - errInvalidHost = errors.New(`"host" must be in the form of :`) + errInvalidEndpoint = errors.New(`"host" must be in the form of :`) ) // Config defines the configuration for the various elements of the receiver agent. type Config struct { scraperhelper.ControllerConfig `mapstructure:",squash"` metadata.MetricsBuilderConfig `mapstructure:",squash"` - Targets []*targetConfig `mapstructure:"targets"` + Targets []*confignet.TCPAddrConfig `mapstructure:"targets"` } type targetConfig struct { - Host string `mapstructure:"host"` + confignet.TCPAddrConfig `mapstructure:",squash"` } func validatePort(port string) error { @@ -43,25 +45,25 @@ func validatePort(port string) error { return nil } -func (cfg *targetConfig) Validate() error { +func ValidateTarget(cfg *confignet.TCPAddrConfig) error { var err error - if cfg.Host == "" { + if cfg.Endpoint == "" { return ErrMissingTargets } - if strings.Contains(cfg.Host, "://") { - return fmt.Errorf("host contains a scheme, which is not allowed: %s", cfg.Host) + if strings.Contains(cfg.Endpoint, "://") { + return fmt.Errorf("host contains a scheme, which is not allowed: %s", cfg.Endpoint) } - _, port, parseErr := net.SplitHostPort(cfg.Host) + _, port, parseErr := net.SplitHostPort(cfg.Endpoint) if parseErr != nil { - return fmt.Errorf("%s: %w", errInvalidHost.Error(), parseErr) + return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), parseErr) } portParseErr := validatePort(port) if portParseErr != nil { - return fmt.Errorf("%s: %w", errInvalidHost.Error(), portParseErr) + return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), portParseErr) } return err @@ -75,7 +77,7 @@ func (cfg *Config) Validate() error { } for _, target := range cfg.Targets { - err = multierr.Append(err, target.Validate()) + err = multierr.Append(err, ValidateTarget(target)) } return err diff --git a/receiver/tlscheckreceiver/config_test.go b/receiver/tlscheckreceiver/config_test.go index e3fa89c0d877..47f62ca33814 100644 --- a/receiver/tlscheckreceiver/config_test.go +++ b/receiver/tlscheckreceiver/config_test.go @@ -6,8 +6,10 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll import ( "fmt" "testing" + "time" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/receiver/scraperhelper" ) @@ -18,76 +20,88 @@ func TestValidate(t *testing.T) { expectedErr error }{ { - desc: "missing url", + desc: "missing targets", cfg: &Config{ - Targets: []*targetConfig{}, + Targets: []*confignet.TCPAddrConfig{}, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, expectedErr: ErrMissingTargets, }, { - desc: "invalid host", + desc: "invalid endpoint", cfg: &Config{ - Targets: []*targetConfig{ + Targets: []*confignet.TCPAddrConfig{ { - Host: "endpoint: 12efg", + Endpoint: "bad-endpoint: 12efg", + DialerConfig: confignet.DialerConfig{ + Timeout: 12 * time.Second, + }, }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidHost, "provided port is not a number: 12efg"), + expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, "provided port is not a number: 12efg"), }, { desc: "invalid config with multiple targets", cfg: &Config{ - Targets: []*targetConfig{ + Targets: []*confignet.TCPAddrConfig{ { - Host: "endpoint: 12efg", + Endpoint: "endpoint: 12efg", }, { - Host: "https://example.com:80", + Endpoint: "https://example.com:80", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `provided port is not a number: 12efg; host contains a scheme, which is not allowed: https://example.com:80`), + expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is not a number: 12efg; host contains a scheme, which is not allowed: https://example.com:80`), }, { desc: "port out of range", cfg: &Config{ - Targets: []*targetConfig{ + Targets: []*confignet.TCPAddrConfig{ { - Host: "www.opentelemetry.io:67000", + Endpoint: "www.opentelemetry.io:67000", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `provided port is out of valid range (1-65535): 67000`), + expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is out of valid range (1-65535): 67000`), }, { - desc: "missing scheme", + desc: "missing port", cfg: &Config{ - Targets: []*targetConfig{ + Targets: []*confignet.TCPAddrConfig{ { - Host: "www.opentelemetry.io/docs", + Endpoint: "www.opentelemetry.io/docs", }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidHost, `address www.opentelemetry.io/docs: missing port in address`), + expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `address www.opentelemetry.io/docs: missing port in address`), }, { desc: "valid config", cfg: &Config{ - Targets: []*targetConfig{ + Targets: []*confignet.TCPAddrConfig{ { - Host: "opentelemetry.io:443", + Endpoint: "opentelemetry.io:443", + DialerConfig: confignet.DialerConfig{ + Timeout: 3 * time.Second, + }, }, { - Host: "opentelemetry.io:8080", + Endpoint: "opentelemetry.io:8080", + DialerConfig: confignet.DialerConfig{ + Timeout: 1 * time.Second, + }, }, { - Host: "111.222.33.44:10000", + Endpoint: "111.222.33.44:10000", + DialerConfig: confignet.DialerConfig{ + Timeout: 5 * time.Second, + }, }, }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 7433fe4afdc4..4ec669dca6aa 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -9,6 +9,7 @@ import ( "time" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -34,7 +35,7 @@ func newDefaultConfig() component.Config { return &Config{ ControllerConfig: cfg, MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), - Targets: []*targetConfig{}, + Targets: []*confignet.TCPAddrConfig{}, } } diff --git a/receiver/tlscheckreceiver/factory_test.go b/receiver/tlscheckreceiver/factory_test.go index 2ca0e3d0ff0c..b3ee353e8345 100644 --- a/receiver/tlscheckreceiver/factory_test.go +++ b/receiver/tlscheckreceiver/factory_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver/receivertest" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -40,7 +41,7 @@ func TestNewFactory(t *testing.T) { InitialDelay: time.Second, }, MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), - Targets: []*targetConfig{}, + Targets: []*confignet.TCPAddrConfig{}, } require.Equal(t, expectedCfg, factory.CreateDefaultConfig()) diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 32914d5f8e4c..2ccd40eff9fa 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -33,6 +33,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect + go.opentelemetry.io/collector/config/confignet v1.18.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.112.0 // indirect go.opentelemetry.io/collector/consumer/consumererror v0.112.0 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.112.0 // indirect diff --git a/receiver/tlscheckreceiver/go.sum b/receiver/tlscheckreceiver/go.sum index 1dc41ade6fcf..82561eae675f 100644 --- a/receiver/tlscheckreceiver/go.sum +++ b/receiver/tlscheckreceiver/go.sum @@ -50,6 +50,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/collector/component v0.112.0 h1:Hw125Tdb427yKkzFx3U/OsfPATYXsbURkc27dn19he8= go.opentelemetry.io/collector/component v0.112.0/go.mod h1:hV9PEgkNlVAySX+Oo/g7+NcLe234L04kRXw6uGj3VEw= +go.opentelemetry.io/collector/config/confignet v1.18.0 h1:ncaBuvH/AxwXk1JgGVpKObGtR105qxgGWqsA6aqsYXc= +go.opentelemetry.io/collector/config/confignet v1.18.0/go.mod h1:o3v4joAEjvLwntqexg5ixMqRrU1+Vst+jWuCUaBNgOg= go.opentelemetry.io/collector/config/configtelemetry v0.112.0 h1:MVBrWJUoqfKrORI38dY8OV0i5d1RRHR/ACIBu9TOcZ8= go.opentelemetry.io/collector/config/configtelemetry v0.112.0/go.mod h1:R0MBUxjSMVMIhljuDHWIygzzJWQyZHXXWIgQNxcFwhc= go.opentelemetry.io/collector/confmap v1.18.0 h1:UEOeJY8RW8lZ1O4lzHSGqolS7uzkpXQi5fa8SidKqQg= diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index 6e1580a54a3b..a951f562e5b5 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -53,14 +53,14 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { now := pcommon.NewTimestampFromTime(time.Now()) mux.Lock() - state, err := s.getConnectionState(target.Host) + state, err := s.getConnectionState(target.Endpoint) if err != nil { - s.settings.Logger.Error("TCP connection error encountered", zap.String("host", target.Host), zap.Error(err)) + s.settings.Logger.Error("TCP connection error encountered", zap.String("host", target.Endpoint), zap.Error(err)) } s.settings.Logger.Error("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) if len(state.PeerCertificates) == 0 { - s.settings.Logger.Error("No TLS certificates found. Verify the host serves TLS certificates.", zap.String("host", target.Host)) + s.settings.Logger.Error("No TLS certificates found. Verify the host serves TLS certificates.", zap.String("host", target.Endpoint)) } cert := state.PeerCertificates[0] @@ -72,7 +72,7 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName, host) mux.Unlock() - }(target.Host) + }(target.Endpoint) } wg.Wait() diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go index 6b4dacc6a888..d9e986e868fc 100644 --- a/receiver/tlscheckreceiver/scraper_test.go +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/receiver/receivertest" ) @@ -57,8 +58,8 @@ func mockGetConnectionStateNotYetValid(host string) (tls.ConnectionState, error) func TestScrape_ValidCertificate(t *testing.T) { cfg := &Config{ - Targets: []*targetConfig{ - {Host: "example.com:443"}, + Targets: []*confignet.TCPAddrConfig{ + {Endpoint: "example.com:443"}, }, } settings := receivertest.NewNopSettings() @@ -84,8 +85,8 @@ func TestScrape_ValidCertificate(t *testing.T) { func TestScrape_ExpiredCertificate(t *testing.T) { cfg := &Config{ - Targets: []*targetConfig{ - {Host: "expired.com:443"}, + Targets: []*confignet.TCPAddrConfig{ + {Endpoint: "expired.com:443"}, }, } settings := receivertest.NewNopSettings() @@ -115,8 +116,8 @@ func TestScrape_ExpiredCertificate(t *testing.T) { func TestScrape_NotYetValidCertificate(t *testing.T) { cfg := &Config{ - Targets: []*targetConfig{ - {Host: "expired.com:443"}, + Targets: []*confignet.TCPAddrConfig{ + {Endpoint: "expired.com:443"}, }, } settings := receivertest.NewNopSettings() From 93ad3045a7047c93b48d619c58813043d3a72fba Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 24 Oct 2024 14:50:57 -0600 Subject: [PATCH 06/20] refactor scrape --- receiver/tlscheckreceiver/config.go | 8 +-- receiver/tlscheckreceiver/config_test.go | 2 +- receiver/tlscheckreceiver/documentation.md | 2 +- receiver/tlscheckreceiver/metadata.yaml | 6 +- receiver/tlscheckreceiver/scraper.go | 64 ++++++++++++---------- receiver/tlscheckreceiver/scraper_test.go | 6 +- 6 files changed, 45 insertions(+), 43 deletions(-) diff --git a/receiver/tlscheckreceiver/config.go b/receiver/tlscheckreceiver/config.go index 3fb7c56a28ea..5c859085628c 100644 --- a/receiver/tlscheckreceiver/config.go +++ b/receiver/tlscheckreceiver/config.go @@ -20,7 +20,7 @@ import ( // Predefined error responses for configuration validation failures var ( - errInvalidEndpoint = errors.New(`"host" must be in the form of :`) + errInvalidEndpoint = errors.New(`"endpoint" must be in the form of :`) ) // Config defines the configuration for the various elements of the receiver agent. @@ -30,10 +30,6 @@ type Config struct { Targets []*confignet.TCPAddrConfig `mapstructure:"targets"` } -type targetConfig struct { - confignet.TCPAddrConfig `mapstructure:",squash"` -} - func validatePort(port string) error { portNum, err := strconv.Atoi(port) if err != nil { @@ -53,7 +49,7 @@ func ValidateTarget(cfg *confignet.TCPAddrConfig) error { } if strings.Contains(cfg.Endpoint, "://") { - return fmt.Errorf("host contains a scheme, which is not allowed: %s", cfg.Endpoint) + return fmt.Errorf("endpoint contains a scheme, which is not allowed: %s", cfg.Endpoint) } _, port, parseErr := net.SplitHostPort(cfg.Endpoint) diff --git a/receiver/tlscheckreceiver/config_test.go b/receiver/tlscheckreceiver/config_test.go index 47f62ca33814..733476cde7c5 100644 --- a/receiver/tlscheckreceiver/config_test.go +++ b/receiver/tlscheckreceiver/config_test.go @@ -55,7 +55,7 @@ func TestValidate(t *testing.T) { }, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is not a number: 12efg; host contains a scheme, which is not allowed: https://example.com:80`), + 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", diff --git a/receiver/tlscheckreceiver/documentation.md b/receiver/tlscheckreceiver/documentation.md index cccf198f3681..e14b57ffb40c 100644 --- a/receiver/tlscheckreceiver/documentation.md +++ b/receiver/tlscheckreceiver/documentation.md @@ -26,4 +26,4 @@ Time in seconds until certificate expiry, as specified by `NotAfter` field in th | ---- | ----------- | ------ | | tlscheck.x509.issuer | The entity that issued the certificate. | Any Str | | tlscheck.x509.cn | The commonName in the subject of the certificate. | Any Str | -| tlscheck.host | Host at which the certificate was accessed. | Any Str | +| tlscheck.endpoint | Endpoint at which the certificate was accessed. | Any Str | diff --git a/receiver/tlscheckreceiver/metadata.yaml b/receiver/tlscheckreceiver/metadata.yaml index c5cad04d1a24..9b0366f2f85d 100644 --- a/receiver/tlscheckreceiver/metadata.yaml +++ b/receiver/tlscheckreceiver/metadata.yaml @@ -11,9 +11,9 @@ status: resource_attributes: attributes: - tlscheck.host: + tlscheck.endpo: enabled: true - description: Host at which the certificate was accessed. + description: Endpoint at which the certificate was accessed. type: string tlscheck.x509.issuer: enabled: true @@ -31,4 +31,4 @@ metrics: gauge: value_type: int unit: "s" - attributes: [tlscheck.x509.issuer, tlscheck.x509.cn, tlscheck.host] \ No newline at end of file + attributes: [tlscheck.x509.issuer, tlscheck.x509.cn, tlscheck.endpoint] \ No newline at end of file diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index a951f562e5b5..0df3cb150157 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -27,11 +27,11 @@ type scraper struct { cfg *Config settings component.TelemetrySettings mb *metadata.MetricsBuilder - getConnectionState func(host string) (tls.ConnectionState, error) + getConnectionState func(endpoint string) (tls.ConnectionState, error) } -func getConnectionState(host string) (tls.ConnectionState, error) { - conn, err := tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true}) +func getConnectionState(endpoint string) (tls.ConnectionState, error) { + conn, err := tls.Dial("tcp", endpoint, &tls.Config{InsecureSkipVerify: true}) if err != nil { return tls.ConnectionState{}, err } @@ -39,6 +39,35 @@ func getConnectionState(host string) (tls.ConnectionState, error) { return conn.ConnectionState(), nil } +func (s *scraper) scrapeTarget(endpoint string, wg *sync.WaitGroup, mux *sync.Mutex) { + defer wg.Done() + + mux.Lock() + defer mux.Unlock() + + state, err := s.getConnectionState(endpoint) + if err != nil { + s.settings.Logger.Error("TCP connection error encountered", zap.String("endpoint", endpoint), zap.Error(err)) + return + } + + s.settings.Logger.Error("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) + if len(state.PeerCertificates) == 0 { + s.settings.Logger.Error("No TLS certificates found. Verify the endpoint serves TLS certificates.", zap.String("endpoint", endpoint)) + return + } + + cert := state.PeerCertificates[0] + issuer := cert.Issuer.String() + commonName := cert.Subject.CommonName + currentTime := time.Now() + timeLeft := cert.NotAfter.Sub(currentTime).Seconds() + timeLeftInt := int64(timeLeft) + now := pcommon.NewTimestampFromTime(time.Now()) + + s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName, endpoint) +} + func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { if s.cfg == nil || len(s.cfg.Targets) == 0 { return pmetric.NewMetrics(), ErrMissingTargets @@ -47,39 +76,16 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { var wg sync.WaitGroup wg.Add(len(s.cfg.Targets)) var mux sync.Mutex + for _, target := range s.cfg.Targets { - go func(host string) { - defer wg.Done() - - now := pcommon.NewTimestampFromTime(time.Now()) - mux.Lock() - state, err := s.getConnectionState(target.Endpoint) - if err != nil { - s.settings.Logger.Error("TCP connection error encountered", zap.String("host", target.Endpoint), zap.Error(err)) - } - - s.settings.Logger.Error("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) - if len(state.PeerCertificates) == 0 { - s.settings.Logger.Error("No TLS certificates found. Verify the host serves TLS certificates.", zap.String("host", target.Endpoint)) - } - - cert := state.PeerCertificates[0] - issuer := cert.Issuer.String() - commonName := cert.Subject.CommonName - currentTime := time.Now() - timeLeft := cert.NotAfter.Sub(currentTime).Seconds() - timeLeftInt := int64(timeLeft) - s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName, host) - mux.Unlock() - - }(target.Endpoint) + go s.scrapeTarget(target.Endpoint, &wg, &mux) } wg.Wait() return s.mb.Emit(), nil } -func newScraper(cfg *Config, settings receiver.Settings, getConnectionState func(host string) (tls.ConnectionState, error)) *scraper { +func newScraper(cfg *Config, settings receiver.Settings, getConnectionState func(endpoint string) (tls.ConnectionState, error)) *scraper { return &scraper{ cfg: cfg, settings: settings.TelemetrySettings, diff --git a/receiver/tlscheckreceiver/scraper_test.go b/receiver/tlscheckreceiver/scraper_test.go index d9e986e868fc..06e5a4b8d943 100644 --- a/receiver/tlscheckreceiver/scraper_test.go +++ b/receiver/tlscheckreceiver/scraper_test.go @@ -18,7 +18,7 @@ import ( ) //nolint:revive -func mockGetConnectionStateValid(host string) (tls.ConnectionState, error) { +func mockGetConnectionStateValid(endpoint string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(24 * time.Hour), @@ -31,7 +31,7 @@ func mockGetConnectionStateValid(host string) (tls.ConnectionState, error) { } //nolint:revive -func mockGetConnectionStateExpired(host string) (tls.ConnectionState, error) { +func mockGetConnectionStateExpired(endpoint string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(-48 * time.Hour), NotAfter: time.Now().Add(-24 * time.Hour), @@ -44,7 +44,7 @@ func mockGetConnectionStateExpired(host string) (tls.ConnectionState, error) { } //nolint:revive -func mockGetConnectionStateNotYetValid(host string) (tls.ConnectionState, error) { +func mockGetConnectionStateNotYetValid(endpoint string) (tls.ConnectionState, error) { cert := &x509.Certificate{ NotBefore: time.Now().Add(48 * time.Hour), NotAfter: time.Now().Add(24 * time.Hour), From 4343e1b24dd2eb1348f8e72e9e7f949eb2a5203c Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 24 Oct 2024 15:10:46 -0600 Subject: [PATCH 07/20] generate --- .../internal/metadata/generated_metrics.go | 8 ++++---- .../internal/metadata/generated_metrics_test.go | 6 +++--- receiver/tlscheckreceiver/metadata.yaml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go b/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go index 7aa27a53bfaf..816b68a5184d 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_metrics.go @@ -26,7 +26,7 @@ func (m *metricTlscheckTimeLeft) init() { m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) } -func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckHostAttributeValue string) { +func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckEndpointAttributeValue string) { if !m.config.Enabled { return } @@ -36,7 +36,7 @@ func (m *metricTlscheckTimeLeft) recordDataPoint(start pcommon.Timestamp, ts pco dp.SetIntValue(val) dp.Attributes().PutStr("tlscheck.x509.issuer", tlscheckX509IssuerAttributeValue) dp.Attributes().PutStr("tlscheck.x509.cn", tlscheckX509CnAttributeValue) - dp.Attributes().PutStr("tlscheck.host", tlscheckHostAttributeValue) + dp.Attributes().PutStr("tlscheck.endpoint", tlscheckEndpointAttributeValue) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -188,8 +188,8 @@ func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics } // RecordTlscheckTimeLeftDataPoint adds a data point to tlscheck.time_left metric. -func (mb *MetricsBuilder) RecordTlscheckTimeLeftDataPoint(ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckHostAttributeValue string) { - mb.metricTlscheckTimeLeft.recordDataPoint(mb.startTime, ts, val, tlscheckX509IssuerAttributeValue, tlscheckX509CnAttributeValue, tlscheckHostAttributeValue) +func (mb *MetricsBuilder) RecordTlscheckTimeLeftDataPoint(ts pcommon.Timestamp, val int64, tlscheckX509IssuerAttributeValue string, tlscheckX509CnAttributeValue string, tlscheckEndpointAttributeValue string) { + mb.metricTlscheckTimeLeft.recordDataPoint(mb.startTime, ts, val, tlscheckX509IssuerAttributeValue, tlscheckX509CnAttributeValue, tlscheckEndpointAttributeValue) } // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, diff --git a/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go b/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go index 5c37211d987f..11ef1fb0b6a0 100644 --- a/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/tlscheckreceiver/internal/metadata/generated_metrics_test.go @@ -61,7 +61,7 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ - mb.RecordTlscheckTimeLeftDataPoint(ts, 1, "tlscheck.x509.issuer-val", "tlscheck.x509.cn-val", "tlscheck.host-val") + mb.RecordTlscheckTimeLeftDataPoint(ts, 1, "tlscheck.x509.issuer-val", "tlscheck.x509.cn-val", "tlscheck.endpoint-val") res := pcommon.NewResource() metrics := mb.Emit(WithResource(res)) @@ -103,9 +103,9 @@ func TestMetricsBuilder(t *testing.T) { attrVal, ok = dp.Attributes().Get("tlscheck.x509.cn") assert.True(t, ok) assert.EqualValues(t, "tlscheck.x509.cn-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("tlscheck.host") + attrVal, ok = dp.Attributes().Get("tlscheck.endpoint") assert.True(t, ok) - assert.EqualValues(t, "tlscheck.host-val", attrVal.Str()) + assert.EqualValues(t, "tlscheck.endpoint-val", attrVal.Str()) } } }) diff --git a/receiver/tlscheckreceiver/metadata.yaml b/receiver/tlscheckreceiver/metadata.yaml index 9b0366f2f85d..df834b74a18d 100644 --- a/receiver/tlscheckreceiver/metadata.yaml +++ b/receiver/tlscheckreceiver/metadata.yaml @@ -11,7 +11,7 @@ status: resource_attributes: attributes: - tlscheck.endpo: + tlscheck.endpoint: enabled: true description: Endpoint at which the certificate was accessed. type: string From ed32280bedc362b0bcddd7b6db5f02c9eb972ce0 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 24 Oct 2024 15:50:36 -0600 Subject: [PATCH 08/20] fixes --- receiver/tlscheckreceiver/config.go | 5 ++--- receiver/tlscheckreceiver/scraper.go | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/receiver/tlscheckreceiver/config.go b/receiver/tlscheckreceiver/config.go index 5c859085628c..203d861e0cff 100644 --- a/receiver/tlscheckreceiver/config.go +++ b/receiver/tlscheckreceiver/config.go @@ -11,7 +11,6 @@ import ( "strings" "go.opentelemetry.io/collector/config/confignet" - "go.opentelemetry.io/collector/receiver/scraperhelper" "go.uber.org/multierr" @@ -41,7 +40,7 @@ func validatePort(port string) error { return nil } -func ValidateTarget(cfg *confignet.TCPAddrConfig) error { +func validateTarget(cfg *confignet.TCPAddrConfig) error { var err error if cfg.Endpoint == "" { @@ -73,7 +72,7 @@ func (cfg *Config) Validate() error { } for _, target := range cfg.Targets { - err = multierr.Append(err, ValidateTarget(target)) + err = multierr.Append(err, validateTarget(target)) } return err diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index 0df3cb150157..39cd050db46d 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -39,7 +39,7 @@ func getConnectionState(endpoint string) (tls.ConnectionState, error) { return conn.ConnectionState(), nil } -func (s *scraper) scrapeTarget(endpoint string, wg *sync.WaitGroup, mux *sync.Mutex) { +func (s *scraper) scrapeEndpoint(endpoint string, wg *sync.WaitGroup, mux *sync.Mutex) { defer wg.Done() mux.Lock() @@ -78,7 +78,7 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { var mux sync.Mutex for _, target := range s.cfg.Targets { - go s.scrapeTarget(target.Endpoint, &wg, &mux) + go s.scrapeEndpoint(target.Endpoint, &wg, &mux) } wg.Wait() From 8b798654aae74486ac2ee87c4d0e7ec4953e1b41 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 24 Oct 2024 16:04:23 -0600 Subject: [PATCH 09/20] go tidy --- receiver/tlscheckreceiver/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 2ccd40eff9fa..f10fc72463d7 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -6,6 +6,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.112.0 + go.opentelemetry.io/collector/config/confignet v1.18.0 go.opentelemetry.io/collector/confmap v1.18.0 go.opentelemetry.io/collector/consumer v0.112.0 go.opentelemetry.io/collector/consumer/consumertest v0.112.0 @@ -33,7 +34,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - go.opentelemetry.io/collector/config/confignet v1.18.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.112.0 // indirect go.opentelemetry.io/collector/consumer/consumererror v0.112.0 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.112.0 // indirect From 711cdc2b3ec5fb385bcab43e55b31f9049b33904 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Mon, 4 Nov 2024 14:38:07 -0700 Subject: [PATCH 10/20] address PR comments --- receiver/tlscheckreceiver/scraper.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index 39cd050db46d..eeb4eda771a6 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -42,16 +42,13 @@ func getConnectionState(endpoint string) (tls.ConnectionState, error) { func (s *scraper) scrapeEndpoint(endpoint string, wg *sync.WaitGroup, mux *sync.Mutex) { defer wg.Done() - mux.Lock() - defer mux.Unlock() - state, err := s.getConnectionState(endpoint) if err != nil { s.settings.Logger.Error("TCP connection error encountered", zap.String("endpoint", endpoint), zap.Error(err)) return } - s.settings.Logger.Error("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) + s.settings.Logger.Info("Peer Certificates", zap.Int("certificates_count", len(state.PeerCertificates))) if len(state.PeerCertificates) == 0 { s.settings.Logger.Error("No TLS certificates found. Verify the endpoint serves TLS certificates.", zap.String("endpoint", endpoint)) return @@ -65,6 +62,8 @@ func (s *scraper) scrapeEndpoint(endpoint string, wg *sync.WaitGroup, mux *sync. timeLeftInt := int64(timeLeft) now := pcommon.NewTimestampFromTime(time.Now()) + mux.Lock() + defer mux.Unlock() s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName, endpoint) } From c537d1a753d4338e96ca92587c10fa8195ceeed5 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Wed, 6 Nov 2024 22:22:39 -0700 Subject: [PATCH 11/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/go.mod | 2 +- receiver/tlscheckreceiver/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 25e5015f0e0e..402bdc2ca4cf 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -6,10 +6,10 @@ require ( github.com/google/go-cmp v0.6.0 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.113.0 + go.opentelemetry.io/collector/config/confignet v1.19.0 go.opentelemetry.io/collector/confmap v1.19.0 go.opentelemetry.io/collector/consumer v0.113.0 go.opentelemetry.io/collector/consumer/consumertest v0.113.0 - go.opentelemetry.io/collector/filter v0.113.0 go.opentelemetry.io/collector/pdata v1.19.0 go.opentelemetry.io/collector/receiver v0.113.0 go.opentelemetry.io/collector/receiver/receivertest v0.113.0 diff --git a/receiver/tlscheckreceiver/go.sum b/receiver/tlscheckreceiver/go.sum index 6a554640cc03..9e8feb600af7 100644 --- a/receiver/tlscheckreceiver/go.sum +++ b/receiver/tlscheckreceiver/go.sum @@ -50,6 +50,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/collector/component v0.113.0 h1:/nx+RvZgxUEXP+YcTj69rEtuSEGkfaCyp/ad5zQGLjU= go.opentelemetry.io/collector/component v0.113.0/go.mod h1:2T779hIGHU9i7xbXbV3q1/JnRw2FyzUYXW2vq47A6EU= +go.opentelemetry.io/collector/config/confignet v1.19.0 h1:gEDTd8zLx4pPpG5///XPRpbYUpvKsuQzDdM5IEULY9w= +go.opentelemetry.io/collector/config/confignet v1.19.0/go.mod h1:o3v4joAEjvLwntqexg5ixMqRrU1+Vst+jWuCUaBNgOg= go.opentelemetry.io/collector/config/configtelemetry v0.113.0 h1:hweTRrVddnUeA3k7HzRY4oUR9lRdMa7of3mHNUS5YyA= go.opentelemetry.io/collector/config/configtelemetry v0.113.0/go.mod h1:R0MBUxjSMVMIhljuDHWIygzzJWQyZHXXWIgQNxcFwhc= go.opentelemetry.io/collector/confmap v1.19.0 h1:TQ0lZpAKqgsE0EKk+u4JA+uBbPYeFRmWP3GH43w40CY= @@ -62,8 +64,6 @@ go.opentelemetry.io/collector/consumer/consumerprofiles v0.113.0 h1:RftAcQUY5UOf go.opentelemetry.io/collector/consumer/consumerprofiles v0.113.0/go.mod h1:ZuHrQ4pWguh6dw0DgTfcUtdY/T+cnOJJNP6LMbm5Y5A= go.opentelemetry.io/collector/consumer/consumertest v0.113.0 h1:ua2AjNx3DUA8qElXNkggB4w3VDL/rBKBvryOQkhumH8= go.opentelemetry.io/collector/consumer/consumertest v0.113.0/go.mod h1:vK8o4ZTZSiG3rVyqxZcCNmT/cvEfx34ig7V65L9+6Rg= -go.opentelemetry.io/collector/filter v0.113.0 h1:5ODwM8QEOzZq08H8DJilBa4PHieXpBreJVKZ0D2YshA= -go.opentelemetry.io/collector/filter v0.113.0/go.mod h1:Mh3N6cpVijdamUJj1tAgSU1RG/Ek4FuY2ODKYxKZDtk= go.opentelemetry.io/collector/pdata v1.19.0 h1:jmnU5R8TOCbwRr4B8sjdRxM7L5WnEKlQWX1dtLYxIbE= go.opentelemetry.io/collector/pdata v1.19.0/go.mod h1:Ox1YVLe87cZDB/TL30i4SUz1cA5s6AM6SpFMfY61ICs= go.opentelemetry.io/collector/pdata/pprofile v0.113.0 h1:VRf4p0VhfuaR+Epy/nMIlu/9t39WU9CUgHVUvpuGxfU= From 7043c57b3c2bda70fdc3ac3e10e4ee301d28f3a0 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Sun, 24 Nov 2024 22:51:23 -0700 Subject: [PATCH 12/20] lint --- receiver/tlscheckreceiver/scraper.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index eeb4eda771a6..c950aa09afa3 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -19,9 +19,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) -var ( - ErrMissingTargets = errors.New(`No targets specified`) -) +var ErrMissingTargets = errors.New(`No targets specified`) type scraper struct { cfg *Config From 0229dd8d050aba32b5b1905ee2bcb53e9bdc9b76 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Mon, 25 Nov 2024 18:18:12 -0700 Subject: [PATCH 13/20] address PR comments --- .chloggen/tlscheckreceiver-implementation.yaml | 4 ++-- receiver/tlscheckreceiver/factory.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.chloggen/tlscheckreceiver-implementation.yaml b/.chloggen/tlscheckreceiver-implementation.yaml index d9695418d232..85c44788abbe 100644 --- a/.chloggen/tlscheckreceiver-implementation.yaml +++ b/.chloggen/tlscheckreceiver-implementation.yaml @@ -1,7 +1,7 @@ # Use this changelog template to create an entry for release notes. # One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement +change_type: breaking # The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) component: tlscheckreceiver @@ -15,7 +15,7 @@ issues: [35842] # (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: +subtext: Changing configuration scheme to use standard confignet TCP client # 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. diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 1d68bd7b7953..0e519d767440 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -28,7 +28,6 @@ func NewFactory() receiver.Factory { func newDefaultConfig() component.Config { cfg := scraperhelper.NewDefaultControllerConfig() - cfg.CollectionInterval = 60 * time.Second return &Config{ ControllerConfig: cfg, From 8ad04078b73169a2f5682fc1cc69339e1fba0b91 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Mon, 25 Nov 2024 19:12:30 -0700 Subject: [PATCH 14/20] lint --- receiver/tlscheckreceiver/factory.go | 1 - 1 file changed, 1 deletion(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 0e519d767440..474370ae1789 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -6,7 +6,6 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll import ( "context" "errors" - "time" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/confignet" From 561c42d8729e5f5367f27aa79d16c29aa64b1817 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Fri, 6 Dec 2024 20:51:02 -0700 Subject: [PATCH 15/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/config.go | 8 +++----- receiver/tlscheckreceiver/config_test.go | 2 +- receiver/tlscheckreceiver/scraper.go | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/receiver/tlscheckreceiver/config.go b/receiver/tlscheckreceiver/config.go index 203d861e0cff..e729e240d693 100644 --- a/receiver/tlscheckreceiver/config.go +++ b/receiver/tlscheckreceiver/config.go @@ -18,9 +18,7 @@ import ( ) // Predefined error responses for configuration validation failures -var ( - errInvalidEndpoint = errors.New(`"endpoint" must be in the form of :`) -) +var errInvalidEndpoint = errors.New(`"endpoint" must be in the form of :`) // Config defines the configuration for the various elements of the receiver agent. type Config struct { @@ -44,7 +42,7 @@ func validateTarget(cfg *confignet.TCPAddrConfig) error { var err error if cfg.Endpoint == "" { - return ErrMissingTargets + return errMissingTargets } if strings.Contains(cfg.Endpoint, "://") { @@ -68,7 +66,7 @@ func (cfg *Config) Validate() error { var err error if len(cfg.Targets) == 0 { - err = multierr.Append(err, ErrMissingTargets) + err = multierr.Append(err, errMissingTargets) } for _, target := range cfg.Targets { diff --git a/receiver/tlscheckreceiver/config_test.go b/receiver/tlscheckreceiver/config_test.go index 05d0a3433fb8..3b2b5c7b65ae 100644 --- a/receiver/tlscheckreceiver/config_test.go +++ b/receiver/tlscheckreceiver/config_test.go @@ -25,7 +25,7 @@ func TestValidate(t *testing.T) { Targets: []*confignet.TCPAddrConfig{}, ControllerConfig: scraperhelper.NewDefaultControllerConfig(), }, - expectedErr: ErrMissingTargets, + expectedErr: errMissingTargets, }, { desc: "invalid endpoint", diff --git a/receiver/tlscheckreceiver/scraper.go b/receiver/tlscheckreceiver/scraper.go index c950aa09afa3..51e079fc58e2 100644 --- a/receiver/tlscheckreceiver/scraper.go +++ b/receiver/tlscheckreceiver/scraper.go @@ -19,7 +19,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) -var ErrMissingTargets = errors.New(`No targets specified`) +var errMissingTargets = errors.New(`No targets specified`) type scraper struct { cfg *Config @@ -67,7 +67,7 @@ func (s *scraper) scrapeEndpoint(endpoint string, wg *sync.WaitGroup, mux *sync. func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { if s.cfg == nil || len(s.cfg.Targets) == 0 { - return pmetric.NewMetrics(), ErrMissingTargets + return pmetric.NewMetrics(), errMissingTargets } var wg sync.WaitGroup From db4443494cfce7a241b97cc8ed36cf79b030d2c6 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Fri, 6 Dec 2024 21:08:54 -0700 Subject: [PATCH 16/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/factory.go | 1 - receiver/tlscheckreceiver/go.mod | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 6e10dc4d99ca..6591976edace 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -12,7 +12,6 @@ import ( "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" - "go.opentelemetry.io/collector/scraper" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 5274663b36d2..fa45e66b5c00 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -14,7 +14,6 @@ require ( go.opentelemetry.io/collector/pdata v1.21.0 go.opentelemetry.io/collector/receiver v0.115.0 go.opentelemetry.io/collector/receiver/receivertest v0.115.0 - go.opentelemetry.io/collector/scraper v0.115.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 @@ -43,6 +42,7 @@ require ( go.opentelemetry.io/collector/pdata/pprofile v0.115.0 // indirect go.opentelemetry.io/collector/pipeline v0.115.0 // indirect go.opentelemetry.io/collector/receiver/receiverprofiles v0.115.0 // indirect + go.opentelemetry.io/collector/scraper v0.115.0 // indirect go.opentelemetry.io/otel v1.32.0 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect go.opentelemetry.io/otel/sdk v1.32.0 // indirect From 1204e1858c7f266c42e510faf121d0444eb4d6ca Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Fri, 6 Dec 2024 21:51:43 -0700 Subject: [PATCH 17/20] [receiver/tlscheck] Implement Scraper --- receiver/tlscheckreceiver/factory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 6591976edace..9917150f93ac 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -47,7 +47,7 @@ func newReceiver( } mp := newScraper(tlsCheckConfig, settings, getConnectionState) - s, err := scraperhelper.NewScraperWithoutType(mp.scrape) + s, err := scraperhelper.NewScraper(mp.scrape) if err != nil { return nil, err } From 985ec4ffed32a2c6d2998c3828e82e8d877027eb Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 12 Dec 2024 14:30:29 -0700 Subject: [PATCH 18/20] fix import --- receiver/tlscheckreceiver/factory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 9917150f93ac..181730ebdaa8 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -47,7 +47,7 @@ func newReceiver( } mp := newScraper(tlsCheckConfig, settings, getConnectionState) - s, err := scraperhelper.NewScraper(mp.scrape) + s, err := scraper.NewMetrics(mp.scrape) if err != nil { return nil, err } From 26a44e24feddffa79236520837746b031a208cee Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 12 Dec 2024 14:41:18 -0700 Subject: [PATCH 19/20] fix import --- receiver/tlscheckreceiver/factory.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 181730ebdaa8..98034de1d0ea 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" + "go.opentelemetry.io/collector/scraper" collectorscraper "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) @@ -47,7 +48,7 @@ func newReceiver( } mp := newScraper(tlsCheckConfig, settings, getConnectionState) - s, err := scraper.NewMetrics(mp.scrape) + s, err := collectorscraper.NewMetrics(mp.scrape) if err != nil { return nil, err } From 0803b58f35b28948c7a86e7298449204986c2f12 Mon Sep 17 00:00:00 2001 From: Michael Burt Date: Thu, 12 Dec 2024 14:52:23 -0700 Subject: [PATCH 20/20] cleanup --- receiver/tlscheckreceiver/factory.go | 2 +- receiver/tlscheckreceiver/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/receiver/tlscheckreceiver/factory.go b/receiver/tlscheckreceiver/factory.go index 98034de1d0ea..7604a144110f 100644 --- a/receiver/tlscheckreceiver/factory.go +++ b/receiver/tlscheckreceiver/factory.go @@ -12,7 +12,7 @@ import ( "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" - "go.opentelemetry.io/collector/scraper" collectorscraper + collectorscraper "go.opentelemetry.io/collector/scraper" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata" ) diff --git a/receiver/tlscheckreceiver/go.mod b/receiver/tlscheckreceiver/go.mod index 156699557e46..103e44cb1b0e 100644 --- a/receiver/tlscheckreceiver/go.mod +++ b/receiver/tlscheckreceiver/go.mod @@ -14,6 +14,7 @@ require ( go.opentelemetry.io/collector/pdata v1.21.1-0.20241206185113-3f3e208e71b8 go.opentelemetry.io/collector/receiver v0.115.1-0.20241206185113-3f3e208e71b8 go.opentelemetry.io/collector/receiver/receivertest v0.115.1-0.20241206185113-3f3e208e71b8 + go.opentelemetry.io/collector/scraper v0.115.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 @@ -42,7 +43,6 @@ require ( go.opentelemetry.io/collector/pdata/pprofile v0.115.1-0.20241206185113-3f3e208e71b8 // indirect go.opentelemetry.io/collector/pipeline v0.115.1-0.20241206185113-3f3e208e71b8 // indirect go.opentelemetry.io/collector/receiver/receiverprofiles v0.115.1-0.20241206185113-3f3e208e71b8 // indirect - go.opentelemetry.io/collector/scraper v0.115.0 // indirect go.opentelemetry.io/otel v1.32.0 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect go.opentelemetry.io/otel/sdk v1.32.0 // indirect