Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add smartagent/collectd/nginx discovery rules #3321

Merged
merged 1 commit into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### 💡 Enhancements 💡

- (Splunk) Add bundled collectd/nginx Smart Agent receiver discovery rules ([#3321](https://github.com/signalfx/splunk-otel-collector/pull/3321))

## v0.80.0

This Splunk OpenTelemetry Collector release includes changes from the [opentelemetry-collector v0.80.0](https://github.com/open-telemetry/opentelemetry-collector/releases/tag/v0.80.0) and the [opentelemetry-collector-contrib v0.80.0](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.80.0) releases where appropriate.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#####################################################################################
# This file is generated by the Splunk Distribution of the OpenTelemetry Collector. #
#####################################################################################
# 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:
# successful:
# - strict: connections.accepted
# first_only: true
# log_record:
# severity_text: info
# body: smartagent/collectd/nginx receiver is working!
# statements:
# failed:
# - regexp: "nginx plugin: curl_easy_perform failed: Operation timed out after"
# first_only: true
# log_record:
# severity_text: info
# append_pattern: true
# body: The container is not serving http connections.
# - regexp: "read-function of plugin .* failed"
# first_only: true
# log_record:
# severity_text: info
# append_pattern: true
# body: The integration is unable to read metrics from this endpoint.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#####################################################################################
# This file is generated by the Splunk Distribution of the OpenTelemetry Collector. #
#####################################################################################
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:
successful:
- strict: connections.accepted
first_only: true
log_record:
severity_text: info
body: smartagent/collectd/nginx receiver is working!
statements:
failed:
- regexp: "nginx plugin: curl_easy_perform failed: Operation timed out after"
first_only: true
log_record:
severity_text: info
append_pattern: true
body: The container is not serving http connections.
- regexp: "read-function of plugin .* failed"
first_only: true
log_record:
severity_text: info
append_pattern: true
body: The integration is unable to read metrics from this endpoint.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{{ 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:
successful:
- strict: connections.accepted
first_only: true
log_record:
severity_text: info
body: smartagent/collectd/nginx receiver is working!
statements:
failed:
- regexp: "nginx plugin: curl_easy_perform failed: Operation timed out after"
first_only: true
log_record:
severity_text: info
append_pattern: true
body: The container is not serving http connections.
- regexp: "read-function of plugin .* failed"
first_only: true
log_record:
severity_text: info
append_pattern: true
body: The integration is unable to read metrics from this endpoint.
2 changes: 2 additions & 0 deletions internal/confmapprovider/discovery/bundle/bundle_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
//go:generate discoverybundler -r -c -d ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-postgresql.discovery.yaml.tmpl
//go:generate discoverybundler -r -t bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml.tmpl
//go:generate discoverybundler -r -c -d ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml.tmpl
//go:generate discoverybundler -r -t bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl
//go:generate discoverybundler -r -c -d ../../../../cmd/otelcol/config/collector/config.d.linux/receivers -t bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml.tmpl

//go:generate discoverybundler -r -t bundle.d/extensions/docker-observer.discovery.yaml.tmpl
//go:generate discoverybundler -r -c -d ../../../../cmd/otelcol/config/collector/config.d.linux/extensions -t bundle.d/extensions/docker-observer.discovery.yaml.tmpl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestBundleDir(t *testing.T) {
require.NoError(t, err)
require.Equal(t, []string{
"bundle.d/receivers/smartagent-collectd-mysql.discovery.yaml",
"bundle.d/receivers/smartagent-collectd-nginx.discovery.yaml",
"bundle.d/receivers/smartagent-postgresql.discovery.yaml",
}, receivers)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"os"
"path/filepath"
"runtime"
"syscall"
"testing"
"time"

Expand All @@ -43,13 +42,6 @@ func TestDockerObserver(t *testing.T) {
defer tc.PrintLogsOnFailure()
defer tc.ShutdownOTLPReceiverSink()

finfo, err := os.Stat("/var/run/docker.sock")
require.NoError(t, err)
fsys := finfo.Sys()
stat, ok := fsys.(*syscall.Stat_t)
require.True(t, ok)
dockerGID := stat.Gid

cc, shutdown := tc.SplunkOtelCollectorContainer(
"docker-otlp-exporter-no-internal-prometheus.yaml",
func(c testutils.Collector) testutils.Collector {
Expand All @@ -61,7 +53,7 @@ func TestDockerObserver(t *testing.T) {
cc.Container = cc.Container.WillWaitForLogs("Discovering for next")
// uid check is for basic collector functionality not using the splunk-otel-collector user
// but the docker gid is required to reach the daemon
cc.Container = cc.Container.WithUser(fmt.Sprintf("%d:%d", os.Getuid(), dockerGID))
cc.Container = cc.Container.WithUser(fmt.Sprintf("%d:%d", os.Getuid(), testutils.GetDockerGID(t)))
return cc
},
func(c testutils.Collector) testutils.Collector {
Expand Down
77 changes: 77 additions & 0 deletions tests/receivers/smartagent/collectd-nginx/bundled_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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 integration

package tests

import (
"fmt"
"path"
"runtime"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/signalfx/splunk-otel-collector/tests/testutils"
)

func TestDockerObserver(t *testing.T) {
testutils.SkipIfNotContainerTest(t)
if runtime.GOOS == "darwin" {
t.Skip("unable to share sockets between mac and d4m vm: https://github.com/docker/for-mac/issues/483#issuecomment-758836836")
}
tc := testutils.NewTestcase(t)
defer tc.PrintLogsOnFailure()
defer tc.ShutdownOTLPReceiverSink()

_, stop := tc.Containers(
testutils.NewContainer().WithContext(
path.Join(".", "testdata", "server"),
).WithExposedPorts(
fmt.Sprintf("%d:80", testutils.GetAvailablePort(t)),
).WithName("nginx").WillWaitForPorts("80"),
)
defer stop()

_, shutdown := tc.SplunkOtelCollectorContainer(
"otlp_exporter.yaml",
func(c testutils.Collector) testutils.Collector {
cc := c.(*testutils.CollectorContainer)
cc.Container = cc.Container.WithBinds("/var/run/docker.sock:/var/run/docker.sock:ro")
cc.Container = cc.Container.WillWaitForLogs("Discovering for next")
cc.Container = cc.Container.WithUser(fmt.Sprintf("999:%d", testutils.GetDockerGID(t)))
return cc
},
func(c testutils.Collector) testutils.Collector {
return c.WithEnv(map[string]string{
// runner seems to be slow
"SPLUNK_DISCOVERY_DURATION": "20s",
// confirm that debug logging doesn't affect runtime
"SPLUNK_DISCOVERY_LOG_LEVEL": "debug",
}).WithArgs(
"--discovery",
"--set", "splunk.discovery.receivers.smartagent/collectd/nginx.config.username=some_user",
"--set", "splunk.discovery.receivers.smartagent/collectd/nginx.config.password=some_password",
"--set", `splunk.discovery.extensions.k8s_observer.enabled=false`,
"--set", `splunk.discovery.extensions.host_observer.enabled=false`,
)
},
)
defer shutdown()

expectedResourceMetrics := tc.ResourceMetrics("default.yaml")
require.NoError(t, tc.OTLPReceiverSink.AssertAllMetricsReceived(t, *expectedResourceMetrics, 30*time.Second))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ receivers:
type: collectd/nginx
host: localhost
port: 8123
username: some_user
password: some_password
extraMetrics: ["*"]
intervalSeconds: 1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
exporters:
otlp:
endpoint: "${OTLP_ENDPOINT}"
tls:
insecure: true

service:
telemetry:
logs:
level: debug
pipelines:
metrics:
exporters: [otlp]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
resource_metrics:
- scope_metrics:
- metrics:
- name: connections.accepted
type: IntMonotonicCumulativeSum
attributes:
dsname: value
host: <ANY>
plugin: nginx
system.type: nginx
- name: connections.handled
type: IntMonotonicCumulativeSum
- name: nginx_connections.active
type: IntGauge
- name: nginx_connections.reading
type: IntGauge
- name: nginx_connections.waiting
type: IntGauge
- name: nginx_connections.writing
type: IntGauge
- name: nginx_requests
type: IntMonotonicCumulativeSum
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ FROM nginx:1.13.8

RUN rm /etc/nginx/conf.d/default.conf
COPY status.conf /etc/nginx/conf.d/status.conf
COPY htpasswd /etc/nginx/.htpasswd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
some_user:$apr1$mn7FX9UF$2wjlEnZe50o./Vd4mpSLc0

Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
server {
listen 80;

auth_basic "restricted";
auth_basic_user_file /etc/nginx/.htpasswd;

location /nginx_status {
stub_status;
}
Expand Down
34 changes: 34 additions & 0 deletions tests/testutils/container_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 !windows

package testutils

import (
"os"
"syscall"
"testing"

"github.com/stretchr/testify/require"
)

func GetDockerGID(t testing.TB) uint32 {
finfo, err := os.Stat("/var/run/docker.sock")
require.NoError(t, err)
fsys := finfo.Sys()
stat, ok := fsys.(*syscall.Stat_t)
require.True(t, ok)
return stat.Gid
}
26 changes: 26 additions & 0 deletions tests/testutils/container_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 windows

package testutils

import (
"testing"
)

func GetDockerGID(t testing.TB) uint32 {
t.Skip("windows acl not yet supported")
return 0
}