summaryrefslogtreecommitdiffstats
path: root/src/go/plugin/go.d/modules/traefik/traefik.go
blob: e38ff969933670b07828f89d74134fa4330aed02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: GPL-3.0-or-later

package traefik

import (
	_ "embed"
	"errors"
	"time"

	"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
	"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/prometheus"
	"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)

//go:embed "config_schema.json"
var configSchema string

func init() {
	module.Register("traefik", module.Creator{
		JobConfigSchema: configSchema,
		Create:          func() module.Module { return New() },
		Config:          func() any { return &Config{} },
	})
}

func New() *Traefik {
	return &Traefik{
		Config: Config{
			HTTP: web.HTTP{
				Request: web.Request{
					URL: "http://127.0.0.1:8082/metrics",
				},
				Client: web.Client{
					Timeout: web.Duration(time.Second),
				},
			},
		},

		charts:       &module.Charts{},
		checkMetrics: true,
		cache: &cache{
			entrypoints: make(map[string]*cacheEntrypoint),
		},
	}
}

type Config struct {
	UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
	web.HTTP    `yaml:",inline" json:""`
}

type (
	Traefik struct {
		module.Base
		Config `yaml:",inline" json:""`

		charts *module.Charts

		prom prometheus.Prometheus

		checkMetrics bool
		cache        *cache
	}
	cache struct {
		entrypoints map[string]*cacheEntrypoint
	}
	cacheEntrypoint struct {
		name, proto     string
		requests        *module.Chart
		reqDur          *module.Chart
		reqDurData      map[string]cacheEntrypointReqDur
		openConn        *module.Chart
		openConnMethods map[string]bool
	}
	cacheEntrypointReqDur struct {
		prev, cur struct{ reqs, secs float64 }
		seen      bool
	}
)

func (t *Traefik) Configuration() any {
	return t.Config
}

func (t *Traefik) Init() error {
	if err := t.validateConfig(); err != nil {
		t.Errorf("config validation: %v", err)
		return err
	}

	prom, err := t.initPrometheusClient()
	if err != nil {
		t.Errorf("prometheus client initialization: %v", err)
		return err
	}
	t.prom = prom

	return nil
}

func (t *Traefik) Check() error {
	mx, err := t.collect()
	if err != nil {
		t.Error(err)
		return err
	}
	if len(mx) == 0 {
		return errors.New("no metrics collected")
	}
	return nil
}

func (t *Traefik) Charts() *module.Charts {
	return t.charts
}

func (t *Traefik) Collect() map[string]int64 {
	mx, err := t.collect()
	if err != nil {
		t.Error(err)
		return nil
	}

	if len(mx) == 0 {
		return nil
	}
	return mx
}

func (t *Traefik) Cleanup() {}