From e172128984c755d25af7a16ad5e0c092f3bdc67e Mon Sep 17 00:00:00 2001 From: Paulo Janotti Date: Thu, 12 Dec 2024 14:48:04 -0800 Subject: [PATCH] Move NGINX discovery to OTel receiver (#5689) * Initial changes to move NGINX discovery to OTel receiver * Initial changes to add discovery test * Fix typo * fix discovery endpoint * Fix typo * Add changelog entry * Remove smartagent-collectd-nginx generated file * Small README.md fix --- .github/workflows/integration-test.yml | 2 +- CHANGELOG.md | 5 ++ Makefile | 4 ++ .../properties.discovery.yaml.example | 4 +- .../receivers/nginx.discovery.yaml | 26 ++++++++++ docker/docker-compose.yml | 2 +- internal/confmapprovider/discovery/README.md | 2 +- ...nx.discovery.yaml => nginx.discovery.yaml} | 18 +++---- .../receivers/nginx.discovery.yaml.tmpl | 18 +++++++ ...rtagent-collectd-nginx.discovery.yaml.tmpl | 24 --------- .../discovery/bundle/bundle_gen.go | 4 +- .../discovery/bundle/bundledfs_other_test.go | 2 +- .../discovery/bundle/bundledfs_others.go | 2 +- .../discovery/bundle/components.go | 2 +- tests/receivers/nginx/nginx_discovery_test.go | 51 +++++++++++++++++++ .../docker_observer_nginx_config.yaml | 50 ++++++++++++++++++ 16 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 cmd/otelcol/config/collector/config.d.linux/receivers/nginx.discovery.yaml rename internal/confmapprovider/discovery/bundle/bundle.d/receivers/{smartagent-collectd-nginx.discovery.yaml => nginx.discovery.yaml} (57%) create mode 100644 internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml.tmpl delete mode 100644 internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl create mode 100644 tests/receivers/nginx/nginx_discovery_test.go create mode 100644 tests/receivers/nginx/testdata/docker_observer_nginx_config.yaml diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index b18b4a0e97..1a8c2db142 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -338,7 +338,7 @@ jobs: id: get-matrix run: | includes="" - for service in "apache" "mongodb" "kafkametrics" "jmx/cassandra"; do + for service in "apache" "jmx/cassandra" "kafkametrics" "mongodb" "nginx"; do for arch in "amd64" "arm64"; do if [ "$service" = "mongodb" ]; then # tests for mongo "6.0" and "7.0" are flaky, skipping for now diff --git a/CHANGELOG.md b/CHANGELOG.md index e82c0afeb4..7a82c29e1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### 💡 Enhancements 💡 + +- (Splunk) Automatic Discovery: + - Switch bundled NGINX discovery to create [OpenTelemetry NGINX receiver](https://docs.splunk.com/observability/en/gdi/opentelemetry/components/nginx-receiver.html#nginx-receiver) instead of the Smart Agent NGINX monitor ([#5689](https://github.com/signalfx/splunk-otel-collector/pull/5689)) + ### 🚩Deprecations 🚩 - (Splunk) Deprecate the collectd/genericjmx monitor. Please use the [jmxreceiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/jmxreceiver) instead. ([#5539](https://github.com/signalfx/splunk-otel-collector/pull/5539)) diff --git a/Makefile b/Makefile index 717eefdece..18349e2fff 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,10 @@ integration-test-jmx/cassandra-discovery: integration-test-apache-discovery: @set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=discovery_integration_apachewebserver -v -timeout 5m -count 1 ./... +.PHONY: integration-test-nginx-discovery +integration-test-nginx-discovery: + @set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=discovery_integration_nginx -v -timeout 5m -count 1 ./... + .PHONY: smartagent-integration-test smartagent-integration-test: @set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=smartagent_integration -v -timeout 5m -count 1 ./... diff --git a/cmd/otelcol/config/collector/config.d.linux/properties.discovery.yaml.example b/cmd/otelcol/config/collector/config.d.linux/properties.discovery.yaml.example index 2a37f92406..65a0891e88 100644 --- a/cmd/otelcol/config/collector/config.d.linux/properties.discovery.yaml.example +++ b/cmd/otelcol/config/collector/config.d.linux/properties.discovery.yaml.example @@ -13,11 +13,11 @@ splunk.discovery: receivers: mysql: enabled: true + nginx: + enabled: true postgresql: enabled: true smartagent/collectd/mysql: enabled: false - smartagent/collectd/nginx: - enabled: true smartagent/postgresql: enabled: false \ No newline at end of file diff --git a/cmd/otelcol/config/collector/config.d.linux/receivers/nginx.discovery.yaml b/cmd/otelcol/config/collector/config.d.linux/receivers/nginx.discovery.yaml new file mode 100644 index 0000000000..d919d80fcb --- /dev/null +++ b/cmd/otelcol/config/collector/config.d.linux/receivers/nginx.discovery.yaml @@ -0,0 +1,26 @@ +##################################################################################### +# This file is generated by the Splunk Distribution of the OpenTelemetry Collector. # +# # +# It reflects the default configuration bundled in the Collector executable for use # +# in discovery mode (--discovery) and is provided for reference or customization. # +# Please note that any changes made to this file will need to be reconciled during # +# upgrades of the Collector. # +##################################################################################### +# nginx: +# enabled: true +# rule: +# docker_observer: type == "container" and any([name, image, command], {# matches "(?i)nginx"}) and not (command matches "splunk.discovery") +# host_observer: type == "hostport" and command matches "(?i)nginx" and not (command matches "splunk.discovery") +# k8s_observer: type == "port" and pod.name matches "(?i)nginx" +# config: +# default: +# endpoint: '`(port in [443] ? "https://" : "http://")``endpoint`/nginx_status}}' +# status: +# metrics: +# - status: successful +# strict: nginx.connections_accepted +# message: nginx receiver is working! +# statements: +# - status: failed +# regexp: "Failed to fetch nginx stats" +# message: Failed to retrieve metrics from NGINX stub_status endpoint. diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e011f29976..61e090f1d0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -245,11 +245,11 @@ services: build: ./mysql ports: - "3306:3306" - # Nginx image for collectd-nginx test: nginx: image: quay.io/splunko11ytest/nginx:latest profiles: - integration + - integration-test-nginx-discovery - smartagent build: ./nginx ports: diff --git a/internal/confmapprovider/discovery/README.md b/internal/confmapprovider/discovery/README.md index 25824d9b5e..332c282616 100644 --- a/internal/confmapprovider/discovery/README.md +++ b/internal/confmapprovider/discovery/README.md @@ -138,11 +138,11 @@ The following components have bundled discovery configurations in the last Splun I. Receivers * `mongodb` ([Linux and Windows](./bundle/bundle.d/receivers/mongodb.discovery.yaml)) * `mysql` ([Linux and Windows](./bundle/bundle.d/receivers/mysql.discovery.yaml)) +* `nginx` ([Linux and Windows](./bundle/bundle.d/receivers/nginx.discovery.yaml)) * `oracledb` ([Linux and Windows](./bundle/bundle.d/receivers/oracledb.discovery.yaml)) * `postgresql` ([Linux and Windows](./bundle/bundle.d/receivers/postgresql.discovery.yaml)) * `redis` ([Linux and Windows](./bundle/bundle.d/receivers/redis.discovery.yaml)) * `smartagent` with `collectd/mysql` monitor type ([Linux](./bundle/bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml)) -* `smartagent` with `collectd/nginx` monitor type ([Linux](./bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml)) * `smartagent` with `postgresql` monitor type ([Linux and Windows](./bundle/bundle.d/receivers/smartagent-postgresql.discovery.yaml)) * `sqlserver` ([Linux And Windows](./bundle/bundle.d/receivers/sqlserver.discovery.yaml)) diff --git a/internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml b/internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml similarity index 57% rename from internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml rename to internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml index 87e6d2ee12..45290edeff 100644 --- a/internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml +++ b/internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml @@ -2,7 +2,7 @@ # Do not edit manually! # # All changes must be made to associated .tmpl file before running 'make bundle.d'. # ##################################################################################### -smartagent/collectd/nginx: +nginx: enabled: true rule: docker_observer: type == "container" and any([name, image, command], {# matches "(?i)nginx"}) and not (command matches "splunk.discovery") @@ -10,19 +10,13 @@ smartagent/collectd/nginx: k8s_observer: type == "port" and pod.name matches "(?i)nginx" config: default: - type: collectd/nginx - url: '`(port in [443, 8443] ? "https" : "http") + "://{{.Host}}:{{.Port}}/nginx_status"`' - timeout: 5000 - isolatedCollectd: true + endpoint: '`(port in [443] ? "https://" : "http://")``endpoint`/nginx_status}}' status: metrics: - status: successful - strict: connections.accepted - message: smartagent/collectd/nginx receiver is working! + strict: nginx.connections_accepted + message: nginx receiver is working! statements: - status: failed - regexp: "nginx plugin: curl_easy_perform failed: Operation timed out after" - message: The container is not serving http connections. - - status: failed - regexp: "read-function of plugin .* failed" - message: The integration is unable to read metrics from this endpoint. + regexp: "Failed to fetch nginx stats" + message: Failed to retrieve metrics from NGINX stub_status endpoint. diff --git a/internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml.tmpl b/internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml.tmpl new file mode 100644 index 0000000000..86a70b5349 --- /dev/null +++ b/internal/confmapprovider/discovery/bundle/bundle.d/receivers/nginx.discovery.yaml.tmpl @@ -0,0 +1,18 @@ +{{ receiver "nginx" }}: + enabled: true + rule: + docker_observer: type == "container" and any([name, image, command], {# matches "(?i)nginx"}) and not (command matches "splunk.discovery") + host_observer: type == "hostport" and command matches "(?i)nginx" and not (command matches "splunk.discovery") + k8s_observer: type == "port" and pod.name matches "(?i)nginx" + config: + default: + endpoint: '`(port in [443] ? "https://" : "http://")``endpoint`/nginx_status}}' + status: + metrics: + - status: successful + strict: nginx.connections_accepted + message: nginx receiver is working! + statements: + - status: failed + regexp: "Failed to fetch nginx stats" + message: Failed to retrieve metrics from NGINX stub_status endpoint. diff --git a/internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl b/internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl deleted file mode 100644 index 6adc2deeb2..0000000000 --- a/internal/confmapprovider/discovery/bundle/bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -{{ receiver "smartagent/collectd/nginx" }}: - enabled: true - rule: - docker_observer: type == "container" and any([name, image, command], {# matches "(?i)nginx"}) and not (command matches "splunk.discovery") - host_observer: type == "hostport" and command matches "(?i)nginx" and not (command matches "splunk.discovery") - k8s_observer: type == "port" and pod.name matches "(?i)nginx" - config: - default: - type: collectd/nginx - url: '`(port in [443, 8443] ? "https" : "http") + "{{`://{{.Host}}:{{.Port}}/nginx_status`}}"`' - timeout: 5000 - isolatedCollectd: true - status: - metrics: - - status: successful - strict: connections.accepted - message: smartagent/collectd/nginx receiver is working! - statements: - - status: failed - regexp: "nginx plugin: curl_easy_perform failed: Operation timed out after" - message: The container is not serving http connections. - - status: failed - regexp: "read-function of plugin .* failed" - message: The integration is unable to read metrics from this endpoint. diff --git a/internal/confmapprovider/discovery/bundle/bundle_gen.go b/internal/confmapprovider/discovery/bundle/bundle_gen.go index 1763646e22..15e4a241a2 100644 --- a/internal/confmapprovider/discovery/bundle/bundle_gen.go +++ b/internal/confmapprovider/discovery/bundle/bundle_gen.go @@ -33,6 +33,8 @@ //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/mongodb.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/mysql.discovery.yaml.tmpl //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/mysql.discovery.yaml.tmpl +//go:generate discoverybundler --render --template bundle.d/receivers/nginx.discovery.yaml.tmpl +//go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/nginx.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/oracledb.discovery.yaml.tmpl //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/oracledb.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/postgresql.discovery.yaml.tmpl @@ -43,8 +45,6 @@ //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/redis.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml.tmpl //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml.tmpl -//go:generate discoverybundler --render --template bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl -//go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/smartagent-postgresql.discovery.yaml.tmpl //go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-postgresql.discovery.yaml.tmpl //go:generate discoverybundler --render --template bundle.d/receivers/sqlserver.discovery.yaml.tmpl diff --git a/internal/confmapprovider/discovery/bundle/bundledfs_other_test.go b/internal/confmapprovider/discovery/bundle/bundledfs_other_test.go index dffd2b7d69..efe3c5320e 100644 --- a/internal/confmapprovider/discovery/bundle/bundledfs_other_test.go +++ b/internal/confmapprovider/discovery/bundle/bundledfs_other_test.go @@ -32,12 +32,12 @@ func TestBundleDir(t *testing.T) { "bundle.d/receivers/kafkametrics.discovery.yaml", "bundle.d/receivers/mongodb.discovery.yaml", "bundle.d/receivers/mysql.discovery.yaml", + "bundle.d/receivers/nginx.discovery.yaml", "bundle.d/receivers/oracledb.discovery.yaml", "bundle.d/receivers/postgresql.discovery.yaml", "bundle.d/receivers/rabbitmq.discovery.yaml", "bundle.d/receivers/redis.discovery.yaml", "bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml", - "bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml", "bundle.d/receivers/smartagent-postgresql.discovery.yaml", "bundle.d/receivers/sqlserver.discovery.yaml", }, receivers) diff --git a/internal/confmapprovider/discovery/bundle/bundledfs_others.go b/internal/confmapprovider/discovery/bundle/bundledfs_others.go index 3ed2493589..f69627a056 100644 --- a/internal/confmapprovider/discovery/bundle/bundledfs_others.go +++ b/internal/confmapprovider/discovery/bundle/bundledfs_others.go @@ -30,12 +30,12 @@ import ( //go:embed bundle.d/receivers/kafkametrics.discovery.yaml //go:embed bundle.d/receivers/mongodb.discovery.yaml //go:embed bundle.d/receivers/mysql.discovery.yaml +//go:embed bundle.d/receivers/nginx.discovery.yaml //go:embed bundle.d/receivers/oracledb.discovery.yaml //go:embed bundle.d/receivers/postgresql.discovery.yaml //go:embed bundle.d/receivers/rabbitmq.discovery.yaml //go:embed bundle.d/receivers/redis.discovery.yaml //go:embed bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml -//go:embed bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml //go:embed bundle.d/receivers/smartagent-postgresql.discovery.yaml //go:embed bundle.d/receivers/sqlserver.discovery.yaml var BundledFS embed.FS diff --git a/internal/confmapprovider/discovery/bundle/components.go b/internal/confmapprovider/discovery/bundle/components.go index f6e0d801b1..2a231d7702 100644 --- a/internal/confmapprovider/discovery/bundle/components.go +++ b/internal/confmapprovider/discovery/bundle/components.go @@ -36,12 +36,12 @@ var ( "kafkametrics", "mongodb", "mysql", + "nginx", "oracledb", "postgresql", "rabbitmq", "redis", "smartagent-collectd-mysql", - "smartagent-collectd-nginx", "smartagent-postgresql", "sqlserver", } diff --git a/tests/receivers/nginx/nginx_discovery_test.go b/tests/receivers/nginx/nginx_discovery_test.go new file mode 100644 index 0000000000..9d8e69d826 --- /dev/null +++ b/tests/receivers/nginx/nginx_discovery_test.go @@ -0,0 +1,51 @@ +// Copyright Splunk, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build discovery_integration_nginx + +package tests + +import ( + "path/filepath" + "runtime" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/signalfx/splunk-otel-collector/tests/internal/discoverytest" +) + +func TestIntegrationNGINXAutoDiscovery(t *testing.T) { + if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { + t.Skip("Integration tests are only run on linux architecture: https://github.com/signalfx/splunk-otel-collector/blob/main/.github/workflows/integration-test.yml#L35") + } + + tests := map[string]struct { + configFileName string + logMessageToAssert string + }{ + "Successful Discovery test": { + configFileName: "docker_observer_nginx_config.yaml", + logMessageToAssert: `nginx receiver is working!`, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + otelConfigPath, err := filepath.Abs(filepath.Join(".", "testdata", test.configFileName)) + require.NoError(t, err) + discoverytest.Run(t, "nginx", otelConfigPath, test.logMessageToAssert) + }) + } +} diff --git a/tests/receivers/nginx/testdata/docker_observer_nginx_config.yaml b/tests/receivers/nginx/testdata/docker_observer_nginx_config.yaml new file mode 100644 index 0000000000..c7f73b5c6a --- /dev/null +++ b/tests/receivers/nginx/testdata/docker_observer_nginx_config.yaml @@ -0,0 +1,50 @@ +extensions: + docker_observer: + use_host_bindings: true + basicauth: + client_auth: + username: some_user + password: some_password + +receivers: + discovery: + embed_receiver_config: true + receivers: + nginx: + config: + endpoint: '`(port in [443] ? "https://" : "http://")``endpoint`/nginx_status}}' + auth: + authenticator: basicauth + collection_interval: 1s + rule: type == "container" and any([name, image, command], {# matches "(?i)nginx"}) and not (command matches "splunk.discovery") + status: + metrics: + - status: successful + strict: nginx.connections_accepted + message: nginx receiver is working! + statements: + - status: failed + regexp: "Failed to fetch nginx stats" + message: Failed to retrieve metrics from NGINX stub_status endpoint. + watch_observers: + - docker_observer + +exporters: + debug: + verbosity: detailed + otlp: + endpoint: "${OTLP_ENDPOINT}" + tls: + insecure: true + +service: + telemetry: + logs: + level: info + extensions: + - docker_observer + - basicauth + pipelines: + logs: + receivers: [discovery] + exporters: [otlp, debug]