go.d/varnish: add docker support (#18512)
Ilya Mashchenko committed
Sep 10, 2024 at 17:36 UTC
2d4c5d1a09a4c346b16d3b854f7bea15ff7c6839
9 files changed
+68
-12
src/go/plugin/go.d/config/go.d/sd/docker.conf
+7
@@ -82,6 +82,8 @@ classify:
82
expr: '{{ and (eq .PrivatePort "9051") (match "sp" .Image "*/tor */tor:*") }}'
83
- tags: "tomcat"
84
expr: '{{ match "sp" .Image "tomcat tomcat:* */tomcat */tomcat:*" }}'
85
+ - tags: "varnish"
86
+ expr: '{{ match "sp" .Image "varnish varnish:*" }}'
87
- tags: "vernemq"
88
expr: '{{ match "sp" .Image "*/vernemq */vernemq:*" }}'
89
- tags: "zookeeper"
@@ -257,6 +259,11 @@ compose:
259
module: tor
260
name: docker_{{.Name}}
261
address: {{.Address}}
262
+ - selector: "varnish"
263
+ template: |
264
+ module: varnish
265
+ name: docker_{{.Name}}
266
+ docker_container: {{.Name}}
267
- selector: "vernemq"
268
template: |
269
module: vernemq
src/go/plugin/go.d/modules/varnish/config_schema.json
+5
@@ -22,6 +22,11 @@
22
"title": "Instance name",
23
"description": "Specifies the name of the Varnish instance to collect metrics from.",
24
"type": "string"
25
+ },
26
+ "docker_container": {
27
+ "title": "Docker container name",
28
+ "description": "Specifies the name of the Docker container where the Varnish instance is running. If set, the `varnishstat` command will be executed within this container.",
29
+ "type": "string"
30
}
31
},
32
"required": [],
src/go/plugin/go.d/modules/varnish/exec.go
+34
-1
@@ -6,16 +6,18 @@ import (
6
"context"
7
"fmt"
8
"os/exec"
9
+ "strconv"
10
"time"
11
12
"github.com/netdata/netdata/go/plugins/logger"
13
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/dockerhost"
14
)
15
16
type varnishstatBinary interface {
17
statistics() ([]byte, error)
18
}
19
18
-func newVarnishstatBinary(binPath string, cfg Config, log *logger.Logger) varnishstatBinary {
20
+func newVarnishstatExecBinary(binPath string, cfg Config, log *logger.Logger) varnishstatBinary {
21
return &varnishstatExec{
22
Logger: log,
23
binPath: binPath,
@@ -46,3 +48,34 @@ func (e *varnishstatExec) statistics() ([]byte, error) {
48
49
return bs, nil
50
}
51
+
52
+func newVarnishstatDockerExecBinary(cfg Config, log *logger.Logger) varnishstatBinary {
53
+ return &varnishstatDockerExec{
54
+ Logger: log,
55
+ timeout: cfg.Timeout.Duration(),
56
+ instanceName: cfg.InstanceName,
57
+ container: cfg.DockerContainer,
58
+ }
59
+}
60
+
61
+type varnishstatDockerExec struct {
62
+ *logger.Logger
63
+
64
+ timeout time.Duration
65
+ instanceName string
66
+ container string
67
+}
68
+
69
+func (e *varnishstatDockerExec) statistics() ([]byte, error) {
70
+ ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
71
+ defer cancel()
72
+
73
+ timeS := strconv.Itoa(max(int(e.timeout.Seconds()), 1))
74
+
75
+ args := []string{"-1", "-t", timeS}
76
+ if e.instanceName != "" {
77
+ args = append(args, "-n", e.instanceName)
78
+ }
79
+
80
+ return dockerhost.Exec(ctx, e.container, "varnishstat", args...)
81
+}
src/go/plugin/go.d/modules/varnish/init.go
+5
-1
@@ -11,6 +11,10 @@ import (
11
)
12
13
func (v *Varnish) initVarnishstatBinary() (varnishstatBinary, error) {
14
+ if v.Config.DockerContainer != "" {
15
+ return newVarnishstatDockerExecBinary(v.Config, v.Logger), nil
16
+ }
17
+
18
ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
19
20
if _, err := os.Stat(ndsudoPath); err != nil {
@@ -18,7 +22,7 @@ func (v *Varnish) initVarnishstatBinary() (varnishstatBinary, error) {
22
23
}
24
21
- varnishstat := newVarnishstatBinary(ndsudoPath, v.Config, v.Logger)
25
+ varnishstat := newVarnishstatExecBinary(ndsudoPath, v.Config, v.Logger)
26
27
return varnishstat, nil
28
}
src/go/plugin/go.d/modules/varnish/metadata.yaml
+4
@@ -71,6 +71,10 @@ modules:
71
description: "Specifies the name of the Varnish instance to collect metrics from. This corresponds to the `-n` argument used with the [varnishstat](https://varnish-cache.org/docs/trunk/reference/varnishstat.html) command."
72
default_value: ""
73
required: false
74
+ - name: docker_container
75
+ description: "Specifies the name of the Docker container where the Varnish instance is running. If set, the `varnishstat` command will be executed within this container."
76
+ default_value: ""
77
+ required: false
78
examples:
79
folding:
80
title: ""
src/go/plugin/go.d/modules/varnish/testdata/config.json
+2
-1
@@ -1,5 +1,6 @@
1
{
2
"update_every": 123,
3
"timeout": 123.123,
4
- "instance_name": "ok"
4
+ "instance_name": "ok",
5
+ "docker_container": "ok"
6
}
src/go/plugin/go.d/modules/varnish/testdata/config.yaml
+1
@@ -1,3 +1,4 @@
1
update_every: 123
2
timeout: 123.123
3
instance_name: "ok"
4
+docker_container: "ok"
src/go/plugin/go.d/modules/varnish/varnish.go
+4
-3
@@ -39,9 +39,10 @@ func New() *Varnish {
39
}
40
41
type Config struct {
42
- UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
43
- Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
44
- InstanceName string `yaml:"instance_name,omitempty" json:"instance_name,omitempty"`
42
+ UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
43
+ Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
44
+ InstanceName string `yaml:"instance_name,omitempty" json:"instance_name,omitempty"`
45
+ DockerContainer string `yaml:"docker_container,omitempty" json:"docker_container,omitempty"`
46
}
47
48
type Varnish struct {
src/go/plugin/go.d/pkg/dockerhost/dockerhost.go
+6
-6
@@ -28,7 +28,7 @@ func FromEnv() string {
28
return fmt.Sprintf("tcp://%s", addr)
29
}
30
31
-func Exec(ctx context.Context, containerId string, cmd string, args ...string) ([]byte, error) {
31
+func Exec(ctx context.Context, container string, cmd string, args ...string) ([]byte, error) {
32
// based on https://github.com/moby/moby/blob/8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb/integration/internal/container/exec.go#L38
33
34
addr := docker.DefaultDockerHost
@@ -51,14 +51,14 @@ func Exec(ctx context.Context, containerId string, cmd string, args ...string) (
51
Cmd: append([]string{cmd}, args...),
52
}
53
54
- createResp, err := cli.ContainerExecCreate(ctx, containerId, execCreateConfig)
54
+ createResp, err := cli.ContainerExecCreate(ctx, container, execCreateConfig)
55
if err != nil {
56
- return nil, fmt.Errorf("failed to container exec create ('%s'): %v", containerId, err)
56
+ return nil, fmt.Errorf("failed to container exec create ('%s'): %v", container, err)
57
}
58
59
attachResp, err := cli.ContainerExecAttach(ctx, createResp.ID, typesContainer.ExecAttachOptions{})
60
if err != nil {
61
- return nil, fmt.Errorf("failed to container exec attach ('%s'): %v", containerId, err)
61
+ return nil, fmt.Errorf("failed to container exec attach ('%s'): %v", container, err)
62
}
63
defer attachResp.Close()
64
@@ -78,7 +78,7 @@ func Exec(ctx context.Context, containerId string, cmd string, args ...string) (
78
select {
79
case err := <-done:
80
if err != nil {
81
- return nil, fmt.Errorf("failed to read response from container ('%s'): %v", containerId, err)
81
+ return nil, fmt.Errorf("failed to read response from container ('%s'): %v", container, err)
82
}
83
case <-ctx.Done():
84
return nil, fmt.Errorf("timed out reading response")
@@ -86,7 +86,7 @@ func Exec(ctx context.Context, containerId string, cmd string, args ...string) (
86
87
inspResp, err := cli.ContainerExecInspect(ctx, createResp.ID)
88
if err != nil {
89
- return nil, fmt.Errorf("failed to container exec inspect ('%s'): %v", containerId, err)
89
+ return nil, fmt.Errorf("failed to container exec inspect ('%s'): %v", container, err)
90
}
91
92
if inspResp.ExitCode != 0 {