Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit 2c4d4c1

Browse files
Ben Keithkeitwb
authored andcommitted
Update health_checker plugin and add test
1 parent 681c4d8 commit 2c4d4c1

File tree

7 files changed

+83
-9
lines changed

7 files changed

+83
-9
lines changed

collectd-plugins.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
repo: signalfx/collectd-haproxy
2727

2828
- name: health_checker
29-
version: multi-instance #v1.0.0
29+
version: v0.0.3
3030
repo: signalfx/collectd-health_checker
3131

3232
- name: jenkins

docs/monitors/collectd-health-checker.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ Monitor Type: `collectd/health-checker`
2222
| `host` | **yes** | `string` | |
2323
| `port` | **yes** | `integer` | |
2424
| `name` | no | `string` | |
25-
| `url` | no | `string` | |
25+
| `path` | no | `string` | The HTTP path that contains a JSON document to verify (**default:** `/`) |
26+
| `jsonKey` | no | `string` | If `jsonKey` and `jsonVal` are given, the given endpoint will be interpreted as a JSON document and will be expected to contain the given key and value for the service to be considered healthy. |
2627
| `jsonVal` | no | `any` | This can be either a string or numeric type |
27-
| `jsonKey` | no | `string` | |
28+
| `useHTTPS` | no | `bool` | If true, the endpoint will be connected to on HTTPS instead of plain HTTP. It is invalid to specify this if `tcpCheck` is true. (**default:** `false`) |
29+
| `skipSecurity` | no | `bool` | If true, and `useHTTPS` is true, the server's SSL/TLS cert will not be verified. (**default:** `false`) |
30+
| `tcpCheck` | no | `bool` | If true, the plugin will verify that it can connect to the given host/port value. JSON checking is not supported. (**default:** `false`) |
2831

2932

3033

internal/monitors/collectd/healthchecker/healthchecker.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package healthchecker
55
//go:generate collectd-template-to-go healthchecker.tmpl
66

77
import (
8+
"errors"
9+
810
"github.com/signalfx/signalfx-agent/internal/core/config"
911
"github.com/signalfx/signalfx-agent/internal/core/services"
1012
"github.com/signalfx/signalfx-agent/internal/monitors"
@@ -37,10 +39,34 @@ type Config struct {
3739
Port uint16 `yaml:"port" validate:"required"`
3840
Name string `yaml:"name"`
3941

40-
URL string `yaml:"url"`
42+
// The HTTP path that contains a JSON document to verify
43+
Path string `yaml:"path" default:"/"`
44+
// If `jsonKey` and `jsonVal` are given, the given endpoint will be
45+
// interpreted as a JSON document and will be expected to contain the given
46+
// key and value for the service to be considered healthy.
47+
JSONKey string `yaml:"jsonKey"`
4148
// This can be either a string or numeric type
4249
JSONVal interface{} `yaml:"jsonVal"`
43-
JSONKey string `yaml:"jsonKey"`
50+
// If true, the endpoint will be connected to on HTTPS instead of plain
51+
// HTTP. It is invalid to specify this if `tcpCheck` is true.
52+
UseHTTPS bool `yaml:"useHTTPS"`
53+
// If true, and `useHTTPS` is true, the server's SSL/TLS cert will not be
54+
// verified.
55+
SkipSecurity bool `yaml:"skipSecurity"`
56+
// If true, the plugin will verify that it can connect to the given
57+
// host/port value. JSON checking is not supported.
58+
TCPCheck bool `yaml:"tcpCheck"`
59+
}
60+
61+
// Validate the given config
62+
func (c *Config) Validate() error {
63+
if c.TCPCheck && (c.SkipSecurity || c.UseHTTPS) {
64+
return errors.New("neither skipSecurity nor useHTTPS should be set when tcpCheck is true")
65+
}
66+
if c.TCPCheck && (c.JSONKey != "" || c.JSONVal != nil) {
67+
return errors.New("cannot do JSON value check with tcpCheck set to true")
68+
}
69+
return nil
4470
}
4571

4672
// Monitor is the main type that represents the monitor
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
LoadPlugin "python"
22
<Plugin python>
33
ModulePath "{{ pluginRoot }}/health_checker"
4+
LogTraces true
45

56
Import "health_checker"
67
<Module health_checker>
7-
URL "{{renderValue .URL .}}"
8-
Instance "{{.Name}}[monitorID={{.MonitorID}}]"
8+
{{ if not .TCPCheck }}
9+
URL "http{{if .UseHTTPS}}s{{end}}://{{.Host}}:{{.Port}}{{.Path}}"
910
JSONKey "{{.JSONKey}}"
1011
JSONVal "{{.JSONVal}}"
12+
{{ else }}
13+
URL "{{.Host}}"
14+
TCP {{.Port}}
15+
{{ end }}
16+
SkipSecurity {{toBool .SkipSecurity}}
17+
Instance "{{.Name}}[monitorID={{.MonitorID}}]"
1118
</Module>
1219
</Plugin>

tests/helpers/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
AGENT_BIN = os.environ.get("AGENT_BIN", "/bundle/bin/signalfx-agent")
1616
PROJECT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
1717
TEST_SERVICES_DIR = os.environ.get("TEST_SERVICES_DIR", "/test-services")
18-
DEFAULT_TIMEOUT = os.environ.get("DEFAULT_TIMEOUT", 20)
18+
DEFAULT_TIMEOUT = os.environ.get("DEFAULT_TIMEOUT", 30)
1919
DOCKER_API_VERSION = "1.34"
2020

2121

tests/kubernetes/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
["haproxy-configmap.yaml", "haproxy.yaml"]),
9090
({"type": "collectd/health-checker",
9191
"discoveryRule": 'container_image =~ "json-server" && private_port == 80',
92-
"url": 'http://{{.Host}}:{{.Port}}/health',
92+
"path": '/health',
9393
"jsonKey": "status",
9494
"jsonVal": "ok"},
9595
["health-checker-configmap.yaml", "health-checker.yaml"]),
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from functools import partial as p
2+
from textwrap import dedent
3+
import string
4+
5+
from tests.helpers.util import wait_for, run_agent, run_service, container_ip
6+
from tests.helpers.assertions import has_datapoint_with_dim, tcp_socket_open
7+
8+
config = string.Template("""
9+
monitors:
10+
- type: collectd/health-checker
11+
host: $host
12+
port: 80
13+
tcpCheck: true
14+
""")
15+
16+
def test_health_checker_tcp():
17+
with run_service("nginx") as nginx_container:
18+
host = container_ip(nginx_container)
19+
assert wait_for(p(tcp_socket_open, host, 80), 60), "service didn't start"
20+
21+
with run_agent(config.substitute(host=host)) as [backend, _, _]:
22+
assert wait_for(p(has_datapoint_with_dim, backend, "plugin", "health_checker")), \
23+
"Didn't get health_checker datapoints"
24+
25+
def test_health_checker_http():
26+
with run_service("nginx") as nginx_container:
27+
host = container_ip(nginx_container)
28+
assert wait_for(p(tcp_socket_open, host, 80), 60), "service didn't start"
29+
30+
with run_agent(string.Template(dedent("""
31+
monitors:
32+
- type: collectd/health-checker
33+
host: $host
34+
port: 80
35+
path: /nonexistent
36+
""")).substitute(host=host)) as [backend, _, _]:
37+
assert wait_for(p(has_datapoint_with_dim, backend, "plugin", "health_checker")), \
38+
"Didn't get health_checker datapoints"

0 commit comments

Comments
 (0)