Skip to content

Commit 4fe7405

Browse files
authored
Add envoy metrics discovery bundle (#5780)
* Add envoy metrics discovery bundle * add changelog * use correct image, use endpoint instead of hardcoding the port * do not skip the test * fix test * fix test * fix test * push envoy discovery to its own test * use a separate test run * fix docker test again * fix the test some more
1 parent 469980b commit 4fe7405

File tree

17 files changed

+569
-1
lines changed

17 files changed

+569
-1
lines changed

.github/workflows/integration-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ jobs:
338338
id: get-matrix
339339
run: |
340340
includes=""
341-
for service in "apache" "jmx/cassandra" "kafkametrics" "mongodb" "nginx"; do
341+
for service in "apache" "jmx/cassandra" "kafkametrics" "mongodb" "nginx" "envoy"; do
342342
for arch in "amd64" "arm64"; do
343343
if [ "$service" = "mongodb" ]; then
344344
# tests for mongo "6.0" and "7.0" are flaky, skipping for now

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- (Splunk) Add `metricsgeneration` processor ([#5769](https://github.com/signalfx/splunk-otel-collector/pull/5769))
88

9+
### 💡 Enhancements 💡
10+
11+
- (Splunk) Add a new discovery bundle for Envoy proxy metrics ([#5780](https://github.com/signalfx/splunk-otel-collector/pull/5780))
12+
913
## v0.116.0
1014

1115
This Splunk OpenTelemetry Collector release includes changes from the [opentelemetry-collector v0.116.0](https://github.com/open-telemetry/opentelemetry-collector/releases/tag/v0.116.0) and the [opentelemetry-collector-contrib v0.116.0](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.116.0) releases where appropriate.

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ integration-test-jmx/cassandra-discovery:
103103
integration-test-apache-discovery:
104104
@set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=discovery_integration_apachewebserver -v -timeout 5m -count 1 ./...
105105

106+
.PHONY: integration-test-envoy-discovery
107+
integration-test-envoy-discovery:
108+
@set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=discovery_integration_envoy -v -timeout 5m -count 1 ./...
109+
106110
.PHONY: integration-test-nginx-discovery
107111
integration-test-nginx-discovery:
108112
@set -e; cd tests && $(GOTEST_SERIAL) $(BUILD_INFO_TESTS) --tags=discovery_integration_nginx -v -timeout 5m -count 1 ./...
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#####################################################################################
2+
# This file is generated by the Splunk Distribution of the OpenTelemetry Collector. #
3+
# #
4+
# It reflects the default configuration bundled in the Collector executable for use #
5+
# in discovery mode (--discovery) and is provided for reference or customization. #
6+
# Please note that any changes made to this file will need to be reconciled during #
7+
# upgrades of the Collector. #
8+
#####################################################################################
9+
# prometheus:
10+
# enabled: true
11+
# rule:
12+
# docker_observer: type == "container" and any([name, image, command], {# matches "(?i)envoy"}) and not (command matches "splunk.discovery")
13+
# host_observer: type == "hostport" and command matches "(?i)envoy" and not (command matches "splunk.discovery")
14+
# k8s_observer: type == "port" and pod.name matches "(?i)envoy"
15+
# config:
16+
# default:
17+
# config:
18+
# scrape_configs:
19+
# - job_name: 'envoy'
20+
# metrics_path: /stats/prometheus
21+
# scrape_interval: 10s
22+
# static_configs:
23+
# - targets: ['`endpoint`']
24+
# metric_relabel_configs:
25+
# - source_labels: [__name__]
26+
# action: keep
27+
# regex: '(envoy_cluster_upstream_cx_active|envoy_cluster_upstream_cx_total|envoy_cluster_upstream_cx_connect_fail|envoy_cluster_upstream_cx_connect_ms|envoy_cluster_upstream_rq_active|envoy_cluster_upstream_rq_total|envoy_cluster_upstream_rq_timeout|envoy_cluster_upstream_rq_pending_active|envoy_cluster_upstream_rq_pending_overflow|envoy_cluster_upstream_rq_time|envoy_cluster_membership_total|envoy_cluster_membership_degraded|envoy_cluster_membership_excluded|envoy_listener_downstream_cx_active|envoy_listener_downstream_cx_total|envoy_listener_downstream_cx_transport_socket_connect_timeout|envoy_listener_downstream_cx_overflow|envoy_listener_downstream_cx_overload_reject|envoy_listener_downstream_global_cx_overflow)'
28+
# status:
29+
# metrics:
30+
# - status: successful
31+
# strict: envoy_cluster_upstream_cx_active
32+
# message: envoy prometheus receiver is working!
33+
# statements:
34+
# - status: failed
35+
# regexp: "connection refused"
36+
# message: The container is not serving http connections.
37+
# - status: failed
38+
# regexp: "dial tcp: lookup"
39+
# message: Unable to resolve envoy prometheus tcp endpoint

docker/docker-compose.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ services:
8080
- integration
8181
environment:
8282
- ELASTIC_PASSWORD=$ELASTIC_PASSWORD
83+
envoy:
84+
image: quay.io/splunko11ytest/envoy:latest
85+
profiles:
86+
- integration-test-envoy-discovery
87+
build: ./envoy
88+
ports:
89+
- "9901:9901"
8390
# Haproxy image for haproxy test:
8491
haproxy:
8592
image: quay.io/splunko11ytest/haproxy:latest

docker/envoy/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM envoyproxy/envoy:v1.32-latest
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#####################################################################################
2+
# Do not edit manually! #
3+
# All changes must be made to associated .tmpl file before running 'make bundle.d'. #
4+
#####################################################################################
5+
prometheus:
6+
enabled: true
7+
rule:
8+
docker_observer: type == "container" and any([name, image, command], {# matches "(?i)envoy"}) and not (command matches "splunk.discovery")
9+
host_observer: type == "hostport" and command matches "(?i)envoy" and not (command matches "splunk.discovery")
10+
k8s_observer: type == "port" and pod.name matches "(?i)envoy"
11+
config:
12+
default:
13+
config:
14+
scrape_configs:
15+
- job_name: 'envoy'
16+
metrics_path: /stats/prometheus
17+
scrape_interval: 10s
18+
static_configs:
19+
- targets: ['`endpoint`']
20+
metric_relabel_configs:
21+
- source_labels: [__name__]
22+
action: keep
23+
regex: '(envoy_cluster_upstream_cx_active|envoy_cluster_upstream_cx_total|envoy_cluster_upstream_cx_connect_fail|envoy_cluster_upstream_cx_connect_ms|envoy_cluster_upstream_rq_active|envoy_cluster_upstream_rq_total|envoy_cluster_upstream_rq_timeout|envoy_cluster_upstream_rq_pending_active|envoy_cluster_upstream_rq_pending_overflow|envoy_cluster_upstream_rq_time|envoy_cluster_membership_total|envoy_cluster_membership_degraded|envoy_cluster_membership_excluded|envoy_listener_downstream_cx_active|envoy_listener_downstream_cx_total|envoy_listener_downstream_cx_transport_socket_connect_timeout|envoy_listener_downstream_cx_overflow|envoy_listener_downstream_cx_overload_reject|envoy_listener_downstream_global_cx_overflow)'
24+
status:
25+
metrics:
26+
- status: successful
27+
strict: envoy_cluster_upstream_cx_active
28+
message: envoy prometheus receiver is working!
29+
statements:
30+
- status: failed
31+
regexp: "connection refused"
32+
message: The container is not serving http connections.
33+
- status: failed
34+
regexp: "dial tcp: lookup"
35+
message: Unable to resolve envoy prometheus tcp endpoint
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{ receiver "prometheus" }}:
2+
enabled: true
3+
rule:
4+
docker_observer: type == "container" and any([name, image, command], {# matches "(?i)envoy"}) and not (command matches "splunk.discovery")
5+
host_observer: type == "hostport" and command matches "(?i)envoy" and not (command matches "splunk.discovery")
6+
k8s_observer: type == "port" and pod.name matches "(?i)envoy"
7+
config:
8+
default:
9+
config:
10+
scrape_configs:
11+
- job_name: 'envoy'
12+
metrics_path: /stats/prometheus
13+
scrape_interval: 10s
14+
static_configs:
15+
- targets: ['`endpoint`']
16+
metric_relabel_configs:
17+
- source_labels: [__name__]
18+
action: keep
19+
regex: '(envoy_cluster_upstream_cx_active|envoy_cluster_upstream_cx_total|envoy_cluster_upstream_cx_connect_fail|envoy_cluster_upstream_cx_connect_ms|envoy_cluster_upstream_rq_active|envoy_cluster_upstream_rq_total|envoy_cluster_upstream_rq_timeout|envoy_cluster_upstream_rq_pending_active|envoy_cluster_upstream_rq_pending_overflow|envoy_cluster_upstream_rq_time|envoy_cluster_membership_total|envoy_cluster_membership_degraded|envoy_cluster_membership_excluded|envoy_listener_downstream_cx_active|envoy_listener_downstream_cx_total|envoy_listener_downstream_cx_transport_socket_connect_timeout|envoy_listener_downstream_cx_overflow|envoy_listener_downstream_cx_overload_reject|envoy_listener_downstream_global_cx_overflow)'
20+
status:
21+
metrics:
22+
- status: successful
23+
strict: envoy_cluster_upstream_cx_active
24+
message: envoy prometheus receiver is working!
25+
statements:
26+
- status: failed
27+
regexp: "connection refused"
28+
message: The container is not serving http connections.
29+
- status: failed
30+
regexp: "dial tcp: lookup"
31+
message: Unable to resolve envoy prometheus tcp endpoint

internal/confmapprovider/discovery/bundle/bundle_gen.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
//go:generate discoverybundler --render --template bundle.d/receivers/apache.discovery.yaml.tmpl
2727
//go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/apache.discovery.yaml.tmpl
28+
//go:generate discoverybundler --render --template bundle.d/receivers/envoy.discovery.yaml.tmpl
29+
//go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/envoy.discovery.yaml.tmpl
2830
//go:generate discoverybundler --render --template bundle.d/receivers/jmx-cassandra.discovery.yaml.tmpl
2931
//go:generate discoverybundler --render --commented --dir ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/jmx-cassandra.discovery.yaml.tmpl
3032
//go:generate discoverybundler --render --template bundle.d/receivers/kafkametrics.discovery.yaml.tmpl

internal/confmapprovider/discovery/bundle/bundledfs_other_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func TestBundleDir(t *testing.T) {
2828
require.NoError(t, err)
2929
require.Equal(t, []string{
3030
"bundle.d/receivers/apache.discovery.yaml",
31+
"bundle.d/receivers/envoy.discovery.yaml",
3132
"bundle.d/receivers/jmx-cassandra.discovery.yaml",
3233
"bundle.d/receivers/kafkametrics.discovery.yaml",
3334
"bundle.d/receivers/mongodb.discovery.yaml",

internal/confmapprovider/discovery/bundle/bundledfs_others.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
//go:embed bundle.d/extensions/host-observer.discovery.yaml
2727
//go:embed bundle.d/extensions/k8s-observer.discovery.yaml
2828
//go:embed bundle.d/receivers/apache.discovery.yaml
29+
//go:embed bundle.d/receivers/envoy.discovery.yaml
2930
//go:embed bundle.d/receivers/jmx-cassandra.discovery.yaml
3031
//go:embed bundle.d/receivers/kafkametrics.discovery.yaml
3132
//go:embed bundle.d/receivers/mongodb.discovery.yaml

internal/confmapprovider/discovery/bundle/bundledfs_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
//go:embed bundle.d/extensions/host-observer.discovery.yaml
2727
//go:embed bundle.d/extensions/k8s-observer.discovery.yaml
2828
//go:embed bundle.d/receivers/apache.discovery.yaml
29+
//go:embed bundle.d/receivers/envoy.discovery.yaml
2930
//go:embed bundle.d/receivers/jmx-cassandra.discovery.yaml
3031
//go:embed bundle.d/receivers/kafkametrics.discovery.yaml
3132
//go:embed bundle.d/receivers/mongodb.discovery.yaml

internal/confmapprovider/discovery/bundle/bundledfs_windows_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func TestBundleDir(t *testing.T) {
2828
require.NoError(t, err)
2929
require.Equal(t, []string{
3030
"bundle.d/receivers/apache.discovery.yaml",
31+
"bundle.d/receivers/envoy.discovery.yaml",
3132
"bundle.d/receivers/jmx-cassandra.discovery.yaml",
3233
"bundle.d/receivers/kafkametrics.discovery.yaml",
3334
"bundle.d/receivers/mongodb.discovery.yaml",

internal/confmapprovider/discovery/bundle/components.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var (
3232
// in Components.Linux. If desired in windows BundledFS, ensure they are included in Components.Windows.
3333
receivers = []string{
3434
"apache",
35+
"envoy",
3536
"jmx-cassandra",
3637
"kafkametrics",
3738
"mongodb",
@@ -66,6 +67,7 @@ var (
6667
Windows: func() map[string]struct{} {
6768
windows := map[string]struct{}{
6869
"apache": {},
70+
"envoy": {},
6971
"jmx-cassandra": {},
7072
"kafkametrics": {},
7173
"mongodb": {},

tests/receivers/envoy/bundled_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright Splunk, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build discovery_integration_envoy
16+
17+
package tests
18+
19+
import (
20+
"fmt"
21+
"path/filepath"
22+
"testing"
23+
"time"
24+
25+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden"
26+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest"
27+
"github.com/stretchr/testify/assert"
28+
"github.com/stretchr/testify/require"
29+
30+
"github.com/signalfx/splunk-otel-collector/tests/testutils"
31+
)
32+
33+
func TestEnvoyDockerObserver(t *testing.T) {
34+
testutils.SkipIfNotContainerTest(t)
35+
dockerSocket := testutils.CreateDockerSocketProxy(t)
36+
require.NoError(t, dockerSocket.Start())
37+
t.Cleanup(func() {
38+
dockerSocket.Stop()
39+
})
40+
41+
tc := testutils.NewTestcase(t)
42+
defer tc.PrintLogsOnFailure()
43+
defer tc.ShutdownOTLPReceiverSink()
44+
_, shutdown := tc.SplunkOtelCollectorContainer("otlp_exporter.yaml", func(collector testutils.Collector) testutils.Collector {
45+
cc := collector.(*testutils.CollectorContainer)
46+
return cc.WithEnv(map[string]string{
47+
"SPLUNK_DISCOVERY_DURATION": "20s",
48+
"SPLUNK_DISCOVERY_LOG_LEVEL": "debug",
49+
}).WithArgs(
50+
"--discovery",
51+
"--set", `splunk.discovery.extensions.k8s_observer.enabled=false`,
52+
"--set", `splunk.discovery.extensions.host_observer.enabled=false`,
53+
"--set", fmt.Sprintf("splunk.discovery.extensions.docker_observer.config.endpoint=tcp://%s", dockerSocket.ContainerEndpoint),
54+
)
55+
})
56+
defer shutdown()
57+
58+
expected, err := golden.ReadMetrics(filepath.Join("testdata", "expected.yaml"))
59+
require.NoError(t, err)
60+
require.EventuallyWithT(t, func(tt *assert.CollectT) {
61+
if len(tc.OTLPReceiverSink.AllMetrics()) == 0 {
62+
assert.Fail(tt, "No metrics collected")
63+
return
64+
}
65+
err := pmetrictest.CompareMetrics(expected, tc.OTLPReceiverSink.AllMetrics()[len(tc.OTLPReceiverSink.AllMetrics())-1],
66+
pmetrictest.IgnoreResourceAttributeValue("service.instance.id"),
67+
pmetrictest.IgnoreResourceAttributeValue("net.host.port"),
68+
pmetrictest.IgnoreResourceAttributeValue("net.host.name"),
69+
pmetrictest.IgnoreResourceAttributeValue("server.address"),
70+
pmetrictest.IgnoreResourceAttributeValue("container.name"),
71+
pmetrictest.IgnoreResourceAttributeValue("server.port"),
72+
pmetrictest.IgnoreResourceAttributeValue("service.name"),
73+
pmetrictest.IgnoreResourceAttributeValue("service_instance_id"),
74+
pmetrictest.IgnoreResourceAttributeValue("service_version"),
75+
pmetrictest.IgnoreMetricAttributeValue("service_version"),
76+
pmetrictest.IgnoreMetricAttributeValue("service_instance_id"),
77+
pmetrictest.IgnoreResourceAttributeValue("server.address"),
78+
pmetrictest.IgnoreTimestamp(),
79+
pmetrictest.IgnoreStartTimestamp(),
80+
pmetrictest.IgnoreMetricDataPointsOrder(),
81+
pmetrictest.IgnoreScopeMetricsOrder(),
82+
pmetrictest.IgnoreScopeVersion(),
83+
pmetrictest.IgnoreResourceMetricsOrder(),
84+
pmetrictest.IgnoreMetricsOrder(),
85+
pmetrictest.IgnoreMetricValues(),
86+
)
87+
assert.NoError(tt, err)
88+
}, 30*time.Second, 1*time.Second)
89+
}

0 commit comments

Comments
 (0)