0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-28 14:42:31 +00:00

chore(go.d.plugin): renames part 2 ()

This commit is contained in:
Ilya Mashchenko 2024-11-27 10:41:02 +02:00 committed by GitHub
parent 8afb7e2ac8
commit ef7bccd2eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
633 changed files with 14157 additions and 14197 deletions

View file

@ -15,7 +15,7 @@ const (
var nameReplacer = strings.NewReplacer(".", "_", " ", "")
func (a *ActiveMQ) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
metrics := make(map[string]int64)
var (
@ -24,23 +24,23 @@ func (a *ActiveMQ) collect() (map[string]int64, error) {
err error
)
if queues, err = a.apiClient.getQueues(); err != nil {
if queues, err = c.apiClient.getQueues(); err != nil {
return nil, err
}
if topics, err = a.apiClient.getTopics(); err != nil {
if topics, err = c.apiClient.getTopics(); err != nil {
return nil, err
}
a.processQueues(queues, metrics)
a.processTopics(topics, metrics)
c.processQueues(queues, metrics)
c.processTopics(topics, metrics)
return metrics, nil
}
func (a *ActiveMQ) processQueues(queues *queues, metrics map[string]int64) {
func (c *Collector) processQueues(queues *queues, metrics map[string]int64) {
var (
count = len(a.activeQueues)
count = len(c.activeQueues)
updated = make(map[string]bool)
unp int
)
@ -50,18 +50,18 @@ func (a *ActiveMQ) processQueues(queues *queues, metrics map[string]int64) {
continue
}
if !a.activeQueues[q.Name] {
if a.MaxQueues != 0 && count > a.MaxQueues {
if !c.activeQueues[q.Name] {
if c.MaxQueues != 0 && count > c.MaxQueues {
unp++
continue
}
if !a.filterQueues(q.Name) {
if !c.filterQueues(q.Name) {
continue
}
a.activeQueues[q.Name] = true
a.addQueueTopicCharts(q.Name, keyQueues)
c.activeQueues[q.Name] = true
c.addQueueTopicCharts(q.Name, keyQueues)
}
rname := nameReplacer.Replace(q.Name)
@ -74,21 +74,21 @@ func (a *ActiveMQ) processQueues(queues *queues, metrics map[string]int64) {
updated[q.Name] = true
}
for name := range a.activeQueues {
for name := range c.activeQueues {
if !updated[name] {
delete(a.activeQueues, name)
a.removeQueueTopicCharts(name, keyQueues)
delete(c.activeQueues, name)
c.removeQueueTopicCharts(name, keyQueues)
}
}
if unp > 0 {
a.Debugf("%d queues were unprocessed due to max_queues limit (%d)", unp, a.MaxQueues)
c.Debugf("%d queues were unprocessed due to max_queues limit (%d)", unp, c.MaxQueues)
}
}
func (a *ActiveMQ) processTopics(topics *topics, metrics map[string]int64) {
func (c *Collector) processTopics(topics *topics, metrics map[string]int64) {
var (
count = len(a.activeTopics)
count = len(c.activeTopics)
updated = make(map[string]bool)
unp int
)
@ -98,18 +98,18 @@ func (a *ActiveMQ) processTopics(topics *topics, metrics map[string]int64) {
continue
}
if !a.activeTopics[t.Name] {
if a.MaxTopics != 0 && count > a.MaxTopics {
if !c.activeTopics[t.Name] {
if c.MaxTopics != 0 && count > c.MaxTopics {
unp++
continue
}
if !a.filterTopics(t.Name) {
if !c.filterTopics(t.Name) {
continue
}
a.activeTopics[t.Name] = true
a.addQueueTopicCharts(t.Name, keyTopics)
c.activeTopics[t.Name] = true
c.addQueueTopicCharts(t.Name, keyTopics)
}
rname := nameReplacer.Replace(t.Name)
@ -122,34 +122,34 @@ func (a *ActiveMQ) processTopics(topics *topics, metrics map[string]int64) {
updated[t.Name] = true
}
for name := range a.activeTopics {
for name := range c.activeTopics {
if !updated[name] {
// TODO: delete after timeout?
delete(a.activeTopics, name)
a.removeQueueTopicCharts(name, keyTopics)
delete(c.activeTopics, name)
c.removeQueueTopicCharts(name, keyTopics)
}
}
if unp > 0 {
a.Debugf("%d topics were unprocessed due to max_topics limit (%d)", unp, a.MaxTopics)
c.Debugf("%d topics were unprocessed due to max_topics limit (%d)", unp, c.MaxTopics)
}
}
func (a *ActiveMQ) filterQueues(line string) bool {
if a.queuesFilter == nil {
func (c *Collector) filterQueues(line string) bool {
if c.queuesFilter == nil {
return true
}
return a.queuesFilter.MatchString(line)
return c.queuesFilter.MatchString(line)
}
func (a *ActiveMQ) filterTopics(line string) bool {
if a.topicsFilter == nil {
func (c *Collector) filterTopics(line string) bool {
if c.topicsFilter == nil {
return true
}
return a.topicsFilter.MatchString(line)
return c.topicsFilter.MatchString(line)
}
func (a *ActiveMQ) addQueueTopicCharts(name, typ string) {
func (c *Collector) addQueueTopicCharts(name, typ string) {
rname := nameReplacer.Replace(name)
charts := charts.Copy()
@ -164,22 +164,22 @@ func (a *ActiveMQ) addQueueTopicCharts(name, typ string) {
}
}
_ = a.charts.Add(*charts...)
_ = c.charts.Add(*charts...)
}
func (a *ActiveMQ) removeQueueTopicCharts(name, typ string) {
func (c *Collector) removeQueueTopicCharts(name, typ string) {
rname := nameReplacer.Replace(name)
chart := a.charts.Get(fmt.Sprintf("%s_%s_messages", typ, rname))
chart := c.charts.Get(fmt.Sprintf("%s_%s_messages", typ, rname))
chart.MarkRemove()
chart.MarkNotCreated()
chart = a.charts.Get(fmt.Sprintf("%s_%s_unprocessed_messages", typ, rname))
chart = c.charts.Get(fmt.Sprintf("%s_%s_unprocessed_messages", typ, rname))
chart.MarkRemove()
chart.MarkNotCreated()
chart = a.charts.Get(fmt.Sprintf("%s_%s_consumers", typ, rname))
chart = c.charts.Get(fmt.Sprintf("%s_%s_consumers", typ, rname))
chart.MarkRemove()
chart.MarkNotCreated()
}

View file

@ -25,8 +25,8 @@ func init() {
})
}
func New() *ActiveMQ {
return &ActiveMQ{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -56,7 +56,7 @@ type Config struct {
TopicsFilter string `yaml:"topics_filter,omitempty" json:"topics_filter"`
}
type ActiveMQ struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -70,39 +70,39 @@ type ActiveMQ struct {
topicsFilter matcher.Matcher
}
func (a *ActiveMQ) Configuration() any {
return a.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (a *ActiveMQ) Init() error {
if err := a.validateConfig(); err != nil {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
qf, err := a.initQueuesFiler()
qf, err := c.initQueuesFiler()
if err != nil {
return fmt.Errorf("init queues filer: %v", err)
}
a.queuesFilter = qf
c.queuesFilter = qf
tf, err := a.initTopicsFilter()
tf, err := c.initTopicsFilter()
if err != nil {
return fmt.Errorf("init topics filter: %v", err)
}
a.topicsFilter = tf
c.topicsFilter = tf
client, err := web.NewHTTPClient(a.ClientConfig)
client, err := web.NewHTTPClient(c.ClientConfig)
if err != nil {
return fmt.Errorf("create http client: %v", err)
}
a.apiClient = newAPIClient(client, a.RequestConfig, a.Webadmin)
c.apiClient = newAPIClient(client, c.RequestConfig, c.Webadmin)
return nil
}
func (a *ActiveMQ) Check() error {
mx, err := a.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -113,21 +113,21 @@ func (a *ActiveMQ) Check() error {
return nil
}
func (a *ActiveMQ) Charts() *Charts {
return a.charts
func (c *Collector) Charts() *Charts {
return c.charts
}
func (a *ActiveMQ) Cleanup() {
if a.apiClient != nil && a.apiClient.httpClient != nil {
a.apiClient.httpClient.CloseIdleConnections()
func (c *Collector) Cleanup() {
if c.apiClient != nil && c.apiClient.httpClient != nil {
c.apiClient.httpClient.CloseIdleConnections()
}
}
func (a *ActiveMQ) Collect() map[string]int64 {
mx, err := a.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
a.Error(err)
c.Error(err)
return nil
}

View file

@ -30,8 +30,8 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestActiveMQ_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &ActiveMQ{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
var (
@ -151,20 +151,20 @@ var (
}
)
func TestActiveMQ_Init(t *testing.T) {
job := New()
func TestCollector_Init(t *testing.T) {
collr := New()
// NG case
job.Webadmin = ""
assert.Error(t, job.Init())
collr.Webadmin = ""
assert.Error(t, collr.Init())
// OK case
job.Webadmin = "webadmin"
assert.NoError(t, job.Init())
assert.NotNil(t, job.apiClient)
collr.Webadmin = "webadmin"
assert.NoError(t, collr.Init())
assert.NotNil(t, collr.apiClient)
}
func TestActiveMQ_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -177,23 +177,23 @@ func TestActiveMQ_Check(t *testing.T) {
}))
defer ts.Close()
job := New()
job.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
job.Webadmin = "webadmin"
collr := New()
collr.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
collr.Webadmin = "webadmin"
require.NoError(t, job.Init())
require.NoError(t, job.Check())
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
}
func TestActiveMQ_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestActiveMQ_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
New().Cleanup()
}
func TestActiveMQ_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
var collectNum int
getQueues := func() string { return queuesData[collectNum] }
getTopics := func() string { return topicsData[collectNum] }
@ -210,12 +210,12 @@ func TestActiveMQ_Collect(t *testing.T) {
}))
defer ts.Close()
job := New()
job.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
job.Webadmin = "webadmin"
collr := New()
collr.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
collr.Webadmin = "webadmin"
require.NoError(t, job.Init())
require.NoError(t, job.Check())
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
cases := []struct {
expected map[string]int64
@ -303,38 +303,38 @@ func TestActiveMQ_Collect(t *testing.T) {
}
for _, c := range cases {
require.Equal(t, c.expected, job.Collect())
assert.Len(t, job.activeQueues, c.numQueues)
assert.Len(t, job.activeTopics, c.numTopics)
assert.Len(t, *job.charts, c.numCharts)
require.Equal(t, c.expected, collr.Collect())
assert.Len(t, collr.activeQueues, c.numQueues)
assert.Len(t, collr.activeTopics, c.numTopics)
assert.Len(t, *collr.charts, c.numCharts)
collectNum++
}
}
func TestActiveMQ_404(t *testing.T) {
func TestCollector_404(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
}))
defer ts.Close()
job := New()
job.Webadmin = "webadmin"
job.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
collr := New()
collr.Webadmin = "webadmin"
collr.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
require.NoError(t, job.Init())
assert.Error(t, job.Check())
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestActiveMQ_InvalidData(t *testing.T) {
func TestCollector_InvalidData(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and goodbye!"))
}))
defer ts.Close()
mod := New()
mod.Webadmin = "webadmin"
mod.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
collr := New()
collr.Webadmin = "webadmin"
collr.HTTPConfig.RequestConfig = web.RequestConfig{URL: ts.URL}
require.NoError(t, mod.Init())
assert.Error(t, mod.Check())
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}

View file

@ -8,26 +8,26 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/matcher"
)
func (a *ActiveMQ) validateConfig() error {
if a.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("url not set")
}
if a.Webadmin == "" {
if c.Webadmin == "" {
return errors.New("webadmin root path set")
}
return nil
}
func (a *ActiveMQ) initQueuesFiler() (matcher.Matcher, error) {
if a.QueuesFilter == "" {
func (c *Collector) initQueuesFiler() (matcher.Matcher, error) {
if c.QueuesFilter == "" {
return matcher.TRUE(), nil
}
return matcher.NewSimplePatternsMatcher(a.QueuesFilter)
return matcher.NewSimplePatternsMatcher(c.QueuesFilter)
}
func (a *ActiveMQ) initTopicsFilter() (matcher.Matcher, error) {
if a.TopicsFilter == "" {
func (c *Collector) initTopicsFilter() (matcher.Matcher, error) {
if c.TopicsFilter == "" {
return matcher.TRUE(), nil
}
return matcher.NewSimplePatternsMatcher(a.TopicsFilter)
return matcher.NewSimplePatternsMatcher(c.TopicsFilter)
}

View file

@ -85,7 +85,7 @@ var (
}
)
func (a *AdaptecRaid) addLogicalDeviceCharts(ld *logicalDevice) {
func (c *Collector) addLogicalDeviceCharts(ld *logicalDevice) {
charts := ldChartsTmpl.Copy()
for _, chart := range *charts {
@ -100,12 +100,12 @@ func (a *AdaptecRaid) addLogicalDeviceCharts(ld *logicalDevice) {
}
}
if err := a.Charts().Add(*charts...); err != nil {
a.Warning(err)
if err := c.Charts().Add(*charts...); err != nil {
c.Warning(err)
}
}
func (a *AdaptecRaid) addPhysicalDeviceCharts(pd *physicalDevice) {
func (c *Collector) addPhysicalDeviceCharts(pd *physicalDevice) {
charts := pdChartsTmpl.Copy()
if _, err := strconv.ParseInt(pd.temperature, 10, 64); err != nil {
@ -125,7 +125,7 @@ func (a *AdaptecRaid) addPhysicalDeviceCharts(pd *physicalDevice) {
}
}
if err := a.Charts().Add(*charts...); err != nil {
a.Warning(err)
if err := c.Charts().Add(*charts...); err != nil {
c.Warning(err)
}
}

View file

@ -8,13 +8,13 @@ import (
"strings"
)
func (a *AdaptecRaid) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
mx := make(map[string]int64)
if err := a.collectLogicalDevices(mx); err != nil {
if err := c.collectLogicalDevices(mx); err != nil {
return nil, err
}
if err := a.collectPhysicalDevices(mx); err != nil {
if err := c.collectPhysicalDevices(mx); err != nil {
return nil, err
}

View file

@ -20,8 +20,8 @@ type logicalDevice struct {
failedStripes string
}
func (a *AdaptecRaid) collectLogicalDevices(mx map[string]int64) error {
bs, err := a.exec.logicalDevicesInfo()
func (c *Collector) collectLogicalDevices(mx map[string]int64) error {
bs, err := c.exec.logicalDevicesInfo()
if err != nil {
return err
}
@ -36,9 +36,9 @@ func (a *AdaptecRaid) collectLogicalDevices(mx map[string]int64) error {
}
for _, ld := range devices {
if !a.lds[ld.number] {
a.lds[ld.number] = true
a.addLogicalDeviceCharts(ld)
if !c.lds[ld.number] {
c.lds[ld.number] = true
c.addLogicalDeviceCharts(ld)
}
px := fmt.Sprintf("ld_%s_", ld.number)

View file

@ -25,8 +25,8 @@ type physicalDevice struct {
temperature string
}
func (a *AdaptecRaid) collectPhysicalDevices(mx map[string]int64) error {
bs, err := a.exec.physicalDevicesInfo()
func (c *Collector) collectPhysicalDevices(mx map[string]int64) error {
bs, err := c.exec.physicalDevicesInfo()
if err != nil {
return err
}
@ -41,9 +41,9 @@ func (a *AdaptecRaid) collectPhysicalDevices(mx map[string]int64) error {
}
for _, pd := range devices {
if !a.pds[pd.number] {
a.pds[pd.number] = true
a.addPhysicalDeviceCharts(pd)
if !c.pds[pd.number] {
c.pds[pd.number] = true
c.addPhysicalDeviceCharts(pd)
}
px := fmt.Sprintf("pd_%s_", pd.number)

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *AdaptecRaid {
return &AdaptecRaid{
func New() *Collector {
return &Collector{
Config: Config{
Timeout: confopt.Duration(time.Second * 2),
},
@ -44,40 +44,34 @@ type Config struct {
Timeout confopt.Duration `yaml:"timeout,omitempty" json:"timeout"`
}
type (
AdaptecRaid struct {
module.Base
Config `yaml:",inline" json:""`
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
charts *module.Charts
charts *module.Charts
exec arcconfCli
exec arcconfCli
lds map[string]bool
pds map[string]bool
}
arcconfCli interface {
logicalDevicesInfo() ([]byte, error)
physicalDevicesInfo() ([]byte, error)
}
)
func (a *AdaptecRaid) Configuration() any {
return a.Config
lds map[string]bool
pds map[string]bool
}
func (a *AdaptecRaid) Init() error {
arcconfExec, err := a.initArcconfCliExec()
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Collector) Init() error {
arcconf, err := c.initArcconfCliExec()
if err != nil {
return fmt.Errorf("arcconf exec initialization: %v", err)
}
a.exec = arcconfExec
c.exec = arcconf
return nil
}
func (a *AdaptecRaid) Check() error {
mx, err := a.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -89,14 +83,14 @@ func (a *AdaptecRaid) Check() error {
return nil
}
func (a *AdaptecRaid) Charts() *module.Charts {
return a.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (a *AdaptecRaid) Collect() map[string]int64 {
mx, err := a.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
a.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -106,4 +100,4 @@ func (a *AdaptecRaid) Collect() map[string]int64 {
return mx
}
func (a *AdaptecRaid) Cleanup() {}
func (c *Collector) Cleanup() {}

View file

@ -39,11 +39,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestAdaptecRaid_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &AdaptecRaid{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestAdaptecRaid_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -56,58 +56,58 @@ func TestAdaptecRaid_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
adaptec := New()
collr := New()
if test.wantFail {
assert.Error(t, adaptec.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, adaptec.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestAdaptecRaid_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
tests := map[string]struct {
prepare func() *AdaptecRaid
prepare func() *Collector
}{
"not initialized exec": {
prepare: func() *AdaptecRaid {
prepare: func() *Collector {
return New()
},
},
"after check": {
prepare: func() *AdaptecRaid {
adaptec := New()
adaptec.exec = prepareMockOkCurrent()
_ = adaptec.Check()
return adaptec
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOkCurrent()
_ = collr.Check()
return collr
},
},
"after collect": {
prepare: func() *AdaptecRaid {
adaptec := New()
adaptec.exec = prepareMockOkCurrent()
_ = adaptec.Collect()
return adaptec
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOkCurrent()
_ = collr.Collect()
return collr
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
adaptec := test.prepare()
collr := test.prepare()
assert.NotPanics(t, adaptec.Cleanup)
assert.NotPanics(t, collr.Cleanup)
})
}
}
func TestAdaptecRaid_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestAdaptecRaid_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockArcconfExec
wantFail bool
@ -136,20 +136,20 @@ func TestAdaptecRaid_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
adaptec := New()
collr := New()
mock := test.prepareMock()
adaptec.exec = mock
collr.exec = mock
if test.wantFail {
assert.Error(t, adaptec.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, adaptec.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestAdaptecRaid_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockArcconfExec
wantMetrics map[string]int64
@ -214,14 +214,14 @@ func TestAdaptecRaid_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
adaptec := New()
collr := New()
mock := test.prepareMock()
adaptec.exec = mock
collr.exec = mock
mx := adaptec.Collect()
mx := collr.Collect()
assert.Equal(t, test.wantMetrics, mx)
assert.Len(t, *adaptec.Charts(), test.wantCharts)
assert.Len(t, *collr.Charts(), test.wantCharts)
})
}
}

View file

@ -13,6 +13,11 @@ import (
"github.com/netdata/netdata/go/plugins/logger"
)
type arcconfCli interface {
logicalDevicesInfo() ([]byte, error)
physicalDevicesInfo() ([]byte, error)
}
func newArcconfCliExec(ndsudoPath string, timeout time.Duration, log *logger.Logger) *arcconfCliExec {
return &arcconfCliExec{
Logger: log,

View file

@ -12,14 +12,14 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/executable"
)
func (a *AdaptecRaid) initArcconfCliExec() (arcconfCli, error) {
func (c *Collector) initArcconfCliExec() (arcconfCli, error) {
ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
if _, err := os.Stat(ndsudoPath); err != nil {
return nil, fmt.Errorf("ndsudo executable not found: %v", err)
}
arcconfExec := newArcconfCliExec(ndsudoPath, a.Timeout.Duration(), a.Logger)
arcconfExec := newArcconfCliExec(ndsudoPath, c.Timeout.Duration(), c.Logger)
return arcconfExec, nil
}

View file

@ -113,7 +113,7 @@ var (
}
)
func (a *AP) addInterfaceCharts(dev *iwInterface) {
func (c *Collector) addInterfaceCharts(dev *iwInterface) {
charts := apChartsTmpl.Copy()
for _, chart := range *charts {
@ -127,15 +127,15 @@ func (a *AP) addInterfaceCharts(dev *iwInterface) {
}
}
if err := a.Charts().Add(*charts...); err != nil {
a.Warning(err)
if err := c.Charts().Add(*charts...); err != nil {
c.Warning(err)
}
}
func (a *AP) removeInterfaceCharts(dev *iwInterface) {
func (c *Collector) removeInterfaceCharts(dev *iwInterface) {
px := fmt.Sprintf("ap_%s_%s_", dev.name, cleanSSID(dev.ssid))
for _, chart := range *a.Charts() {
for _, chart := range *c.Charts() {
if strings.HasPrefix(chart.ID, px) {
chart.MarkRemove()
chart.MarkNotCreated()

View file

@ -34,8 +34,8 @@ type stationStats struct {
rxBitrate float64
}
func (a *AP) collect() (map[string]int64, error) {
bs, err := a.exec.devices()
func (c *Collector) collect() (map[string]int64, error) {
bs, err := c.exec.devices()
if err != nil {
return nil, err
}
@ -54,7 +54,7 @@ func (a *AP) collect() (map[string]int64, error) {
seen := make(map[string]bool)
for _, iface := range apInterfaces {
bs, err = a.exec.stationStatistics(iface.name)
bs, err = c.exec.stationStatistics(iface.name)
if err != nil {
return nil, fmt.Errorf("getting station statistics for %s: %v", iface, err)
}
@ -68,9 +68,9 @@ func (a *AP) collect() (map[string]int64, error) {
seen[key] = true
if _, ok := a.seenIfaces[key]; !ok {
a.seenIfaces[key] = iface
a.addInterfaceCharts(iface)
if _, ok := c.seenIfaces[key]; !ok {
c.seenIfaces[key] = iface
c.addInterfaceCharts(iface)
}
px := fmt.Sprintf("ap_%s_%s_", iface.name, iface.ssid)
@ -90,10 +90,10 @@ func (a *AP) collect() (map[string]int64, error) {
}
}
for key, iface := range a.seenIfaces {
for key, iface := range c.seenIfaces {
if !seen[key] {
delete(a.seenIfaces, key)
a.removeInterfaceCharts(iface)
delete(c.seenIfaces, key)
c.removeInterfaceCharts(iface)
}
}

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *AP {
return &AP{
func New() *Collector {
return &Collector{
Config: Config{
BinaryPath: "/usr/sbin/iw",
Timeout: confopt.Duration(time.Second * 2),
@ -45,43 +45,37 @@ type Config struct {
BinaryPath string `yaml:"binary_path,omitempty" json:"binary_path"`
}
type (
AP struct {
module.Base
Config `yaml:",inline" json:""`
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
charts *module.Charts
charts *module.Charts
exec iwBinary
exec iwBinary
seenIfaces map[string]*iwInterface
}
iwBinary interface {
devices() ([]byte, error)
stationStatistics(ifaceName string) ([]byte, error)
}
)
func (a *AP) Configuration() any {
return a.Config
seenIfaces map[string]*iwInterface
}
func (a *AP) Init() error {
if err := a.validateConfig(); err != nil {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %s", err)
}
iw, err := a.initIwExec()
iw, err := c.initIwExec()
if err != nil {
return fmt.Errorf("iw exec initialization: %v", err)
}
a.exec = iw
c.exec = iw
return nil
}
func (a *AP) Check() error {
mx, err := a.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -93,14 +87,14 @@ func (a *AP) Check() error {
return nil
}
func (a *AP) Charts() *module.Charts {
return a.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (a *AP) Collect() map[string]int64 {
mx, err := a.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
a.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -110,4 +104,4 @@ func (a *AP) Collect() map[string]int64 {
return mx
}
func (a *AP) Cleanup() {}
func (c *Collector) Cleanup() {}

View file

@ -37,11 +37,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestAP_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &AP{}, dataConfigJSON, dataConfigYAML)
func TestCollector_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestAP_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -62,59 +62,59 @@ func TestAP_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
pf := New()
pf.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, pf.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, pf.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestAP_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
tests := map[string]struct {
prepare func() *AP
prepare func() *Collector
}{
"not initialized exec": {
prepare: func() *AP {
prepare: func() *Collector {
return New()
},
},
"after check": {
prepare: func() *AP {
ap := New()
ap.exec = prepareMockOk()
_ = ap.Check()
return ap
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOk()
_ = collr.Check()
return collr
},
},
"after collect": {
prepare: func() *AP {
ap := New()
ap.exec = prepareMockOk()
_ = ap.Collect()
return ap
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOk()
_ = collr.Collect()
return collr
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
pf := test.prepare()
collr := test.prepare()
assert.NotPanics(t, pf.Cleanup)
assert.NotPanics(t, collr.Cleanup)
})
}
}
func TestAP_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestAP_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockIwExec
wantFail bool
@ -143,19 +143,19 @@ func TestAP_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
ap := New()
ap.exec = test.prepareMock()
collr := New()
collr.exec = test.prepareMock()
if test.wantFail {
assert.Error(t, ap.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, ap.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestAP_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockIwExec
wantMetrics map[string]int64
@ -207,16 +207,16 @@ func TestAP_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
ap := New()
ap.exec = test.prepareMock()
collr := New()
collr.exec = test.prepareMock()
mx := ap.Collect()
mx := collr.Collect()
assert.Equal(t, test.wantMetrics, mx)
assert.Equal(t, test.wantCharts, len(*ap.Charts()), "wantCharts")
assert.Equal(t, test.wantCharts, len(*collr.Charts()), "wantCharts")
module.TestMetricsHasAllChartsDims(t, ap.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
})
}
}

View file

@ -13,6 +13,11 @@ import (
"github.com/netdata/netdata/go/plugins/logger"
)
type iwBinary interface {
devices() ([]byte, error)
stationStatistics(ifaceName string) ([]byte, error)
}
func newIwExec(binPath string, timeout time.Duration) *iwCliExec {
return &iwCliExec{
binPath: binPath,

View file

@ -11,15 +11,15 @@ import (
"strings"
)
func (a *AP) validateConfig() error {
if a.BinaryPath == "" {
func (c *Collector) validateConfig() error {
if c.BinaryPath == "" {
return errors.New("no iw binary path specified")
}
return nil
}
func (a *AP) initIwExec() (iwBinary, error) {
binPath := a.BinaryPath
func (c *Collector) initIwExec() (iwBinary, error) {
binPath := c.BinaryPath
if !strings.HasPrefix(binPath, "/") {
path, err := exec.LookPath(binPath)
@ -33,7 +33,7 @@ func (a *AP) initIwExec() (iwBinary, error) {
return nil, err
}
iw := newIwExec(binPath, a.Timeout.Duration())
iw := newIwExec(binPath, c.Timeout.Duration())
return iw, nil
}

View file

@ -13,24 +13,24 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (a *Apache) collect() (map[string]int64, error) {
status, err := a.scrapeStatus()
func (c *Collector) collect() (map[string]int64, error) {
status, err := c.scrapeStatus()
if err != nil {
return nil, err
}
mx := stm.ToMap(status)
if len(mx) == 0 {
return nil, fmt.Errorf("nothing was collected from %s", a.URL)
return nil, fmt.Errorf("nothing was collected from %s", c.URL)
}
a.once.Do(func() { a.charts = newCharts(status) })
c.once.Do(func() { c.charts = newCharts(status) })
return mx, nil
}
func (a *Apache) scrapeStatus() (*serverStatus, error) {
req, err := web.NewHTTPRequest(a.RequestConfig)
func (c *Collector) scrapeStatus() (*serverStatus, error) {
req, err := web.NewHTTPRequest(c.RequestConfig)
if err != nil {
return nil, err
}
@ -38,7 +38,7 @@ func (a *Apache) scrapeStatus() (*serverStatus, error) {
var stats *serverStatus
var perr error
if err := web.DoHTTP(a.httpClient).Request(req, func(body io.Reader) error {
if err := web.DoHTTP(c.httpClient).Request(req, func(body io.Reader) error {
if stats, perr = parseResponse(body); perr != nil {
return perr
}

View file

@ -26,8 +26,8 @@ func init() {
})
}
func New() *Apache {
return &Apache{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -48,7 +48,7 @@ type Config struct {
web.HTTPConfig `yaml:",inline" json:""`
}
type Apache struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -59,29 +59,29 @@ type Apache struct {
once *sync.Once
}
func (a *Apache) Configuration() any {
return a.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (a *Apache) Init() error {
if err := a.validateConfig(); err != nil {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
httpClient, err := a.initHTTPClient()
httpClient, err := c.initHTTPClient()
if err != nil {
return fmt.Errorf("init HTTP client: %v", err)
}
a.httpClient = httpClient
c.httpClient = httpClient
a.Debugf("using URL %s", a.URL)
a.Debugf("using timeout: %s", a.Timeout)
c.Debugf("using URL %s", c.URL)
c.Debugf("using timeout: %s", c.Timeout)
return nil
}
func (a *Apache) Check() error {
mx, err := a.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -92,14 +92,14 @@ func (a *Apache) Check() error {
return nil
}
func (a *Apache) Charts() *module.Charts {
return a.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (a *Apache) Collect() map[string]int64 {
mx, err := a.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
a.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -108,8 +108,8 @@ func (a *Apache) Collect() map[string]int64 {
return mx
}
func (a *Apache) Cleanup() {
if a.httpClient != nil {
a.httpClient.CloseIdleConnections()
func (c *Collector) Cleanup() {
if c.httpClient != nil {
c.httpClient.CloseIdleConnections()
}
}

View file

@ -39,11 +39,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestApache_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Apache{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestApache_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
wantFail bool
config Config
@ -72,22 +72,22 @@ func TestApache_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apache := New()
apache.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, apache.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, apache.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestApache_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
wantFail bool
prepare func(t *testing.T) (apache *Apache, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
}{
"success on simple status MPM Event": {
wantFail: false,
@ -121,25 +121,25 @@ func TestApache_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apache, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, apache.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, apache.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestApache_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestApache_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func(t *testing.T) (apache *Apache, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
wantNumOfCharts int
wantMetrics map[string]int64
}{
@ -244,102 +244,102 @@ func TestApache_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apache, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
_ = apache.Check()
_ = collr.Check()
collected := apache.Collect()
collected := collr.Collect()
require.Equal(t, test.wantMetrics, collected)
assert.Equal(t, test.wantNumOfCharts, len(*apache.Charts()))
assert.Equal(t, test.wantNumOfCharts, len(*collr.Charts()))
})
}
}
func caseMPMEventSimpleStatus(t *testing.T) (*Apache, func()) {
func caseMPMEventSimpleStatus(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataSimpleStatusMPMEvent)
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}
func caseMPMEventExtendedStatus(t *testing.T) (*Apache, func()) {
func caseMPMEventExtendedStatus(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataExtendedStatusMPMEvent)
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}
func caseMPMPreforkExtendedStatus(t *testing.T) (*Apache, func()) {
func caseMPMPreforkExtendedStatus(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataExtendedStatusMPMPrefork)
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}
func caseLighttpdResponse(t *testing.T) (*Apache, func()) {
func caseLighttpdResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataLighttpdStatus)
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}
func caseInvalidDataResponse(t *testing.T) (*Apache, func()) {
func caseInvalidDataResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}
func caseConnectionRefused(t *testing.T) (*Apache, func()) {
func caseConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
apache := New()
apache.URL = "http://127.0.0.1:65001/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = "http://127.0.0.1:65001/server-status?auto"
require.NoError(t, collr.Init())
return apache, func() {}
return collr, func() {}
}
func case404(t *testing.T) (*Apache, func()) {
func case404(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
apache := New()
apache.URL = srv.URL + "/server-status?auto"
require.NoError(t, apache.Init())
collr := New()
collr.URL = srv.URL + "/server-status?auto"
require.NoError(t, collr.Init())
return apache, srv.Close
return collr, srv.Close
}

View file

@ -10,16 +10,16 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (a *Apache) validateConfig() error {
if a.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("url not set")
}
if !strings.HasSuffix(a.URL, "?auto") {
if !strings.HasSuffix(c.URL, "?auto") {
return errors.New("invalid URL, should ends in '?auto'")
}
return nil
}
func (a *Apache) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(a.ClientConfig)
func (c *Collector) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(c.ClientConfig)
}

View file

@ -11,31 +11,31 @@ import (
const precision = 100
func (a *Apcupsd) collect() (map[string]int64, error) {
if a.conn == nil {
conn, err := a.establishConnection()
func (c *Collector) collect() (map[string]int64, error) {
if c.conn == nil {
conn, err := c.establishConnection()
if err != nil {
return nil, err
}
a.conn = conn
c.conn = conn
}
resp, err := a.conn.status()
resp, err := c.conn.status()
if err != nil {
a.Cleanup()
c.Cleanup()
return nil, err
}
mx := make(map[string]int64)
if err := a.collectStatus(mx, resp); err != nil {
if err := c.collectStatus(mx, resp); err != nil {
return nil, err
}
return mx, nil
}
func (a *Apcupsd) collectStatus(mx map[string]int64, resp []byte) error {
func (c *Collector) collectStatus(mx map[string]int64, resp []byte) error {
st, err := parseStatus(resp)
if err != nil {
return fmt.Errorf("failed to parse status: %v", err)
@ -105,7 +105,7 @@ func (a *Apcupsd) collectStatus(mx map[string]int64, resp []byte) error {
}
if st.battdate != "" {
if v, err := battdateSecondsAgo(st.battdate); err != nil {
a.Debugf("failed to calculate time since battery replacement for date '%s': %v", st.battdate, err)
c.Debugf("failed to calculate time since battery replacement for date '%s': %v", st.battdate, err)
} else {
mx["battery_seconds_since_replacement"] = v
}
@ -133,8 +133,8 @@ func battdateSecondsAgo(battdate string) (int64, error) {
return secsAgo, nil
}
func (a *Apcupsd) establishConnection() (apcupsdConn, error) {
conn := a.newConn(a.Config)
func (c *Collector) establishConnection() (apcupsdConn, error) {
conn := c.newConn(c.Config)
if err := conn.connect(); err != nil {
return nil, err

View file

@ -22,8 +22,8 @@ func init() {
})
}
func New() *Apcupsd {
return &Apcupsd{
func New() *Collector {
return &Collector{
Config: Config{
Address: "127.0.0.1:3551",
Timeout: confopt.Duration(time.Second * 3),
@ -39,7 +39,7 @@ type Config struct {
Timeout confopt.Duration `yaml:"timeout,omitempty" json:"timeout"`
}
type Apcupsd struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -49,20 +49,20 @@ type Apcupsd struct {
newConn func(Config) apcupsdConn
}
func (a *Apcupsd) Configuration() any {
return a.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (a *Apcupsd) Init() error {
if a.Address == "" {
func (c *Collector) Init() error {
if c.Address == "" {
return errors.New("config: 'address' not set")
}
return nil
}
func (a *Apcupsd) Check() error {
mx, err := a.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -72,14 +72,14 @@ func (a *Apcupsd) Check() error {
return nil
}
func (a *Apcupsd) Charts() *module.Charts {
return a.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (a *Apcupsd) Collect() map[string]int64 {
mx, err := a.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
a.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -88,11 +88,11 @@ func (a *Apcupsd) Collect() map[string]int64 {
return mx
}
func (a *Apcupsd) Cleanup() {
if a.conn != nil {
if err := a.conn.disconnect(); err != nil {
a.Warningf("error on disconnect: %v", err)
func (c *Collector) Cleanup() {
if c.conn != nil {
if err := c.conn.disconnect(); err != nil {
c.Warningf("error on disconnect: %v", err)
}
a.conn = nil
c.conn = nil
}
}

View file

@ -33,25 +33,24 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestApcupsd_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Apcupsd{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestApcupsd_Cleanup(t *testing.T) {
apc := New()
require.NotPanics(t, apc.Cleanup)
func TestCollector_Cleanup(t *testing.T) {
collr := New()
require.NotPanics(t, collr.Cleanup)
mock := prepareMockOk()
apc.newConn = func(Config) apcupsdConn { return mock }
collr.newConn = func(Config) apcupsdConn { return mock }
require.NoError(t, apc.Init())
_ = apc.Collect()
require.NotPanics(t, apc.Cleanup)
require.NoError(t, collr.Init())
_ = collr.Collect()
require.NotPanics(t, collr.Cleanup)
assert.True(t, mock.calledDisconnect)
}
func TestApcupsd_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -68,19 +67,19 @@ func TestApcupsd_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apc := New()
apc.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, apc.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, apc.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestApcupsd_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockApcupsdConn
wantFail bool
@ -105,27 +104,27 @@ func TestApcupsd_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apc := New()
apc.newConn = func(Config) apcupsdConn { return test.prepareMock() }
collr := New()
collr.newConn = func(Config) apcupsdConn { return test.prepareMock() }
require.NoError(t, apc.Init())
require.NoError(t, collr.Init())
if test.wantFail {
assert.Error(t, apc.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, apc.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestApcupsd_Charts(t *testing.T) {
apc := New()
require.NoError(t, apc.Init())
assert.NotNil(t, apc.Charts())
func TestCollector_Charts(t *testing.T) {
collr := New()
require.NoError(t, collr.Init())
assert.NotNil(t, collr.Charts())
}
func TestApcupsd_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockApcupsdConn
wantCollected map[string]int64
@ -205,13 +204,13 @@ func TestApcupsd_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
apc := New()
require.NoError(t, apc.Init())
collr := New()
require.NoError(t, collr.Init())
mock := test.prepareMock()
apc.newConn = func(Config) apcupsdConn { return mock }
collr.newConn = func(Config) apcupsdConn { return mock }
mx := apc.Collect()
mx := collr.Collect()
if _, ok := mx["battery_seconds_since_replacement"]; ok {
mx["battery_seconds_since_replacement"] = 86400
@ -221,11 +220,11 @@ func TestApcupsd_Collect(t *testing.T) {
if len(test.wantCollected) > 0 {
if strings.Contains(name, "commlost") {
module.TestMetricsHasAllChartsDimsSkip(t, apc.Charts(), mx, func(chart *module.Chart, _ *module.Dim) bool {
module.TestMetricsHasAllChartsDimsSkip(t, collr.Charts(), mx, func(chart *module.Chart, _ *module.Dim) bool {
return chart.ID != statusChart.ID
})
} else {
module.TestMetricsHasAllChartsDims(t, apc.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
}

View file

@ -297,7 +297,7 @@ var (
}
)
func (b *Beanstalk) addTubeCharts(name string) {
func (c *Collector) addTubeCharts(name string) {
charts := tubeChartsTmpl.Copy()
for _, chart := range *charts {
@ -311,15 +311,15 @@ func (b *Beanstalk) addTubeCharts(name string) {
}
}
if err := b.Charts().Add(*charts...); err != nil {
b.Warning(err)
if err := c.Charts().Add(*charts...); err != nil {
c.Warning(err)
}
}
func (b *Beanstalk) removeTubeCharts(name string) {
func (c *Collector) removeTubeCharts(name string) {
px := fmt.Sprintf("tube_%s_", cleanTubeName(name))
for _, chart := range *b.Charts() {
for _, chart := range *c.Charts() {
if strings.HasPrefix(chart.ID, px) {
chart.MarkRemove()
chart.MarkNotCreated()

View file

@ -10,30 +10,30 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/stm"
)
func (b *Beanstalk) collect() (map[string]int64, error) {
if b.conn == nil {
conn, err := b.establishConn()
func (c *Collector) collect() (map[string]int64, error) {
if c.conn == nil {
conn, err := c.establishConn()
if err != nil {
return nil, err
}
b.conn = conn
c.conn = conn
}
mx := make(map[string]int64)
if err := b.collectStats(mx); err != nil {
b.Cleanup()
if err := c.collectStats(mx); err != nil {
c.Cleanup()
return nil, err
}
if err := b.collectTubesStats(mx); err != nil {
if err := c.collectTubesStats(mx); err != nil {
return mx, err
}
return mx, nil
}
func (b *Beanstalk) collectStats(mx map[string]int64) error {
stats, err := b.conn.queryStats()
func (c *Collector) collectStats(mx map[string]int64) error {
stats, err := c.conn.queryStats()
if err != nil {
return err
}
@ -43,52 +43,52 @@ func (b *Beanstalk) collectStats(mx map[string]int64) error {
return nil
}
func (b *Beanstalk) collectTubesStats(mx map[string]int64) error {
func (c *Collector) collectTubesStats(mx map[string]int64) error {
now := time.Now()
if now.Sub(b.lastDiscoverTubesTime) > b.discoverTubesEvery {
tubes, err := b.conn.queryListTubes()
if now.Sub(c.lastDiscoverTubesTime) > c.discoverTubesEvery {
tubes, err := c.conn.queryListTubes()
if err != nil {
return err
}
b.Debugf("discovered tubes (%d): %v", len(tubes), tubes)
v := slices.DeleteFunc(tubes, func(s string) bool { return !b.tubeSr.MatchString(s) })
c.Debugf("discovered tubes (%d): %v", len(tubes), tubes)
v := slices.DeleteFunc(tubes, func(s string) bool { return !c.tubeSr.MatchString(s) })
if len(tubes) != len(v) {
b.Debugf("discovered tubes after filtering (%d): %v", len(v), v)
c.Debugf("discovered tubes after filtering (%d): %v", len(v), v)
}
b.discoveredTubes = v
b.lastDiscoverTubesTime = now
c.discoveredTubes = v
c.lastDiscoverTubesTime = now
}
seen := make(map[string]bool)
for i, tube := range b.discoveredTubes {
for i, tube := range c.discoveredTubes {
if tube == "" {
continue
}
stats, err := b.conn.queryStatsTube(tube)
stats, err := c.conn.queryStatsTube(tube)
if err != nil {
return err
}
if stats == nil {
b.Infof("tube '%s' stats object not found (tube does not exist)", tube)
b.discoveredTubes[i] = ""
c.Infof("tube '%s' stats object not found (tube does not exist)", tube)
c.discoveredTubes[i] = ""
continue
}
if stats.Name == "" {
b.Debugf("tube '%s' stats object has an empty name, ignoring it", tube)
b.discoveredTubes[i] = ""
c.Debugf("tube '%s' stats object has an empty name, ignoring it", tube)
c.discoveredTubes[i] = ""
continue
}
seen[stats.Name] = true
if !b.seenTubes[stats.Name] {
b.seenTubes[stats.Name] = true
b.addTubeCharts(stats.Name)
if !c.seenTubes[stats.Name] {
c.seenTubes[stats.Name] = true
c.addTubeCharts(stats.Name)
}
px := fmt.Sprintf("tube_%s_", stats.Name)
@ -97,18 +97,18 @@ func (b *Beanstalk) collectTubesStats(mx map[string]int64) error {
}
}
for tube := range b.seenTubes {
for tube := range c.seenTubes {
if !seen[tube] {
delete(b.seenTubes, tube)
b.removeTubeCharts(tube)
delete(c.seenTubes, tube)
c.removeTubeCharts(tube)
}
}
return nil
}
func (b *Beanstalk) establishConn() (beanstalkConn, error) {
conn := b.newConn(b.Config, b.Logger)
func (c *Collector) establishConn() (beanstalkConn, error) {
conn := c.newConn(c.Config, c.Logger)
if err := conn.connect(); err != nil {
return nil, err

View file

@ -25,8 +25,8 @@ func init() {
})
}
func New() *Beanstalk {
return &Beanstalk{
func New() *Collector {
return &Collector{
Config: Config{
Address: "127.0.0.1:11300",
Timeout: confopt.Duration(time.Second * 1),
@ -48,7 +48,7 @@ type Config struct {
TubeSelector string `yaml:"tube_selector,omitempty" json:"tube_selector"`
}
type Beanstalk struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -64,26 +64,26 @@ type Beanstalk struct {
seenTubes map[string]bool
}
func (b *Beanstalk) Configuration() any {
return b.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (b *Beanstalk) Init() error {
if err := b.validateConfig(); err != nil {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
sr, err := b.initTubeSelector()
sr, err := c.initTubeSelector()
if err != nil {
return fmt.Errorf("failed to init tube selector: %v", err)
}
b.tubeSr = sr
c.tubeSr = sr
return nil
}
func (b *Beanstalk) Check() error {
mx, err := b.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -95,14 +95,14 @@ func (b *Beanstalk) Check() error {
return nil
}
func (b *Beanstalk) Charts() *module.Charts {
return b.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (b *Beanstalk) Collect() map[string]int64 {
mx, err := b.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
b.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -112,11 +112,11 @@ func (b *Beanstalk) Collect() map[string]int64 {
return mx
}
func (b *Beanstalk) Cleanup() {
if b.conn != nil {
if err := b.conn.disconnect(); err != nil {
b.Warningf("error on disconnect: %s", err)
func (c *Collector) Cleanup() {
if c.conn != nil {
if err := c.conn.disconnect(); err != nil {
c.Warningf("error on disconnect: %s", err)
}
b.conn = nil
c.conn = nil
}
}

View file

@ -39,11 +39,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestBeanstalk_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Beanstalk{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestBeanstalk_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -64,25 +64,25 @@ func TestBeanstalk_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
beans := New()
beans.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, beans.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, beans.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestBeanstalk_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestBeanstalk_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepare func() (*Beanstalk, *mockBeanstalkDaemon)
prepare func() (*Collector, *mockBeanstalkDaemon)
wantFail bool
}{
"success on valid response": {
@ -100,7 +100,7 @@ func TestBeanstalk_Check(t *testing.T) {
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
beanstalk, daemon := test.prepare()
collr, daemon := test.prepare()
defer func() {
assert.NoError(t, daemon.Close(), "daemon.Close()")
@ -112,31 +112,31 @@ func TestBeanstalk_Check(t *testing.T) {
select {
case <-daemon.started:
case <-time.After(time.Second * 3):
t.Errorf("mock beanstalk daemon start timed out")
t.Errorf("mock collr daemon start timed out")
}
require.NoError(t, beanstalk.Init())
require.NoError(t, collr.Init())
if test.wantFail {
assert.Error(t, beanstalk.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, beanstalk.Check())
assert.NoError(t, collr.Check())
}
beanstalk.Cleanup()
collr.Cleanup()
select {
case <-daemon.stopped:
case <-time.After(time.Second * 3):
t.Errorf("mock beanstalk daemon stop timed out")
t.Errorf("mock collr daemon stop timed out")
}
})
}
}
func TestBeanstalk_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func() (*Beanstalk, *mockBeanstalkDaemon)
prepare func() (*Collector, *mockBeanstalkDaemon)
wantMetrics map[string]int64
wantCharts int
}{
@ -211,7 +211,7 @@ func TestBeanstalk_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
beanstalk, daemon := test.prepare()
collr, daemon := test.prepare()
defer func() {
assert.NoError(t, daemon.Close(), "daemon.Close()")
@ -223,33 +223,33 @@ func TestBeanstalk_Collect(t *testing.T) {
select {
case <-daemon.started:
case <-time.After(time.Second * 3):
t.Errorf("mock beanstalk daemon start timed out")
t.Errorf("mock collr daemon start timed out")
}
require.NoError(t, beanstalk.Init())
require.NoError(t, collr.Init())
mx := beanstalk.Collect()
mx := collr.Collect()
require.Equal(t, test.wantMetrics, mx)
assert.Equal(t, test.wantCharts, len(*beanstalk.Charts()), "want charts")
assert.Equal(t, test.wantCharts, len(*collr.Charts()), "want charts")
if len(test.wantMetrics) > 0 {
module.TestMetricsHasAllChartsDims(t, beanstalk.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
beanstalk.Cleanup()
collr.Cleanup()
select {
case <-daemon.stopped:
case <-time.After(time.Second * 3):
t.Errorf("mock beanstalk daemon stop timed out")
t.Errorf("mock collr daemon stop timed out")
}
})
}
}
func prepareCaseOk() (*Beanstalk, *mockBeanstalkDaemon) {
func prepareCaseOk() (*Collector, *mockBeanstalkDaemon) {
daemon := &mockBeanstalkDaemon{
addr: "127.0.0.1:65001",
started: make(chan struct{}),
@ -259,13 +259,13 @@ func prepareCaseOk() (*Beanstalk, *mockBeanstalkDaemon) {
dataStatsTube: dataStatsTubeDefault,
}
beanstalk := New()
beanstalk.Address = daemon.addr
collr := New()
collr.Address = daemon.addr
return beanstalk, daemon
return collr, daemon
}
func prepareCaseUnexpectedResponse() (*Beanstalk, *mockBeanstalkDaemon) {
func prepareCaseUnexpectedResponse() (*Collector, *mockBeanstalkDaemon) {
daemon := &mockBeanstalkDaemon{
addr: "127.0.0.1:65001",
started: make(chan struct{}),
@ -275,13 +275,13 @@ func prepareCaseUnexpectedResponse() (*Beanstalk, *mockBeanstalkDaemon) {
dataStatsTube: []byte("INTERNAL_ERROR\n"),
}
beanstalk := New()
beanstalk.Address = daemon.addr
collr := New()
collr.Address = daemon.addr
return beanstalk, daemon
return collr, daemon
}
func prepareCaseConnectionRefused() (*Beanstalk, *mockBeanstalkDaemon) {
func prepareCaseConnectionRefused() (*Collector, *mockBeanstalkDaemon) {
ch := make(chan struct{})
close(ch)
daemon := &mockBeanstalkDaemon{
@ -291,10 +291,10 @@ func prepareCaseConnectionRefused() (*Beanstalk, *mockBeanstalkDaemon) {
stopped: ch,
}
beanstalk := New()
beanstalk.Address = daemon.addr
collr := New()
collr.Address = daemon.addr
return beanstalk, daemon
return collr, daemon
}
type mockBeanstalkDaemon struct {

View file

@ -8,19 +8,19 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/matcher"
)
func (b *Beanstalk) validateConfig() error {
if b.Address == "" {
func (c *Collector) validateConfig() error {
if c.Address == "" {
return errors.New("beanstalk address is required")
}
return nil
}
func (b *Beanstalk) initTubeSelector() (matcher.Matcher, error) {
if b.TubeSelector == "" {
func (c *Collector) initTubeSelector() (matcher.Matcher, error) {
if c.TubeSelector == "" {
return matcher.TRUE(), nil
}
m, err := matcher.NewSimplePatternsMatcher(b.TubeSelector)
m, err := matcher.NewSimplePatternsMatcher(c.TubeSelector)
if err != nil {
return nil, err
}

View file

@ -9,19 +9,19 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
)
func (b *Bind) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
mx := make(map[string]int64)
s, err := b.serverStats()
s, err := c.serverStats()
if err != nil {
return nil, err
}
b.collectServerStats(mx, s)
c.collectServerStats(mx, s)
return mx, nil
}
func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats) {
func (c *Collector) collectServerStats(metrics map[string]int64, stats *serverStats) {
var chart *Chart
for k, v := range stats.NSStats {
@ -63,11 +63,11 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
chartID = keyReceivedUpdates
}
if !b.charts.Has(chartID) {
_ = b.charts.Add(charts[chartID].Copy())
if !c.charts.Has(chartID) {
_ = c.charts.Add(charts[chartID].Copy())
}
chart = b.charts.Get(chartID)
chart = c.charts.Get(chartID)
if !chart.HasDim(k) {
_ = chart.AddDim(&Dim{ID: k, Name: dimName, Algo: algo})
@ -91,11 +91,11 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
continue
}
if !b.charts.Has(v.chartID) {
_ = b.charts.Add(charts[v.chartID].Copy())
if !c.charts.Has(v.chartID) {
_ = c.charts.Add(charts[v.chartID].Copy())
}
chart = b.charts.Get(v.chartID)
chart = c.charts.Get(v.chartID)
for key, val := range v.item {
if !chart.HasDim(key) {
@ -107,12 +107,12 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
}
}
if !(b.permitView != nil && len(stats.Views) > 0) {
if !(c.permitView != nil && len(stats.Views) > 0) {
return
}
for name, view := range stats.Views {
if !b.permitView.MatchString(name) {
if !c.permitView.MatchString(name) {
continue
}
r := view.Resolver
@ -140,14 +140,14 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
chartID := fmt.Sprintf(chartKey, name)
if !b.charts.Has(chartID) {
if !c.charts.Has(chartID) {
chart = charts[chartKey].Copy()
chart.ID = chartID
chart.Fam = fmt.Sprintf(chart.Fam, name)
_ = b.charts.Add(chart)
_ = c.charts.Add(chart)
}
chart = b.charts.Get(chartID)
chart = c.charts.Get(chartID)
dimID := fmt.Sprintf("%s_%s", name, key)
if !chart.HasDim(dimID) {
@ -161,14 +161,14 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
if len(r.QTypes) > 0 {
chartID := fmt.Sprintf(keyResolverInQTypes, name)
if !b.charts.Has(chartID) {
if !c.charts.Has(chartID) {
chart = charts[keyResolverInQTypes].Copy()
chart.ID = chartID
chart.Fam = fmt.Sprintf(chart.Fam, name)
_ = b.charts.Add(chart)
_ = c.charts.Add(chart)
}
chart = b.charts.Get(chartID)
chart = c.charts.Get(chartID)
for key, val := range r.QTypes {
dimID := fmt.Sprintf("%s_%s", name, key)
@ -183,11 +183,11 @@ func (b *Bind) collectServerStats(metrics map[string]int64, stats *serverStats)
if len(r.CacheStats) > 0 {
chartID := fmt.Sprintf(keyResolverCacheHits, name)
if !b.charts.Has(chartID) {
if !c.charts.Has(chartID) {
chart = charts[keyResolverCacheHits].Copy()
chart.ID = chartID
chart.Fam = fmt.Sprintf(chart.Fam, name)
_ = b.charts.Add(chart)
_ = c.charts.Add(chart)
for _, dim := range chart.Dims {
dim.ID = fmt.Sprintf(dim.ID, name)
}

View file

@ -26,8 +26,8 @@ func init() {
})
}
func New() *Bind {
return &Bind{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -49,7 +49,7 @@ type Config struct {
}
type (
Bind struct {
Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -66,40 +66,40 @@ type (
}
)
func (b *Bind) Configuration() any {
return b.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (b *Bind) Init() error {
if err := b.validateConfig(); err != nil {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config verification: %v", err)
}
pvm, err := b.initPermitViewMatcher()
pvm, err := c.initPermitViewMatcher()
if err != nil {
return fmt.Errorf("init permit view matcher: %v", err)
}
if pvm != nil {
b.permitView = pvm
c.permitView = pvm
}
httpClient, err := web.NewHTTPClient(b.ClientConfig)
httpClient, err := web.NewHTTPClient(c.ClientConfig)
if err != nil {
return fmt.Errorf("creating http client : %v", err)
}
b.httpClient = httpClient
c.httpClient = httpClient
bindClient, err := b.initBindApiClient(httpClient)
bindClient, err := c.initBindApiClient(httpClient)
if err != nil {
return fmt.Errorf("init bind api client: %v", err)
}
b.bindAPIClient = bindClient
c.bindAPIClient = bindClient
return nil
}
func (b *Bind) Check() error {
mx, err := b.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -110,23 +110,23 @@ func (b *Bind) Check() error {
return nil
}
func (b *Bind) Charts() *Charts {
return b.charts
func (c *Collector) Charts() *Charts {
return c.charts
}
func (b *Bind) Collect() map[string]int64 {
mx, err := b.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
b.Error(err)
c.Error(err)
return nil
}
return mx
}
func (b *Bind) Cleanup() {
if b.httpClient != nil {
b.httpClient.CloseIdleConnections()
func (c *Collector) Cleanup() {
if c.httpClient != nil {
c.httpClient.CloseIdleConnections()
}
}

View file

@ -34,25 +34,25 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestBind_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Bind{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestBind_Cleanup(t *testing.T) { New().Cleanup() }
func TestCollector_Cleanup(t *testing.T) { New().Cleanup() }
func TestBind_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
// OK
job := New()
assert.NoError(t, job.Init())
assert.NotNil(t, job.bindAPIClient)
collr := New()
assert.NoError(t, collr.Init())
assert.NotNil(t, collr.bindAPIClient)
//NG
job = New()
job.URL = ""
assert.Error(t, job.Init())
collr = New()
collr.URL = ""
assert.Error(t, collr.Init())
}
func TestBind_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -62,26 +62,26 @@ func TestBind_Check(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/json/v1"
collr := New()
collr.URL = ts.URL + "/json/v1"
require.NoError(t, job.Init())
require.NoError(t, job.Check())
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
}
func TestBind_CheckNG(t *testing.T) {
job := New()
func TestCollector_CheckNG(t *testing.T) {
collr := New()
job.URL = "http://127.0.0.1:38001/xml/v3"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
collr.URL = "http://127.0.0.1:38001/xml/v3"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestBind_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestBind_CollectJSON(t *testing.T) {
func TestCollector_CollectJSON(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -91,12 +91,12 @@ func TestBind_CollectJSON(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/json/v1"
job.PermitView = "*"
collr := New()
collr.URL = ts.URL + "/json/v1"
collr.PermitView = "*"
require.NoError(t, job.Init())
require.NoError(t, job.Check())
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
expected := map[string]int64{
"_default_Queryv4": 4503685324,
@ -254,11 +254,11 @@ func TestBind_CollectJSON(t *testing.T) {
"Others": 74006,
}
assert.Equal(t, expected, job.Collect())
assert.Len(t, *job.charts, 17)
assert.Equal(t, expected, collr.Collect())
assert.Len(t, *collr.charts, 17)
}
func TestBind_CollectXML3(t *testing.T) {
func TestCollector_CollectXML3(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -268,12 +268,12 @@ func TestBind_CollectXML3(t *testing.T) {
}))
defer ts.Close()
job := New()
job.PermitView = "*"
job.URL = ts.URL + "/xml/v3"
collr := New()
collr.PermitView = "*"
collr.URL = ts.URL + "/xml/v3"
require.NoError(t, job.Init())
require.NoError(t, job.Check())
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
expected := map[string]int64{
"_bind_CookieClientOk": 0,
@ -507,26 +507,26 @@ func TestBind_CollectXML3(t *testing.T) {
"IQUERY": 199,
}
assert.Equal(t, expected, job.Collect())
assert.Len(t, *job.charts, 20)
assert.Equal(t, expected, collr.Collect())
assert.Len(t, *collr.charts, 20)
}
func TestBind_InvalidData(t *testing.T) {
func TestCollector_InvalidData(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("hello and goodbye")) }))
defer ts.Close()
job := New()
job.URL = ts.URL + "/json/v1"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
collr := New()
collr.URL = ts.URL + "/json/v1"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestBind_404(t *testing.T) {
func TestCollector_404(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) }))
defer ts.Close()
job := New()
job.URL = ts.URL + "/json/v1"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
collr := New()
collr.URL = ts.URL + "/json/v1"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}

View file

@ -11,27 +11,27 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/matcher"
)
func (b *Bind) validateConfig() error {
if b.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("url not set")
}
return nil
}
func (b *Bind) initPermitViewMatcher() (matcher.Matcher, error) {
if b.PermitView == "" {
func (c *Collector) initPermitViewMatcher() (matcher.Matcher, error) {
if c.PermitView == "" {
return nil, nil
}
return matcher.NewSimplePatternsMatcher(b.PermitView)
return matcher.NewSimplePatternsMatcher(c.PermitView)
}
func (b *Bind) initBindApiClient(httpClient *http.Client) (bindAPIClient, error) {
func (c *Collector) initBindApiClient(httpClient *http.Client) (bindAPIClient, error) {
switch {
case strings.HasSuffix(b.URL, "/xml/v3"): // BIND 9.9+
return newXML3Client(httpClient, b.RequestConfig), nil
case strings.HasSuffix(b.URL, "/json/v1"): // BIND 9.10+
return newJSONClient(httpClient, b.RequestConfig), nil
case strings.HasSuffix(c.URL, "/xml/v3"): // BIND 9.9+
return newXML3Client(httpClient, c.RequestConfig), nil
case strings.HasSuffix(c.URL, "/json/v1"): // BIND 9.10+
return newJSONClient(httpClient, c.RequestConfig), nil
default:
return nil, fmt.Errorf("URL %s is wrong, supported endpoints: `/xml/v3`, `/json/v1`", b.URL)
return nil, fmt.Errorf("URL %s is wrong, supported endpoints: `/xml/v3`, `/json/v1`", c.URL)
}
}

View file

@ -7,31 +7,31 @@ import (
"net"
)
func (b *Boinc) collect() (map[string]int64, error) {
if b.conn == nil {
conn, err := b.establishConn()
func (c *Collector) collect() (map[string]int64, error) {
if c.conn == nil {
conn, err := c.establishConn()
if err != nil {
return nil, err
}
b.conn = conn
c.conn = conn
}
results, err := b.conn.getResults()
results, err := c.conn.getResults()
if err != nil {
b.Cleanup()
c.Cleanup()
return nil, err
}
mx := make(map[string]int64)
if err := b.collectResults(mx, results); err != nil {
if err := c.collectResults(mx, results); err != nil {
return nil, err
}
return mx, nil
}
func (b *Boinc) collectResults(mx map[string]int64, results []boincReplyResult) error {
func (c *Collector) collectResults(mx map[string]int64, results []boincReplyResult) error {
mx["total"] = int64(len(results))
mx["active"] = 0
@ -57,14 +57,14 @@ func (b *Boinc) collectResults(mx map[string]int64, results []boincReplyResult)
return nil
}
func (b *Boinc) establishConn() (boincConn, error) {
conn := b.newConn(b.Config, b.Logger)
func (c *Collector) establishConn() (boincConn, error) {
conn := c.newConn(c.Config, c.Logger)
if err := conn.connect(); err != nil {
return nil, fmt.Errorf("failed to establish connection: %w", err)
}
if host, _, err := net.SplitHostPort(b.Address); err == nil {
if host, _, err := net.SplitHostPort(c.Address); err == nil {
// for the commands we use, authentication is only required for remote connections
ip := net.ParseIP(host)
if host == "localhost" || (ip != nil && ip.IsLoopback()) {

View file

@ -23,8 +23,8 @@ func init() {
})
}
func New() *Boinc {
return &Boinc{
func New() *Collector {
return &Collector{
Config: Config{
Address: "127.0.0.1:31416",
Timeout: confopt.Duration(time.Second * 1),
@ -41,7 +41,7 @@ type Config struct {
Password string `yaml:"password" json:"password"`
}
type Boinc struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -51,20 +51,20 @@ type Boinc struct {
conn boincConn
}
func (b *Boinc) Configuration() any {
return b.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (b *Boinc) Init() error {
if b.Address == "" {
func (c *Collector) Init() error {
if c.Address == "" {
return errors.New("config: 'address' not set")
}
return nil
}
func (b *Boinc) Check() error {
mx, err := b.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -76,14 +76,14 @@ func (b *Boinc) Check() error {
return nil
}
func (b *Boinc) Charts() *module.Charts {
return b.charts
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (b *Boinc) Collect() map[string]int64 {
mx, err := b.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
b.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -93,9 +93,9 @@ func (b *Boinc) Collect() map[string]int64 {
return mx
}
func (b *Boinc) Cleanup() {
if b.conn != nil {
b.conn.disconnect()
b.conn = nil
func (c *Collector) Cleanup() {
if c.conn != nil {
c.conn.disconnect()
c.conn = nil
}
}

View file

@ -34,11 +34,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestBoinc_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Boinc{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestBoinc_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -59,59 +59,59 @@ func TestBoinc_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
boinc := New()
boinc.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, boinc.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, boinc.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestBoinc_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
tests := map[string]struct {
prepare func() *Boinc
prepare func() *Collector
}{
"not initialized": {
prepare: func() *Boinc {
prepare: func() *Collector {
return New()
},
},
"after check": {
prepare: func() *Boinc {
boinc := New()
boinc.newConn = func(Config, *logger.Logger) boincConn { return prepareMockOk() }
_ = boinc.Check()
return boinc
prepare: func() *Collector {
collr := New()
collr.newConn = func(Config, *logger.Logger) boincConn { return prepareMockOk() }
_ = collr.Check()
return collr
},
},
"after collect": {
prepare: func() *Boinc {
boinc := New()
boinc.newConn = func(Config, *logger.Logger) boincConn { return prepareMockOk() }
_ = boinc.Collect()
return boinc
prepare: func() *Collector {
collr := New()
collr.newConn = func(Config, *logger.Logger) boincConn { return prepareMockOk() }
_ = collr.Collect()
return collr
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
boinc := test.prepare()
collr := test.prepare()
assert.NotPanics(t, boinc.Cleanup)
assert.NotPanics(t, collr.Cleanup)
})
}
}
func TestBoinc_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestBoinc_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockBoincConn
wantFail bool
@ -128,20 +128,20 @@ func TestBoinc_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
boinc := New()
collr := New()
mock := test.prepareMock()
boinc.newConn = func(Config, *logger.Logger) boincConn { return mock }
collr.newConn = func(Config, *logger.Logger) boincConn { return mock }
if test.wantFail {
assert.Error(t, boinc.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, boinc.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestBoinc_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockBoincConn
wantMetrics map[string]int64
@ -212,20 +212,20 @@ func TestBoinc_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
boinc := New()
collr := New()
mock := test.prepareMock()
boinc.newConn = func(Config, *logger.Logger) boincConn { return mock }
collr.newConn = func(Config, *logger.Logger) boincConn { return mock }
mx := boinc.Collect()
mx := collr.Collect()
require.Equal(t, test.wantMetrics, mx)
if len(test.wantMetrics) > 0 {
module.TestMetricsHasAllChartsDims(t, boinc.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
assert.Equal(t, test.disconnectBeforeCleanup, mock.disconnectCalled, "disconnect before cleanup")
boinc.Cleanup()
collr.Cleanup()
assert.Equal(t, test.disconnectAfterCleanup, mock.disconnectCalled, "disconnect after cleanup")
})
}

View file

@ -442,7 +442,7 @@ var (
}
)
func (c *Cassandra) addThreadPoolCharts(pool *threadPoolMetrics) {
func (c *Collector) addThreadPoolCharts(pool *threadPoolMetrics) {
charts := chartsTmplThreadPool.Copy()
for _, chart := range *charts {

View file

@ -14,7 +14,7 @@ const (
suffixValue = "_value"
)
func (c *Cassandra) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
pms, err := c.prom.ScrapeSeries()
if err != nil {
return nil, err
@ -22,7 +22,7 @@ func (c *Cassandra) collect() (map[string]int64, error) {
if c.validateMetrics {
if !isCassandraMetrics(pms) {
return nil, errors.New("collected metrics aren't Cassandra metrics")
return nil, errors.New("collected metrics aren't Collector metrics")
}
c.validateMetrics = false
}
@ -36,7 +36,7 @@ func (c *Cassandra) collect() (map[string]int64, error) {
return mx, nil
}
func (c *Cassandra) resetMetrics() {
func (c *Collector) resetMetrics() {
cm := newCassandraMetrics()
for key, p := range c.mx.threadPools {
cm.threadPools[key] = &threadPoolMetrics{
@ -47,7 +47,7 @@ func (c *Cassandra) resetMetrics() {
c.mx = cm
}
func (c *Cassandra) processMetric(mx map[string]int64) {
func (c *Collector) processMetric(mx map[string]int64) {
c.mx.clientReqTotalLatencyReads.write(mx, "client_request_total_latency_reads")
c.mx.clientReqTotalLatencyWrites.write(mx, "client_request_total_latency_writes")
c.mx.clientReqLatencyReads.write(mx, "client_request_latency_reads")
@ -138,7 +138,7 @@ func (c *Cassandra) processMetric(mx map[string]int64) {
}
}
func (c *Cassandra) collectMetrics(pms prometheus.Series) {
func (c *Collector) collectMetrics(pms prometheus.Series) {
c.collectClientRequestMetrics(pms)
c.collectDroppedMessagesMetrics(pms)
c.collectThreadPoolsMetrics(pms)
@ -148,7 +148,7 @@ func (c *Cassandra) collectMetrics(pms prometheus.Series) {
c.collectCompactionMetrics(pms)
}
func (c *Cassandra) collectClientRequestMetrics(pms prometheus.Series) {
func (c *Collector) collectClientRequestMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_clientrequest"
var rw struct{ read, write *metricValue }
@ -222,7 +222,7 @@ func (c *Cassandra) collectClientRequestMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectCacheMetrics(pms prometheus.Series) {
func (c *Collector) collectCacheMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_cache"
var hm struct{ hits, misses *metricValue }
@ -270,7 +270,7 @@ func (c *Cassandra) collectCacheMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectThreadPoolsMetrics(pms prometheus.Series) {
func (c *Collector) collectThreadPoolsMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_threadpools"
for _, pm := range pms.FindByName(metric + suffixValue) {
@ -301,7 +301,7 @@ func (c *Cassandra) collectThreadPoolsMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectStorageMetrics(pms prometheus.Series) {
func (c *Collector) collectStorageMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_storage"
for _, pm := range pms.FindByName(metric + suffixCount) {
@ -316,7 +316,7 @@ func (c *Cassandra) collectStorageMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectDroppedMessagesMetrics(pms prometheus.Series) {
func (c *Collector) collectDroppedMessagesMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_droppedmessage"
for _, pm := range pms.FindByName(metric + suffixCount) {
@ -324,7 +324,7 @@ func (c *Cassandra) collectDroppedMessagesMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectJVMMetrics(pms prometheus.Series) {
func (c *Collector) collectJVMMetrics(pms prometheus.Series) {
const metricMemUsed = "jvm_memory_bytes_used"
const metricGC = "jvm_gc_collection_seconds"
@ -362,7 +362,7 @@ func (c *Cassandra) collectJVMMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) collectCompactionMetrics(pms prometheus.Series) {
func (c *Collector) collectCompactionMetrics(pms prometheus.Series) {
const metric = "org_apache_cassandra_metrics_compaction"
for _, pm := range pms.FindByName(metric + suffixValue) {
@ -385,7 +385,7 @@ func (c *Cassandra) collectCompactionMetrics(pms prometheus.Series) {
}
}
func (c *Cassandra) getThreadPoolMetrics(name string) *threadPoolMetrics {
func (c *Collector) getThreadPoolMetrics(name string) *threadPoolMetrics {
pool, ok := c.mx.threadPools[name]
if !ok {
pool = &threadPoolMetrics{name: name}

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *Cassandra {
return &Cassandra{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -51,7 +51,7 @@ type Config struct {
web.HTTPConfig `yaml:",inline" json:""`
}
type Cassandra struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -64,11 +64,11 @@ type Cassandra struct {
mx *cassandraMetrics
}
func (c *Cassandra) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Cassandra) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("error on validating config: %v", err)
}
@ -82,7 +82,7 @@ func (c *Cassandra) Init() error {
return nil
}
func (c *Cassandra) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -94,11 +94,11 @@ func (c *Cassandra) Check() error {
return nil
}
func (c *Cassandra) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *Cassandra) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -110,7 +110,7 @@ func (c *Cassandra) Collect() map[string]int64 {
return mx
}
func (c *Cassandra) Cleanup() {
func (c *Collector) Cleanup() {
if c.prom != nil && c.prom.HTTPClient() != nil {
c.prom.HTTPClient().CloseIdleConnections()
}

View file

@ -32,15 +32,15 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCassandra_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Cassandra{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestNew(t *testing.T) {
assert.IsType(t, (*Cassandra)(nil), New())
assert.IsType(t, (*Collector)(nil), New())
}
func TestCassandra_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -61,21 +61,21 @@ func TestCassandra_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c := New()
c.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, c.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, c.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestCassandra_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepare func() (c *Cassandra, cleanup func())
prepare func() (c *Collector, cleanup func())
wantFail bool
}{
"success on valid response": {
@ -97,27 +97,27 @@ func TestCassandra_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c, cleanup := test.prepare()
collr, cleanup := test.prepare()
defer cleanup()
require.NoError(t, c.Init())
require.NoError(t, collr.Init())
if test.wantFail {
assert.Error(t, c.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, c.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestCassandra_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestCassandra_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func() (c *Cassandra, cleanup func())
prepare func() (c *Collector, cleanup func())
wantCollected map[string]int64
}{
"success on valid response": {
@ -246,53 +246,53 @@ func TestCassandra_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c, cleanup := test.prepare()
collr, cleanup := test.prepare()
defer cleanup()
require.NoError(t, c.Init())
require.NoError(t, collr.Init())
mx := c.Collect()
mx := collr.Collect()
assert.Equal(t, test.wantCollected, mx)
})
}
}
func prepareCassandra() (c *Cassandra, cleanup func()) {
func prepareCassandra() (collr *Collector, cleanup func()) {
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataExpectedMetrics)
}))
c = New()
c.URL = ts.URL
return c, ts.Close
collr = New()
collr.URL = ts.URL
return collr, ts.Close
}
func prepareCassandraInvalidData() (c *Cassandra, cleanup func()) {
func prepareCassandraInvalidData() (collr *Collector, cleanup func()) {
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
c = New()
c.URL = ts.URL
return c, ts.Close
collr = New()
collr.URL = ts.URL
return collr, ts.Close
}
func prepareCassandraConnectionRefused() (c *Cassandra, cleanup func()) {
c = New()
c.URL = "http://127.0.0.1:38001"
return c, func() {}
func prepareCassandraConnectionRefused() (collr *Collector, cleanup func()) {
collr = New()
collr.URL = "http://127.0.0.1:38001"
return collr, func() {}
}
func prepareCassandraResponse404() (c *Cassandra, cleanup func()) {
func prepareCassandraResponse404() (collr *Collector, cleanup func()) {
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
c = New()
c.URL = ts.URL
return c, ts.Close
collr = New()
collr.URL = ts.URL
return collr, ts.Close
}

View file

@ -9,14 +9,14 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *Cassandra) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("'url' is not set")
}
return nil
}
func (c *Cassandra) initPrometheusClient() (prometheus.Prometheus, error) {
func (c *Collector) initPrometheusClient() (prometheus.Prometheus, error) {
client, err := web.NewHTTPClient(c.ClientConfig)
if err != nil {
return nil, err

View file

@ -23,7 +23,7 @@ type (
}
)
func (c *Ceph) authLogin() (string, error) {
func (c *Collector) authLogin() (string, error) {
// https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth
req, err := func() (*http.Request, error) {
@ -72,7 +72,7 @@ func (c *Ceph) authLogin() (string, error) {
return tok.Token, nil
}
func (c *Ceph) authCheck() (bool, error) {
func (c *Collector) authCheck() (bool, error) {
// https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth-check
if c.token == "" {
return false, nil
@ -112,7 +112,7 @@ func (c *Ceph) authCheck() (bool, error) {
return resp.Username != "", nil
}
func (c *Ceph) authLogout() error {
func (c *Collector) authLogout() error {
// https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth-logout
if c.token == "" {

View file

@ -504,7 +504,7 @@ var (
}
)
func (c *Ceph) addClusterCharts() {
func (c *Collector) addClusterCharts() {
charts := clusterCharts.Copy()
for _, chart := range *charts {
@ -518,7 +518,7 @@ func (c *Ceph) addClusterCharts() {
}
}
func (c *Ceph) addOsdCharts(osdUuid, devClass, osdName string) {
func (c *Collector) addOsdCharts(osdUuid, devClass, osdName string) {
charts := osdChartsTmpl.Copy()
for _, chart := range *charts {
@ -540,7 +540,7 @@ func (c *Ceph) addOsdCharts(osdUuid, devClass, osdName string) {
}
}
func (c *Ceph) addPoolCharts(poolName string) {
func (c *Collector) addPoolCharts(poolName string) {
charts := poolChartsTmpl.Copy()
for _, chart := range *charts {
@ -560,7 +560,7 @@ func (c *Ceph) addPoolCharts(poolName string) {
}
}
func (c *Ceph) removeCharts(prefix string) {
func (c *Collector) removeCharts(prefix string) {
prefix = cleanChartID(prefix)
for _, chart := range *c.Charts() {
if strings.HasPrefix(chart.ID, prefix) {

View file

@ -14,7 +14,7 @@ import (
const precision = 1000
func (c *Ceph) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
mx := make(map[string]int64)
if err := c.auth(); err != nil {
@ -43,7 +43,7 @@ func (c *Ceph) collect() (map[string]int64, error) {
return mx, nil
}
func (c *Ceph) auth() error {
func (c *Collector) auth() error {
if c.token != "" {
ok, err := c.authCheck()
if err != nil {
@ -64,7 +64,7 @@ func (c *Ceph) auth() error {
return nil
}
func (c *Ceph) getFsid() (string, error) {
func (c *Collector) getFsid() (string, error) {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiMonitor)
if err != nil {
return "", err
@ -93,7 +93,7 @@ func (c *Ceph) getFsid() (string, error) {
return resp.MonStatus.MonMap.FSID, nil
}
func (c *Ceph) webClient(statusCodes ...int) *web.Client {
func (c *Collector) webClient(statusCodes ...int) *web.Client {
return web.DoHTTP(c.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
if slices.Contains(statusCodes, resp.StatusCode) {
return true, nil

View file

@ -8,7 +8,7 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *Ceph) collectHealth(mx map[string]int64) error {
func (c *Collector) collectHealth(mx map[string]int64) error {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiHealthMinimal)
if err != nil {
return err

View file

@ -8,7 +8,7 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *Ceph) collectOsds(mx map[string]int64) error {
func (c *Collector) collectOsds(mx map[string]int64) error {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiOsd)
if err != nil {
return err

View file

@ -8,7 +8,7 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *Ceph) collectPools(mx map[string]int64) error {
func (c *Collector) collectPools(mx map[string]int64) error {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiPool)
if err != nil {
return err

View file

@ -30,8 +30,8 @@ func init() {
})
}
func New() *Ceph {
return &Ceph{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -56,7 +56,7 @@ type Config struct {
web.HTTPConfig `yaml:",inline" json:""`
}
type Ceph struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -73,11 +73,11 @@ type Ceph struct {
seenOsds map[string]bool
}
func (c *Ceph) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Ceph) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("invalid config: %v", err)
}
@ -91,7 +91,7 @@ func (c *Ceph) Init() error {
return nil
}
func (c *Ceph) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -104,11 +104,11 @@ func (c *Ceph) Check() error {
return nil
}
func (c *Ceph) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *Ceph) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -121,7 +121,7 @@ func (c *Ceph) Collect() map[string]int64 {
return mx
}
func (c *Ceph) Cleanup() {
func (c *Collector) Cleanup() {
if c.httpClient != nil {
if err := c.authLogout(); err != nil {
c.Warningf("failed to logout: %v", err)

View file

@ -43,12 +43,12 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCeph_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &Ceph{}, dataConfigJSON, dataConfigYAML)
func TestCollector_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestCeph_Init(t *testing.T) {
tesceph := map[string]struct {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
wantFail bool
config Config
}{
@ -66,24 +66,24 @@ func TestCeph_Init(t *testing.T) {
},
}
for name, test := range tesceph {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
ceph := New()
ceph.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, ceph.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, ceph.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestCeph_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
wantFail bool
prepare func(t *testing.T) (ceph *Ceph, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
}{
"success with valid API key": {
wantFail: false,
@ -101,25 +101,25 @@ func TestCeph_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
ceph, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, ceph.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, ceph.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestCeph_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestCeph_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func(t *testing.T) (ceph *Ceph, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
wantNumOfCharts int
wantMetrics map[string]int64
}{
@ -224,25 +224,25 @@ func TestCeph_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
ceph, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
_ = ceph.Check()
_ = collr.Check()
mx := ceph.Collect()
mx := collr.Collect()
require.Equal(t, test.wantMetrics, mx)
if len(test.wantMetrics) > 0 {
assert.Equal(t, test.wantNumOfCharts, len(*ceph.Charts()), "want charts")
assert.Equal(t, test.wantNumOfCharts, len(*collr.Charts()), "want charts")
module.TestMetricsHasAllChartsDims(t, ceph.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
})
}
}
func caseOk(t *testing.T) (*Ceph, func()) {
func caseOk(t *testing.T) (*Collector, func()) {
t.Helper()
loginResp, _ := json.Marshal(authLoginResp{Token: "secret_token"})
@ -295,37 +295,37 @@ func caseOk(t *testing.T) (*Ceph, func()) {
}
}))
ceph := New()
ceph.URL = srv.URL
ceph.Username = "user"
ceph.Password = "password"
require.NoError(t, ceph.Init())
collr := New()
collr.URL = srv.URL
collr.Username = "user"
collr.Password = "password"
require.NoError(t, collr.Init())
return ceph, srv.Close
return collr, srv.Close
}
func caseConnectionRefused(t *testing.T) (*Ceph, func()) {
func caseConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
ceph := New()
ceph.URL = "http://127.0.0.1:65001"
ceph.Username = "user"
ceph.Password = "password"
require.NoError(t, ceph.Init())
collr := New()
collr.URL = "http://127.0.0.1:65001"
collr.Username = "user"
collr.Password = "password"
require.NoError(t, collr.Init())
return ceph, func() {}
return collr, func() {}
}
func case404(t *testing.T) (*Ceph, func()) {
func case404(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
ceph := New()
ceph.URL = srv.URL
ceph.Username = "user"
ceph.Password = "password"
require.NoError(t, ceph.Init())
collr := New()
collr.URL = srv.URL
collr.Username = "user"
collr.Password = "password"
require.NoError(t, collr.Init())
return ceph, srv.Close
return collr, srv.Close
}

View file

@ -6,7 +6,7 @@ import (
"fmt"
)
func (c *Ceph) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return fmt.Errorf("URL is required but not set")
}

View file

@ -248,7 +248,7 @@ var (
}
)
func (c *Chrony) addServerStatsCharts() {
func (c *Collector) addServerStatsCharts() {
if err := c.Charts().Add(*serverStatsCharts.Copy()...); err != nil {
c.Warning(err)
}

View file

@ -24,7 +24,7 @@ const (
leapStatusUnsynchronised = 3
)
func (c *Chrony) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
if c.conn == nil {
client, err := c.newConn(c.Config)
if err != nil {
@ -53,7 +53,7 @@ func (c *Chrony) collect() (map[string]int64, error) {
return mx, nil
}
func (c *Chrony) collectTracking(mx map[string]int64) error {
func (c *Collector) collectTracking(mx map[string]int64) error {
reply, err := c.conn.tracking()
if err != nil {
return fmt.Errorf("error on collecting tracking: %v", err)
@ -82,7 +82,7 @@ func (c *Chrony) collectTracking(mx map[string]int64) error {
return nil
}
func (c *Chrony) collectActivity(mx map[string]int64) error {
func (c *Collector) collectActivity(mx map[string]int64) error {
reply, err := c.conn.activity()
if err != nil {
return fmt.Errorf("error on collecting activity: %v", err)
@ -97,7 +97,7 @@ func (c *Chrony) collectActivity(mx map[string]int64) error {
return nil
}
func (c *Chrony) collectServerStats(mx map[string]int64) error {
func (c *Collector) collectServerStats(mx map[string]int64) error {
bs, err := c.exec.serverStats()
if err != nil {
return fmt.Errorf("error on collecting server stats: %v", err)

View file

@ -24,8 +24,8 @@ func init() {
})
}
func New() *Chrony {
return &Chrony{
func New() *Collector {
return &Collector{
Config: Config{
Address: "127.0.0.1:323",
Timeout: confopt.Duration(time.Second),
@ -42,7 +42,7 @@ type Config struct {
Timeout confopt.Duration `yaml:"timeout,omitempty" json:"timeout"`
}
type Chrony struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -55,11 +55,11 @@ type Chrony struct {
newConn func(c Config) (chronyConn, error)
}
func (c *Chrony) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Chrony) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
@ -72,7 +72,7 @@ func (c *Chrony) Init() error {
return nil
}
func (c *Chrony) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -84,11 +84,11 @@ func (c *Chrony) Check() error {
return nil
}
func (c *Chrony) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *Chrony) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -100,7 +100,7 @@ func (c *Chrony) Collect() map[string]int64 {
return mx
}
func (c *Chrony) Cleanup() {
func (c *Collector) Cleanup() {
if c.conn != nil {
c.conn.close()
c.conn = nil

View file

@ -30,11 +30,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestChrony_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Chrony{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestChrony_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -52,94 +52,94 @@ func TestChrony_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c := New()
c.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, c.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, c.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestChrony_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepare func() *Chrony
prepare func() *Collector
wantFail bool
}{
"tracking: success, activity: success": {
wantFail: false,
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{}) },
},
"tracking: success, activity: fail": {
wantFail: true,
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnActivity: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnActivity: true}) },
},
"tracking: fail, activity: success": {
wantFail: true,
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
},
"tracking: fail, activity: fail": {
wantFail: true,
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
},
"fail on creating client": {
wantFail: true,
prepare: func() *Chrony { return prepareChronyWithMock(nil) },
prepare: func() *Collector { return prepareChronyWithMock(nil) },
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c := test.prepare()
collr := test.prepare()
require.NoError(t, c.Init())
require.NoError(t, collr.Init())
if test.wantFail {
assert.Error(t, c.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, c.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestChrony_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.Equal(t, len(charts), len(*New().Charts()))
}
func TestChrony_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
tests := map[string]struct {
prepare func(c *Chrony)
prepare func(c *Collector)
wantClose bool
}{
"after New": {
wantClose: false,
prepare: func(c *Chrony) {},
prepare: func(c *Collector) {},
},
"after Init": {
wantClose: false,
prepare: func(c *Chrony) { _ = c.Init() },
prepare: func(c *Collector) { _ = c.Init() },
},
"after Check": {
wantClose: true,
prepare: func(c *Chrony) { _ = c.Init(); _ = c.Check() },
prepare: func(c *Collector) { _ = c.Init(); _ = c.Check() },
},
"after Collect": {
wantClose: true,
prepare: func(c *Chrony) { _ = c.Init(); _ = c.Collect() },
prepare: func(c *Collector) { _ = c.Init(); _ = c.Collect() },
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
m := &mockClient{}
c := prepareChronyWithMock(m)
test.prepare(c)
collr := prepareChronyWithMock(m)
test.prepare(collr)
require.NotPanics(t, c.Cleanup)
require.NotPanics(t, collr.Cleanup)
if test.wantClose {
assert.True(t, m.closeCalled)
@ -150,13 +150,13 @@ func TestChrony_Cleanup(t *testing.T) {
}
}
func TestChrony_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func() *Chrony
prepare func() *Collector
expected map[string]int64
}{
"tracking: success, activity: success, serverstats: success": {
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{}) },
expected: map[string]int64{
"burst_offline_sources": 3,
"burst_online_sources": 4,
@ -185,7 +185,7 @@ func TestChrony_Collect(t *testing.T) {
},
},
"tracking: success, activity: fail": {
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnActivity: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnActivity: true}) },
expected: map[string]int64{
"current_correction": 154872,
"frequency": 51051185607,
@ -205,28 +205,28 @@ func TestChrony_Collect(t *testing.T) {
},
},
"tracking: fail, activity: success": {
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
expected: nil,
},
"tracking: fail, activity: fail": {
prepare: func() *Chrony { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
prepare: func() *Collector { return prepareChronyWithMock(&mockClient{errOnTracking: true}) },
expected: nil,
},
"fail on creating client": {
prepare: func() *Chrony { return prepareChronyWithMock(nil) },
prepare: func() *Collector { return prepareChronyWithMock(nil) },
expected: nil,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
c := test.prepare()
collr := test.prepare()
require.NoError(t, c.Init())
c.exec = &mockChronyc{}
_ = c.Check()
require.NoError(t, collr.Init())
collr.exec = &mockChronyc{}
_ = collr.Check()
mx := c.Collect()
mx := collr.Collect()
copyRefMeasurementTime(mx, test.expected)
assert.Equal(t, test.expected, mx)
@ -234,7 +234,7 @@ func TestChrony_Collect(t *testing.T) {
}
}
func prepareChronyWithMock(m *mockClient) *Chrony {
func prepareChronyWithMock(m *mockClient) *Collector {
c := New()
if m == nil {
c.newConn = func(_ Config) (chronyConn, error) { return nil, errors.New("mock.newClient error") }

View file

@ -12,14 +12,14 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/executable"
)
func (c *Chrony) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.Address == "" {
return errors.New("empty 'address'")
}
return nil
}
func (c *Chrony) initChronycBinary() (chronyBinary, error) {
func (c *Collector) initChronycBinary() (chronyBinary, error) {
host, _, err := net.SplitHostPort(c.Address)
if err != nil {
return nil, err

View file

@ -948,7 +948,7 @@ var (
}
)
func (c *ClickHouse) addDiskCharts(disk *seenDisk) {
func (c *Collector) addDiskCharts(disk *seenDisk) {
charts := diskChartsTmpl.Copy()
for _, chart := range *charts {
@ -966,12 +966,12 @@ func (c *ClickHouse) addDiskCharts(disk *seenDisk) {
}
}
func (c *ClickHouse) removeDiskCharts(disk *seenDisk) {
func (c *Collector) removeDiskCharts(disk *seenDisk) {
px := fmt.Sprintf("disk_%s_", disk.disk)
c.removeCharts(px)
}
func (c *ClickHouse) addTableCharts(table *seenTable) {
func (c *Collector) addTableCharts(table *seenTable) {
charts := tableChartsTmpl.Copy()
for _, chart := range *charts {
@ -990,12 +990,12 @@ func (c *ClickHouse) addTableCharts(table *seenTable) {
}
}
func (c *ClickHouse) removeTableCharts(table *seenTable) {
func (c *Collector) removeTableCharts(table *seenTable) {
px := fmt.Sprintf("table_%s_database_%s_", table.table, table.db)
c.removeCharts(px)
}
func (c *ClickHouse) removeCharts(prefix string) {
func (c *Collector) removeCharts(prefix string) {
for _, chart := range *c.Charts() {
if strings.HasPrefix(chart.ID, prefix) {
chart.MarkRemove()

View file

@ -15,7 +15,7 @@ import (
const precision = 1000
func (c *ClickHouse) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
mx := make(map[string]int64)
if err := c.collectSystemEvents(mx); err != nil {
@ -40,7 +40,7 @@ func (c *ClickHouse) collect() (map[string]int64, error) {
return mx, nil
}
func (c *ClickHouse) doHTTP(req *http.Request, assign func(column, value string, lineEnd bool)) error {
func (c *Collector) doHTTP(req *http.Request, assign func(column, value string, lineEnd bool)) error {
return web.DoHTTP(c.httpClient).Request(req, func(body io.Reader) error {
return readCSVResponseData(body, assign)
})

View file

@ -21,7 +21,7 @@ where
OR metric LIKE 'ReplicasMaxAbsoluteDelay' FORMAT CSVWithNames
`
func (c *ClickHouse) collectSystemAsyncMetrics(mx map[string]int64) error {
func (c *Collector) collectSystemAsyncMetrics(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(querySystemAsyncMetrics)

View file

@ -25,7 +25,7 @@ type diskStats struct {
freeBytes int64
}
func (c *ClickHouse) collectSystemDisks(mx map[string]int64) error {
func (c *Collector) collectSystemDisks(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(querySystemDisks)

View file

@ -17,7 +17,7 @@ FROM
system.events FORMAT CSVWithNames
`
func (c *ClickHouse) collectSystemEvents(mx map[string]int64) error {
func (c *Collector) collectSystemEvents(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(querySystemEvents)

View file

@ -17,7 +17,7 @@ FROM
system.metrics FORMAT CSVWithNames
`
func (c *ClickHouse) collectSystemMetrics(mx map[string]int64) error {
func (c *Collector) collectSystemMetrics(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(querySystemMetrics)

View file

@ -33,7 +33,7 @@ type tableStats struct {
rows int64
}
func (c *ClickHouse) collectSystemParts(mx map[string]int64) error {
func (c *Collector) collectSystemParts(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(querySystemParts)

View file

@ -15,7 +15,7 @@ FROM
system.processes FORMAT CSVWithNames
`
func (c *ClickHouse) collectLongestRunningQueryTime(mx map[string]int64) error {
func (c *Collector) collectLongestRunningQueryTime(mx map[string]int64) error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
req.URL.RawQuery = makeURLQuery(queryLongestQueryTime)

View file

@ -25,8 +25,8 @@ func init() {
})
}
func New() *ClickHouse {
return &ClickHouse{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -49,7 +49,7 @@ type Config struct {
}
type (
ClickHouse struct {
Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -64,11 +64,11 @@ type (
seenTable struct{ db, table string }
)
func (c *ClickHouse) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *ClickHouse) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
@ -85,7 +85,7 @@ func (c *ClickHouse) Init() error {
return nil
}
func (c *ClickHouse) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -98,11 +98,11 @@ func (c *ClickHouse) Check() error {
return nil
}
func (c *ClickHouse) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *ClickHouse) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -115,7 +115,7 @@ func (c *ClickHouse) Collect() map[string]int64 {
return mx
}
func (c *ClickHouse) Cleanup() {
func (c *Collector) Cleanup() {
if c.httpClient != nil {
c.httpClient.CloseIdleConnections()
}

View file

@ -43,10 +43,10 @@ func Test_testDataIsValid(t *testing.T) {
}
func TestClickhouse_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &ClickHouse{}, dataConfigJSON, dataConfigYAML)
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestClickHouse_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
wantFail bool
config Config
@ -67,26 +67,26 @@ func TestClickHouse_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
click := New()
click.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, click.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, click.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestClickHouse_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestClickHouse_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
wantFail bool
prepare func(t *testing.T) (*ClickHouse, func())
prepare func(t *testing.T) (*Collector, func())
}{
"success on valid response": {
wantFail: false,
@ -104,21 +104,21 @@ func TestClickHouse_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
click, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, click.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, click.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestClickHouse_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func(t *testing.T) (*ClickHouse, func())
prepare func(t *testing.T) (*Collector, func())
wantMetrics map[string]int64
}{
"success on valid response": {
@ -237,21 +237,21 @@ func TestClickHouse_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
click, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
mx := click.Collect()
mx := collr.Collect()
require.Equal(t, test.wantMetrics, mx)
if len(test.wantMetrics) > 0 {
module.TestMetricsHasAllChartsDims(t, click.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
})
}
}
func prepareCaseOk(t *testing.T) (*ClickHouse, func()) {
func prepareCaseOk(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -273,32 +273,32 @@ func prepareCaseOk(t *testing.T) (*ClickHouse, func()) {
}
}))
click := New()
click.URL = srv.URL
require.NoError(t, click.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return click, srv.Close
return collr, srv.Close
}
func prepareCaseUnexpectedResponse(t *testing.T) (*ClickHouse, func()) {
func prepareCaseUnexpectedResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
click := New()
click.URL = srv.URL
require.NoError(t, click.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return click, srv.Close
return collr, srv.Close
}
func prepareCaseConnectionRefused(t *testing.T) (*ClickHouse, func()) {
func prepareCaseConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
click := New()
click.URL = "http://127.0.0.1:65001/stat"
require.NoError(t, click.Init())
collr := New()
collr.URL = "http://127.0.0.1:65001/stat"
require.NoError(t, collr.Init())
return click, func() {}
return collr, func() {}
}

View file

@ -9,13 +9,13 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *ClickHouse) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("url not set")
}
return nil
}
func (c *ClickHouse) initHTTPClient() (*http.Client, error) {
func (c *Collector) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(c.ClientConfig)
}

View file

@ -13,7 +13,7 @@ func validCockroachDBMetrics(scraped prometheus.Series) bool {
return scraped.FindByName("sql_restart_savepoint_count_internal").Len() > 0
}
func (c *CockroachDB) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
scraped, err := c.prom.ScrapeSeries()
if err != nil {
return nil, err

View file

@ -32,8 +32,8 @@ func init() {
})
}
func New() *CockroachDB {
return &CockroachDB{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -53,7 +53,7 @@ type Config struct {
web.HTTPConfig `yaml:",inline" json:""`
}
type CockroachDB struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -62,11 +62,11 @@ type CockroachDB struct {
prom prometheus.Prometheus
}
func (c *CockroachDB) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *CockroachDB) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("error on validating config: %v", err)
}
@ -85,7 +85,7 @@ func (c *CockroachDB) Init() error {
return nil
}
func (c *CockroachDB) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -97,11 +97,11 @@ func (c *CockroachDB) Check() error {
return nil
}
func (c *CockroachDB) Charts() *Charts {
func (c *Collector) Charts() *Charts {
return c.charts
}
func (c *CockroachDB) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -113,7 +113,7 @@ func (c *CockroachDB) Collect() map[string]int64 {
return mx
}
func (c *CockroachDB) Cleanup() {
func (c *Collector) Cleanup() {
if c.prom != nil && c.prom.HTTPClient() != nil {
c.prom.HTTPClient().CloseIdleConnections()
}

View file

@ -33,59 +33,59 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCockroachDB_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &CockroachDB{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestNew(t *testing.T) {
assert.Implements(t, (*module.Module)(nil), New())
}
func TestCockroachDB_Init(t *testing.T) {
cdb := prepareCockroachDB()
func TestCollector_Init(t *testing.T) {
collr := prepareCockroachDB()
assert.NoError(t, cdb.Init())
assert.NoError(t, collr.Init())
}
func TestCockroachDB_Init_ReturnsFalseIfConfigURLIsNotSet(t *testing.T) {
cdb := prepareCockroachDB()
cdb.URL = ""
func TestCollector_Init_ReturnsFalseIfConfigURLIsNotSet(t *testing.T) {
collr := prepareCockroachDB()
collr.URL = ""
assert.Error(t, cdb.Init())
assert.Error(t, collr.Init())
}
func TestCockroachDB_Init_ReturnsFalseIfClientWrongTLSCA(t *testing.T) {
cdb := prepareCockroachDB()
cdb.ClientConfig.TLSConfig.TLSCA = "testdata/tls"
func TestCollector_Init_ReturnsFalseIfClientWrongTLSCA(t *testing.T) {
collr := prepareCockroachDB()
collr.ClientConfig.TLSConfig.TLSCA = "testdata/tls"
assert.Error(t, cdb.Init())
assert.Error(t, collr.Init())
}
func TestCockroachDB_Check(t *testing.T) {
cdb, srv := prepareClientServer(t)
func TestCollector_Check(t *testing.T) {
collr, srv := prepareClientServer(t)
defer srv.Close()
assert.NoError(t, cdb.Check())
assert.NoError(t, collr.Check())
}
func TestCockroachDB_Check_ReturnsFalseIfConnectionRefused(t *testing.T) {
cdb := New()
cdb.URL = "http://127.0.0.1:38001/metrics"
require.NoError(t, cdb.Init())
func TestCollector_Check_ReturnsFalseIfConnectionRefused(t *testing.T) {
collr := New()
collr.URL = "http://127.0.0.1:38001/metrics"
require.NoError(t, collr.Init())
assert.Error(t, cdb.Check())
assert.Error(t, collr.Check())
}
func TestCockroachDB_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestCockroachDB_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
assert.NotPanics(t, New().Cleanup)
}
func TestCockroachDB_Collect(t *testing.T) {
cdb, srv := prepareClientServer(t)
func TestCollector_Collect(t *testing.T) {
collr, srv := prepareClientServer(t)
defer srv.Close()
expected := map[string]int64{
@ -221,98 +221,98 @@ func TestCockroachDB_Collect(t *testing.T) {
"valcount": 124081,
}
mx := cdb.Collect()
mx := collr.Collect()
assert.Equal(t, expected, mx)
module.TestMetricsHasAllChartsDims(t, cdb.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
func TestCockroachDB_Collect_ReturnsNilIfNotCockroachDBMetrics(t *testing.T) {
cdb, srv := prepareClientServerNotCockroachDBMetricResponse(t)
func TestCollector_Collect_ReturnsNilIfNotCockroachDBMetrics(t *testing.T) {
collr, srv := prepareClientServerNotCockroachDBMetricResponse(t)
defer srv.Close()
assert.Nil(t, cdb.Collect())
assert.Nil(t, collr.Collect())
}
func TestCockroachDB_Collect_ReturnsNilIfConnectionRefused(t *testing.T) {
cdb := prepareCockroachDB()
require.NoError(t, cdb.Init())
func TestCollector_Collect_ReturnsNilIfConnectionRefused(t *testing.T) {
collr := prepareCockroachDB()
require.NoError(t, collr.Init())
assert.Nil(t, cdb.Collect())
assert.Nil(t, collr.Collect())
}
func TestCockroachDB_Collect_ReturnsNilIfReceiveInvalidResponse(t *testing.T) {
cdb, ts := prepareClientServerInvalidDataResponse(t)
func TestCollector_Collect_ReturnsNilIfReceiveInvalidResponse(t *testing.T) {
collr, ts := prepareClientServerInvalidDataResponse(t)
defer ts.Close()
assert.Nil(t, cdb.Collect())
assert.Nil(t, collr.Collect())
}
func TestCockroachDB_Collect_ReturnsNilIfReceiveResponse404(t *testing.T) {
cdb, ts := prepareClientServerResponse404(t)
func TestCollector_Collect_ReturnsNilIfReceiveResponse404(t *testing.T) {
collr, ts := prepareClientServerResponse404(t)
defer ts.Close()
assert.Nil(t, cdb.Collect())
assert.Nil(t, collr.Collect())
}
func prepareCockroachDB() *CockroachDB {
cdb := New()
cdb.URL = "http://127.0.0.1:38001/metrics"
return cdb
func prepareCockroachDB() *Collector {
collr := New()
collr.URL = "http://127.0.0.1:38001/metrics"
return collr
}
func prepareClientServer(t *testing.T) (*CockroachDB, *httptest.Server) {
func prepareClientServer(t *testing.T) (*Collector, *httptest.Server) {
t.Helper()
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataExpectedMetrics)
}))
cdb := New()
cdb.URL = ts.URL
require.NoError(t, cdb.Init())
collr := New()
collr.URL = ts.URL
require.NoError(t, collr.Init())
return cdb, ts
return collr, ts
}
func prepareClientServerNotCockroachDBMetricResponse(t *testing.T) (*CockroachDB, *httptest.Server) {
func prepareClientServerNotCockroachDBMetricResponse(t *testing.T) (*Collector, *httptest.Server) {
t.Helper()
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataUnexpectedMetrics)
}))
cdb := New()
cdb.URL = ts.URL
require.NoError(t, cdb.Init())
collr := New()
collr.URL = ts.URL
require.NoError(t, collr.Init())
return cdb, ts
return collr, ts
}
func prepareClientServerInvalidDataResponse(t *testing.T) (*CockroachDB, *httptest.Server) {
func prepareClientServerInvalidDataResponse(t *testing.T) (*Collector, *httptest.Server) {
t.Helper()
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
cdb := New()
cdb.URL = ts.URL
require.NoError(t, cdb.Init())
collr := New()
collr.URL = ts.URL
require.NoError(t, collr.Init())
return cdb, ts
return collr, ts
}
func prepareClientServerResponse404(t *testing.T) (*CockroachDB, *httptest.Server) {
func prepareClientServerResponse404(t *testing.T) (*Collector, *httptest.Server) {
t.Helper()
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
cdb := New()
cdb.URL = ts.URL
require.NoError(t, cdb.Init())
return cdb, ts
collr := New()
collr.URL = ts.URL
require.NoError(t, collr.Init())
return collr, ts
}

View file

@ -9,14 +9,14 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *CockroachDB) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("URL is not set")
}
return nil
}
func (c *CockroachDB) initPrometheusClient() (prometheus.Prometheus, error) {
func (c *Collector) initPrometheusClient() (prometheus.Prometheus, error) {
client, err := web.NewHTTPClient(c.ClientConfig)
if err != nil {
return nil, err

View file

@ -557,7 +557,7 @@ var (
}
)
func (c *Consul) addGlobalCharts() {
func (c *Collector) addGlobalCharts() {
if !c.isTelemetryPrometheusEnabled() {
return
}
@ -602,7 +602,7 @@ func (c *Consul) addGlobalCharts() {
}
}
func (c *Consul) addServerAutopilotHealthCharts() {
func (c *Collector) addServerAutopilotHealthCharts() {
charts := serverAutopilotHealthCharts.Copy()
for _, chart := range *charts {
@ -644,7 +644,7 @@ func newNodeHealthCheckChart(check *agentCheck) *module.Chart {
return chart
}
func (c *Consul) addHealthCheckCharts(check *agentCheck) {
func (c *Collector) addHealthCheckCharts(check *agentCheck) {
var chart *module.Chart
if check.ServiceName != "" {
@ -663,7 +663,7 @@ func (c *Consul) addHealthCheckCharts(check *agentCheck) {
}
}
func (c *Consul) removeHealthCheckCharts(checkID string) {
func (c *Collector) removeHealthCheckCharts(checkID string) {
id := fmt.Sprintf("health_check_%s_status", checkID)
chart := c.Charts().Get(id)
@ -676,7 +676,7 @@ func (c *Consul) removeHealthCheckCharts(checkID string) {
chart.MarkNotCreated()
}
func (c *Consul) addLeaderCharts() {
func (c *Collector) addLeaderCharts() {
charts := serverLeaderCharts.Copy()
for _, chart := range *charts {
@ -691,7 +691,7 @@ func (c *Consul) addLeaderCharts() {
}
}
func (c *Consul) removeLeaderCharts() {
func (c *Collector) removeLeaderCharts() {
s := make(map[string]bool)
for _, v := range serverLeaderCharts {
s[v.ID] = true
@ -705,7 +705,7 @@ func (c *Consul) removeLeaderCharts() {
}
}
func (c *Consul) addFollowerCharts() {
func (c *Collector) addFollowerCharts() {
charts := serverFollowerCharts.Copy()
if c.isCloudManaged() {
// 'autopilot_server_lastContact_leader' comes from 'operator/autopilot/health' which is disabled
@ -724,7 +724,7 @@ func (c *Consul) addFollowerCharts() {
}
}
func (c *Consul) removeFollowerCharts() {
func (c *Collector) removeFollowerCharts() {
s := make(map[string]bool)
for _, v := range serverFollowerCharts {
s[v.ID] = true

View file

@ -14,7 +14,7 @@ const (
precision = 1000
)
func (c *Consul) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
if c.cfg == nil {
if err := c.collectConfiguration(); err != nil {
return nil, err
@ -51,29 +51,29 @@ func (c *Consul) collect() (map[string]int64, error) {
return mx, nil
}
func (c *Consul) isTelemetryPrometheusEnabled() bool {
func (c *Collector) isTelemetryPrometheusEnabled() bool {
return c.cfg.DebugConfig.Telemetry.PrometheusOpts.Expiration != "0s"
}
func (c *Consul) isCloudManaged() bool {
func (c *Collector) isCloudManaged() bool {
return c.cfg.DebugConfig.Cloud.ClientSecret != "" || c.cfg.DebugConfig.Cloud.ResourceID != ""
}
func (c *Consul) hasLicense() bool {
func (c *Collector) hasLicense() bool {
return c.cfg.Stats.License.ID != ""
}
func (c *Consul) isServer() bool {
func (c *Collector) isServer() bool {
return c.cfg.Config.Server
}
func (c *Consul) client(statusCodes ...int) *web.Client {
func (c *Collector) client(statusCodes ...int) *web.Client {
return web.DoHTTP(c.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
return slices.Contains(statusCodes, resp.StatusCode), nil
})
}
func (c *Consul) createRequest(urlPath string) (*http.Request, error) {
func (c *Collector) createRequest(urlPath string) (*http.Request, error) {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPath)
if err != nil {
return nil, fmt.Errorf("failed to create '%s' request: %w", urlPath, err)

View file

@ -26,7 +26,7 @@ type autopilotHealth struct {
}
}
func (c *Consul) collectAutopilotHealth(mx map[string]int64) error {
func (c *Collector) collectAutopilotHealth(mx map[string]int64) error {
req, err := c.createRequest(urlPathOperationAutopilotHealth)
if err != nil {
return err

View file

@ -19,7 +19,7 @@ type agentCheck struct {
ServiceTags []string
}
func (c *Consul) collectChecks(mx map[string]int64) error {
func (c *Collector) collectChecks(mx map[string]int64) error {
req, err := c.createRequest(urlPathAgentChecks)
if err != nil {
return err

View file

@ -45,7 +45,7 @@ type consulConfig struct {
}
}
func (c *Consul) collectConfiguration() error {
func (c *Collector) collectConfiguration() error {
req, err := c.createRequest(urlPathAgentSelf)
if err != nil {
return err

View file

@ -12,7 +12,7 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/prometheus"
)
func (c *Consul) collectMetricsPrometheus(mx map[string]int64) error {
func (c *Collector) collectMetricsPrometheus(mx map[string]int64) error {
mfs, err := c.prom.Scrape()
if err != nil {
return err
@ -85,7 +85,7 @@ func (c *Consul) collectMetricsPrometheus(mx map[string]int64) error {
return nil
}
func (c *Consul) isLeader(mfs prometheus.MetricFamilies) (bool, bool) {
func (c *Collector) isLeader(mfs prometheus.MetricFamilies) (bool, bool) {
var mf *prometheus.MetricFamily
for _, v := range []string{"server_isLeader_isLeader", "server_isLeader"} {
if mf = mfs.GetGauge(c.promMetricNameWithHostname(v)); mf != nil {
@ -103,7 +103,7 @@ func (c *Consul) isLeader(mfs prometheus.MetricFamilies) (bool, bool) {
return mf.Metrics()[0].Gauge().Value() == 1, true
}
func (c *Consul) collectGauge(mx map[string]int64, mfs prometheus.MetricFamilies, name string, mul float64, aliases ...string) {
func (c *Collector) collectGauge(mx map[string]int64, mfs prometheus.MetricFamilies, name string, mul float64, aliases ...string) {
var mf *prometheus.MetricFamily
for _, v := range append(aliases, name) {
if mf = mfs.GetGauge(c.promMetricNameWithHostname(v)); mf != nil {
@ -125,7 +125,7 @@ func (c *Consul) collectGauge(mx map[string]int64, mfs prometheus.MetricFamilies
}
}
func (c *Consul) collectGaugeBool(mx map[string]int64, mfs prometheus.MetricFamilies, name string, aliases ...string) {
func (c *Collector) collectGaugeBool(mx map[string]int64, mfs prometheus.MetricFamilies, name string, aliases ...string) {
var mf *prometheus.MetricFamily
for _, v := range append(aliases, name) {
if mf = mfs.GetGauge(c.promMetricNameWithHostname(v)); mf != nil {
@ -148,7 +148,7 @@ func (c *Consul) collectGaugeBool(mx map[string]int64, mfs prometheus.MetricFami
}
}
func (c *Consul) collectCounter(mx map[string]int64, mfs prometheus.MetricFamilies, name string, mul float64) {
func (c *Collector) collectCounter(mx map[string]int64, mfs prometheus.MetricFamilies, name string, mul float64) {
mf := mfs.GetCounter(c.promMetricName(name))
if mf == nil {
return
@ -161,7 +161,7 @@ func (c *Consul) collectCounter(mx map[string]int64, mfs prometheus.MetricFamili
}
}
func (c *Consul) collectSummary(mx map[string]int64, mfs prometheus.MetricFamilies, name string) {
func (c *Collector) collectSummary(mx map[string]int64, mfs prometheus.MetricFamilies, name string) {
mf := mfs.GetSummary(c.promMetricName(name))
if mf == nil {
return
@ -185,7 +185,7 @@ func (c *Consul) collectSummary(mx map[string]int64, mfs prometheus.MetricFamili
mx[name+"_count"] = int64(m.Summary().Count())
}
func (c *Consul) promMetricName(name string) string {
func (c *Collector) promMetricName(name string) string {
px := c.cfg.DebugConfig.Telemetry.MetricsPrefix
return px + "_" + name
}
@ -194,7 +194,7 @@ var forbiddenCharsReplacer = strings.NewReplacer(" ", "_", ".", "_", "=", "_", "
// controlled by 'disable_hostname'
// https://developer.hashicorp.com/consul/docs/agent/config/config-files#telemetry-disable_hostname
func (c *Consul) promMetricNameWithHostname(name string) string {
func (c *Collector) promMetricNameWithHostname(name string) string {
px := c.cfg.DebugConfig.Telemetry.MetricsPrefix
node := forbiddenCharsReplacer.Replace(c.cfg.Config.NodeName)

View file

@ -22,7 +22,7 @@ type nodeCoordinates struct {
}
}
func (c *Consul) collectNetworkRTT(mx map[string]int64) error {
func (c *Collector) collectNetworkRTT(mx map[string]int64) error {
req, err := c.createRequest(urlPathCoordinateNodes)
if err != nil {
return err

View file

@ -32,8 +32,8 @@ func init() {
})
}
func New() *Consul {
return &Consul{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -57,7 +57,7 @@ type Config struct {
ACLToken string `yaml:"acl_token,omitempty" json:"acl_token"`
}
type Consul struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -75,11 +75,11 @@ type Consul struct {
checks map[string]bool
}
func (c *Consul) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *Consul) Init() error {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
@ -99,7 +99,7 @@ func (c *Consul) Init() error {
return nil
}
func (c *Consul) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -111,11 +111,11 @@ func (c *Consul) Check() error {
return nil
}
func (c *Consul) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *Consul) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -127,7 +127,7 @@ func (c *Consul) Collect() map[string]int64 {
return mx
}
func (c *Consul) Cleanup() {
func (c *Collector) Cleanup() {
if c.httpClient != nil {
c.httpClient.CloseIdleConnections()
}

View file

@ -59,11 +59,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestConsul_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Consul{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestConsul_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
wantFail bool
config Config
@ -84,22 +84,22 @@ func TestConsul_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
consul := New()
consul.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, consul.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, consul.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestConsul_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
wantFail bool
prepare func(t *testing.T) (consul *Consul, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
}{
"success on response from Consul v1.13.2 server": {
wantFail: false,
@ -137,21 +137,21 @@ func TestConsul_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
consul, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, consul.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, consul.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestConsul_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func(t *testing.T) (consul *Consul, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
wantNumOfCharts int
wantMetrics map[string]int64
}{
@ -532,23 +532,23 @@ func TestConsul_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
consul, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
mx := consul.Collect()
mx := collr.Collect()
delete(mx, "autopilot_server_stable_time")
delete(test.wantMetrics, "autopilot_server_stable_time")
require.Equal(t, test.wantMetrics, mx)
if len(test.wantMetrics) > 0 {
assert.Equal(t, test.wantNumOfCharts, len(*consul.Charts()))
assert.Equal(t, test.wantNumOfCharts, len(*collr.Charts()))
}
})
}
}
func caseConsulV1143CloudServerResponse(t *testing.T) (*Consul, func()) {
func caseConsulV1143CloudServerResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -568,15 +568,15 @@ func caseConsulV1143CloudServerResponse(t *testing.T) (*Consul, func()) {
}
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseConsulV1132ServerResponse(t *testing.T) (*Consul, func()) {
func caseConsulV1132ServerResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -596,15 +596,15 @@ func caseConsulV1132ServerResponse(t *testing.T) (*Consul, func()) {
}
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseConsulV1132ServerWithHostnameResponse(t *testing.T) (*Consul, func()) {
func caseConsulV1132ServerWithHostnameResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -624,15 +624,15 @@ func caseConsulV1132ServerWithHostnameResponse(t *testing.T) (*Consul, func()) {
}
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseConsulV1132ServerWithDisabledPrometheus(t *testing.T) (*Consul, func()) {
func caseConsulV1132ServerWithDisabledPrometheus(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -650,15 +650,15 @@ func caseConsulV1132ServerWithDisabledPrometheus(t *testing.T) (*Consul, func())
}
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseConsulV1132ClientResponse(t *testing.T) (*Consul, func()) {
func caseConsulV1132ClientResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -674,48 +674,48 @@ func caseConsulV1132ClientResponse(t *testing.T) (*Consul, func()) {
}
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseInvalidDataResponse(t *testing.T) (*Consul, func()) {
func caseInvalidDataResponse(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
consul := New()
consul.URL = srv.URL
collr := New()
collr.URL = srv.URL
require.NoError(t, consul.Init())
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}
func caseConnectionRefused(t *testing.T) (*Consul, func()) {
func caseConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
consul := New()
consul.URL = "http://127.0.0.1:65535/"
require.NoError(t, consul.Init())
collr := New()
collr.URL = "http://127.0.0.1:65535/"
require.NoError(t, collr.Init())
return consul, func() {}
return collr, func() {}
}
func case404(t *testing.T) (*Consul, func()) {
func case404(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
consul := New()
consul.URL = srv.URL
require.NoError(t, consul.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return consul, srv.Close
return collr, srv.Close
}

View file

@ -11,20 +11,20 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (c *Consul) validateConfig() error {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("'url' not set")
}
return nil
}
func (c *Consul) initHTTPClient() (*http.Client, error) {
func (c *Collector) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(c.ClientConfig)
}
const urlPathAgentMetrics = "/v1/agent/metrics"
func (c *Consul) initPrometheusClient(httpClient *http.Client) (prometheus.Prometheus, error) {
func (c *Collector) initPrometheusClient(httpClient *http.Client) (prometheus.Prometheus, error) {
r, err := web.NewHTTPRequest(c.RequestConfig.Copy())
if err != nil {
return nil, err

View file

@ -48,8 +48,8 @@ type requestMetricsNames struct {
responseRcodeCountTotal string
}
func (cd *CoreDNS) collect() (map[string]int64, error) {
raw, err := cd.prom.ScrapeSeries()
func (c *Collector) collect() (map[string]int64, error) {
raw, err := c.prom.ScrapeSeries()
if err != nil {
return nil, err
@ -59,81 +59,81 @@ func (cd *CoreDNS) collect() (map[string]int64, error) {
// some metric names are different depending on the version
// update them once
if !cd.skipVersionCheck {
cd.updateVersionDependentMetrics(raw)
cd.skipVersionCheck = true
if !c.skipVersionCheck {
c.updateVersionDependentMetrics(raw)
c.skipVersionCheck = true
}
//we can only get these metrics if we know the server version
if cd.version == nil {
if c.version == nil {
return nil, errors.New("unable to determine server version")
}
cd.collectPanic(mx, raw)
cd.collectSummaryRequests(mx, raw)
cd.collectSummaryRequestsPerType(mx, raw)
cd.collectSummaryResponsesPerRcode(mx, raw)
c.collectPanic(mx, raw)
c.collectSummaryRequests(mx, raw)
c.collectSummaryRequestsPerType(mx, raw)
c.collectSummaryResponsesPerRcode(mx, raw)
if cd.perServerMatcher != nil {
cd.collectPerServerRequests(mx, raw)
//cd.collectPerServerRequestsDuration(mx, raw)
cd.collectPerServerRequestPerType(mx, raw)
cd.collectPerServerResponsePerRcode(mx, raw)
if c.perServerMatcher != nil {
c.collectPerServerRequests(mx, raw)
//c.collectPerServerRequestsDuration(mx, raw)
c.collectPerServerRequestPerType(mx, raw)
c.collectPerServerResponsePerRcode(mx, raw)
}
if cd.perZoneMatcher != nil {
cd.collectPerZoneRequests(mx, raw)
//cd.collectPerZoneRequestsDuration(mx, raw)
cd.collectPerZoneRequestsPerType(mx, raw)
cd.collectPerZoneResponsesPerRcode(mx, raw)
if c.perZoneMatcher != nil {
c.collectPerZoneRequests(mx, raw)
//c.collectPerZoneRequestsDuration(mx, raw)
c.collectPerZoneRequestsPerType(mx, raw)
c.collectPerZoneResponsesPerRcode(mx, raw)
}
return stm.ToMap(mx), nil
}
func (cd *CoreDNS) updateVersionDependentMetrics(raw prometheus.Series) {
version := cd.parseVersion(raw)
func (c *Collector) updateVersionDependentMetrics(raw prometheus.Series) {
version := c.parseVersion(raw)
if version == nil {
return
}
cd.version = version
if cd.version.LTE(version169) {
cd.metricNames.panicCountTotal = metricPanicCountTotal169orOlder
cd.metricNames.requestCountTotal = metricRequestCountTotal169orOlder
cd.metricNames.requestTypeCountTotal = metricRequestTypeCountTotal169orOlder
cd.metricNames.responseRcodeCountTotal = metricResponseRcodeCountTotal169orOlder
c.version = version
if c.version.LTE(version169) {
c.metricNames.panicCountTotal = metricPanicCountTotal169orOlder
c.metricNames.requestCountTotal = metricRequestCountTotal169orOlder
c.metricNames.requestTypeCountTotal = metricRequestTypeCountTotal169orOlder
c.metricNames.responseRcodeCountTotal = metricResponseRcodeCountTotal169orOlder
} else {
cd.metricNames.panicCountTotal = metricPanicCountTotal170orNewer
cd.metricNames.requestCountTotal = metricRequestCountTotal170orNewer
cd.metricNames.requestTypeCountTotal = metricRequestTypeCountTotal170orNewer
cd.metricNames.responseRcodeCountTotal = metricResponseRcodeCountTotal170orNewer
c.metricNames.panicCountTotal = metricPanicCountTotal170orNewer
c.metricNames.requestCountTotal = metricRequestCountTotal170orNewer
c.metricNames.requestTypeCountTotal = metricRequestTypeCountTotal170orNewer
c.metricNames.responseRcodeCountTotal = metricResponseRcodeCountTotal170orNewer
}
}
func (cd *CoreDNS) parseVersion(raw prometheus.Series) *semver.Version {
func (c *Collector) parseVersion(raw prometheus.Series) *semver.Version {
var versionStr string
for _, metric := range raw.FindByName("coredns_build_info") {
versionStr = metric.Labels.Get("version")
}
if versionStr == "" {
cd.Error("cannot find version string in metrics")
c.Error("cannot find version string in metrics")
return nil
}
version, err := semver.Make(versionStr)
if err != nil {
cd.Errorf("failed to find server version: %v", err)
c.Errorf("failed to find server version: %v", err)
return nil
}
return &version
}
func (cd *CoreDNS) collectPanic(mx *metrics, raw prometheus.Series) {
mx.Panic.Set(raw.FindByName(cd.metricNames.panicCountTotal).Max())
func (c *Collector) collectPanic(mx *metrics, raw prometheus.Series) {
mx.Panic.Set(raw.FindByName(c.metricNames.panicCountTotal).Max())
}
func (cd *CoreDNS) collectSummaryRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestCountTotal) {
func (c *Collector) collectSummaryRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestCountTotal) {
var (
family = metric.Labels.Get("family")
proto = metric.Labels.Get("proto")
@ -162,7 +162,7 @@ func (cd *CoreDNS) collectSummaryRequests(mx *metrics, raw prometheus.Series) {
}
}
//func (cd *CoreDNS) collectSummaryRequestsDuration(mx *metrics, raw prometheus.Series) {
//func (cd *Collector) collectSummaryRequestsDuration(mx *metrics, raw prometheus.Series) {
// for _, metric := range raw.FindByName(metricRequestDurationSecondsBucket) {
// var (
// server = metric.Labels.Get("server")
@ -180,8 +180,8 @@ func (cd *CoreDNS) collectSummaryRequests(mx *metrics, raw prometheus.Series) {
// processRequestDuration(&mx.Summary.RequestConfig)
//}
func (cd *CoreDNS) collectSummaryRequestsPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestTypeCountTotal) {
func (c *Collector) collectSummaryRequestsPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestTypeCountTotal) {
var (
server = metric.Labels.Get("server")
typ = metric.Labels.Get("type")
@ -197,8 +197,8 @@ func (cd *CoreDNS) collectSummaryRequestsPerType(mx *metrics, raw prometheus.Ser
}
}
func (cd *CoreDNS) collectSummaryResponsesPerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.responseRcodeCountTotal) {
func (c *Collector) collectSummaryResponsesPerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.responseRcodeCountTotal) {
var (
rcode = metric.Labels.Get("rcode")
server = metric.Labels.Get("server")
@ -216,8 +216,8 @@ func (cd *CoreDNS) collectSummaryResponsesPerRcode(mx *metrics, raw prometheus.S
// Per Server
func (cd *CoreDNS) collectPerServerRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestCountTotal) {
func (c *Collector) collectPerServerRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestCountTotal) {
var (
family = metric.Labels.Get("family")
proto = metric.Labels.Get("proto")
@ -230,7 +230,7 @@ func (cd *CoreDNS) collectPerServerRequests(mx *metrics, raw prometheus.Series)
continue
}
if !cd.perServerMatcher.MatchString(server) {
if !c.perServerMatcher.MatchString(server) {
continue
}
@ -238,9 +238,9 @@ func (cd *CoreDNS) collectPerServerRequests(mx *metrics, raw prometheus.Series)
server = emptyServerReplaceName
}
if !cd.collectedServers[server] {
cd.addNewServerCharts(server)
cd.collectedServers[server] = true
if !c.collectedServers[server] {
c.addNewServerCharts(server)
c.collectedServers[server] = true
}
if _, ok := mx.PerServer[server]; !ok {
@ -261,7 +261,7 @@ func (cd *CoreDNS) collectPerServerRequests(mx *metrics, raw prometheus.Series)
}
}
//func (cd *CoreDNS) collectPerServerRequestsDuration(mx *metrics, raw prometheus.Series) {
//func (cd *Collector) collectPerServerRequestsDuration(mx *metrics, raw prometheus.Series) {
// for _, metric := range raw.FindByName(metricRequestDurationSecondsBucket) {
// var (
// server = metric.Labels.Get("server")
@ -298,8 +298,8 @@ func (cd *CoreDNS) collectPerServerRequests(mx *metrics, raw prometheus.Series)
// }
//}
func (cd *CoreDNS) collectPerServerRequestPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestTypeCountTotal) {
func (c *Collector) collectPerServerRequestPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestTypeCountTotal) {
var (
server = metric.Labels.Get("server")
typ = metric.Labels.Get("type")
@ -311,7 +311,7 @@ func (cd *CoreDNS) collectPerServerRequestPerType(mx *metrics, raw prometheus.Se
continue
}
if !cd.perServerMatcher.MatchString(server) {
if !c.perServerMatcher.MatchString(server) {
continue
}
@ -319,9 +319,9 @@ func (cd *CoreDNS) collectPerServerRequestPerType(mx *metrics, raw prometheus.Se
server = emptyServerReplaceName
}
if !cd.collectedServers[server] {
cd.addNewServerCharts(server)
cd.collectedServers[server] = true
if !c.collectedServers[server] {
c.addNewServerCharts(server)
c.collectedServers[server] = true
}
if _, ok := mx.PerServer[server]; !ok {
@ -332,8 +332,8 @@ func (cd *CoreDNS) collectPerServerRequestPerType(mx *metrics, raw prometheus.Se
}
}
func (cd *CoreDNS) collectPerServerResponsePerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.responseRcodeCountTotal) {
func (c *Collector) collectPerServerResponsePerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.responseRcodeCountTotal) {
var (
rcode = metric.Labels.Get("rcode")
server = metric.Labels.Get("server")
@ -345,7 +345,7 @@ func (cd *CoreDNS) collectPerServerResponsePerRcode(mx *metrics, raw prometheus.
continue
}
if !cd.perServerMatcher.MatchString(server) {
if !c.perServerMatcher.MatchString(server) {
continue
}
@ -353,9 +353,9 @@ func (cd *CoreDNS) collectPerServerResponsePerRcode(mx *metrics, raw prometheus.
server = emptyServerReplaceName
}
if !cd.collectedServers[server] {
cd.addNewServerCharts(server)
cd.collectedServers[server] = true
if !c.collectedServers[server] {
c.addNewServerCharts(server)
c.collectedServers[server] = true
}
if _, ok := mx.PerServer[server]; !ok {
@ -368,8 +368,8 @@ func (cd *CoreDNS) collectPerServerResponsePerRcode(mx *metrics, raw prometheus.
// Per Zone
func (cd *CoreDNS) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestCountTotal) {
func (c *Collector) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestCountTotal) {
var (
family = metric.Labels.Get("family")
proto = metric.Labels.Get("proto")
@ -381,7 +381,7 @@ func (cd *CoreDNS) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
continue
}
if !cd.perZoneMatcher.MatchString(zone) {
if !c.perZoneMatcher.MatchString(zone) {
continue
}
@ -389,9 +389,9 @@ func (cd *CoreDNS) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
zone = rootZoneReplaceName
}
if !cd.collectedZones[zone] {
cd.addNewZoneCharts(zone)
cd.collectedZones[zone] = true
if !c.collectedZones[zone] {
c.addNewZoneCharts(zone)
c.collectedZones[zone] = true
}
if _, ok := mx.PerZone[zone]; !ok {
@ -405,7 +405,7 @@ func (cd *CoreDNS) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
}
}
//func (cd *CoreDNS) collectPerZoneRequestsDuration(mx *metrics, raw prometheus.Series) {
//func (cd *Collector) collectPerZoneRequestsDuration(mx *metrics, raw prometheus.Series) {
// for _, metric := range raw.FindByName(metricRequestDurationSecondsBucket) {
// var (
// zone = metric.Labels.Get("zone")
@ -441,8 +441,8 @@ func (cd *CoreDNS) collectPerZoneRequests(mx *metrics, raw prometheus.Series) {
// }
//}
func (cd *CoreDNS) collectPerZoneRequestsPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.requestTypeCountTotal) {
func (c *Collector) collectPerZoneRequestsPerType(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.requestTypeCountTotal) {
var (
typ = metric.Labels.Get("type")
zone = metric.Labels.Get("zone")
@ -453,7 +453,7 @@ func (cd *CoreDNS) collectPerZoneRequestsPerType(mx *metrics, raw prometheus.Ser
continue
}
if !cd.perZoneMatcher.MatchString(zone) {
if !c.perZoneMatcher.MatchString(zone) {
continue
}
@ -461,9 +461,9 @@ func (cd *CoreDNS) collectPerZoneRequestsPerType(mx *metrics, raw prometheus.Ser
zone = rootZoneReplaceName
}
if !cd.collectedZones[zone] {
cd.addNewZoneCharts(zone)
cd.collectedZones[zone] = true
if !c.collectedZones[zone] {
c.addNewZoneCharts(zone)
c.collectedZones[zone] = true
}
if _, ok := mx.PerZone[zone]; !ok {
@ -474,8 +474,8 @@ func (cd *CoreDNS) collectPerZoneRequestsPerType(mx *metrics, raw prometheus.Ser
}
}
func (cd *CoreDNS) collectPerZoneResponsesPerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(cd.metricNames.responseRcodeCountTotal) {
func (c *Collector) collectPerZoneResponsesPerRcode(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName(c.metricNames.responseRcodeCountTotal) {
var (
rcode = metric.Labels.Get("rcode")
zone = metric.Labels.Get("zone")
@ -486,7 +486,7 @@ func (cd *CoreDNS) collectPerZoneResponsesPerRcode(mx *metrics, raw prometheus.S
continue
}
if !cd.perZoneMatcher.MatchString(zone) {
if !c.perZoneMatcher.MatchString(zone) {
continue
}
@ -494,9 +494,9 @@ func (cd *CoreDNS) collectPerZoneResponsesPerRcode(mx *metrics, raw prometheus.S
zone = rootZoneReplaceName
}
if !cd.collectedZones[zone] {
cd.addNewZoneCharts(zone)
cd.collectedZones[zone] = true
if !c.collectedZones[zone] {
c.addNewZoneCharts(zone)
c.collectedZones[zone] = true
}
if _, ok := mx.PerZone[zone]; !ok {
@ -684,7 +684,7 @@ func setResponsePerRcode(mx *response, value float64, rcode string) {
// ---
func (cd *CoreDNS) addNewServerCharts(name string) {
func (c *Collector) addNewServerCharts(name string) {
charts := serverCharts.Copy()
for _, chart := range *charts {
chart.ID = fmt.Sprintf(chart.ID, "server", name)
@ -695,10 +695,10 @@ func (cd *CoreDNS) addNewServerCharts(name string) {
dim.ID = fmt.Sprintf(dim.ID, name)
}
}
_ = cd.charts.Add(*charts...)
_ = c.charts.Add(*charts...)
}
func (cd *CoreDNS) addNewZoneCharts(name string) {
func (c *Collector) addNewZoneCharts(name string) {
charts := zoneCharts.Copy()
for _, chart := range *charts {
chart.ID = fmt.Sprintf(chart.ID, "zone", name)
@ -710,5 +710,5 @@ func (cd *CoreDNS) addNewZoneCharts(name string) {
dim.ID = fmt.Sprintf(dim.ID, name)
}
}
_ = cd.charts.Add(*charts...)
_ = c.charts.Add(*charts...)
}

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *CoreDNS {
return &CoreDNS{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -53,7 +53,7 @@ type Config struct {
PerZoneStats matcher.SimpleExpr `yaml:"per_zone_stats,omitempty" json:"per_zone_stats"`
}
type CoreDNS struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -70,42 +70,42 @@ type CoreDNS struct {
metricNames requestMetricsNames
}
func (cd *CoreDNS) Configuration() any {
return cd.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (cd *CoreDNS) Init() error {
if err := cd.validateConfig(); err != nil {
func (c *Collector) Init() error {
if err := c.validateConfig(); err != nil {
return fmt.Errorf("config validation: %v", err)
}
sm, err := cd.initPerServerMatcher()
sm, err := c.initPerServerMatcher()
if err != nil {
return fmt.Errorf("init per_server_stats: %v", err)
}
if sm != nil {
cd.perServerMatcher = sm
c.perServerMatcher = sm
}
zm, err := cd.initPerZoneMatcher()
zm, err := c.initPerZoneMatcher()
if err != nil {
return fmt.Errorf("init per_zone_stats: %v", err)
}
if zm != nil {
cd.perZoneMatcher = zm
c.perZoneMatcher = zm
}
prom, err := cd.initPrometheusClient()
prom, err := c.initPrometheusClient()
if err != nil {
return fmt.Errorf("init prometheus client: %v", err)
}
cd.prom = prom
c.prom = prom
return nil
}
func (cd *CoreDNS) Check() error {
mx, err := cd.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -116,23 +116,23 @@ func (cd *CoreDNS) Check() error {
return nil
}
func (cd *CoreDNS) Charts() *Charts {
return cd.charts
func (c *Collector) Charts() *Charts {
return c.charts
}
func (cd *CoreDNS) Collect() map[string]int64 {
mx, err := cd.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
cd.Error(err)
c.Error(err)
return nil
}
return mx
}
func (cd *CoreDNS) Cleanup() {
if cd.prom != nil && cd.prom.HTTPClient() != nil {
cd.prom.HTTPClient().CloseIdleConnections()
func (c *Collector) Cleanup() {
if c.prom != nil && c.prom.HTTPClient() != nil {
c.prom.HTTPClient().CloseIdleConnections()
}
}

View file

@ -41,29 +41,29 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCoreDNS_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &CoreDNS{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestCoreDNS_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestCoreDNS_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
New().Cleanup()
}
func TestCoreDNS_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
assert.NoError(t, New().Init())
}
func TestCoreDNS_InitNG(t *testing.T) {
job := New()
job.URL = ""
assert.Error(t, job.Init())
func TestCollector_InitNG(t *testing.T) {
collr := New()
collr.URL = ""
assert.Error(t, collr.Init())
}
func TestCoreDNS_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := []struct {
name string
data []byte
@ -81,22 +81,22 @@ func TestCoreDNS_Check(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
require.NoError(t, job.Init())
assert.NoError(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
require.NoError(t, collr.Init())
assert.NoError(t, collr.Check())
})
}
}
func TestCoreDNS_CheckNG(t *testing.T) {
job := New()
job.URL = "http://127.0.0.1:38001/metrics"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
func TestCollector_CheckNG(t *testing.T) {
collr := New()
collr.URL = "http://127.0.0.1:38001/metrics"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestCoreDNS_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := []struct {
name string
data []byte
@ -114,12 +114,12 @@ func TestCoreDNS_Collect(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
job.PerServerStats.Includes = []string{"glob:*"}
job.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, job.Init())
require.NoError(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
collr.PerServerStats.Includes = []string{"glob:*"}
collr.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
expected := map[string]int64{
"coredns.io._request_per_ip_family_v4": 19,
@ -441,12 +441,12 @@ func TestCoreDNS_Collect(t *testing.T) {
"ya.ru._response_total": 21,
}
assert.Equal(t, expected, job.Collect())
assert.Equal(t, expected, collr.Collect())
})
}
}
func TestCoreDNS_CollectNoLoad(t *testing.T) {
func TestCollector_CollectNoLoad(t *testing.T) {
tests := []struct {
name string
data []byte
@ -463,12 +463,12 @@ func TestCoreDNS_CollectNoLoad(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
job.PerServerStats.Includes = []string{"glob:*"}
job.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, job.Init())
require.NoError(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
collr.PerServerStats.Includes = []string{"glob:*"}
collr.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, collr.Init())
require.NoError(t, collr.Check())
expected := map[string]int64{
"no_matching_zone_dropped_total": 0,
@ -520,13 +520,13 @@ func TestCoreDNS_CollectNoLoad(t *testing.T) {
"response_total": 0,
}
assert.Equal(t, expected, job.Collect())
assert.Equal(t, expected, collr.Collect())
})
}
}
func TestCoreDNS_InvalidData(t *testing.T) {
func TestCollector_InvalidData(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -534,13 +534,13 @@ func TestCoreDNS_InvalidData(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestCoreDNS_404(t *testing.T) {
func TestCollector_404(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -548,13 +548,13 @@ func TestCoreDNS_404(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
require.NoError(t, job.Init())
assert.Error(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
require.NoError(t, collr.Init())
assert.Error(t, collr.Check())
}
func TestCoreDNS_CollectNoVersion(t *testing.T) {
func TestCollector_CollectNoVersion(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
@ -562,12 +562,12 @@ func TestCoreDNS_CollectNoVersion(t *testing.T) {
}))
defer ts.Close()
job := New()
job.URL = ts.URL + "/metrics"
job.PerServerStats.Includes = []string{"glob:*"}
job.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, job.Init())
require.Error(t, job.Check())
collr := New()
collr.URL = ts.URL + "/metrics"
collr.PerServerStats.Includes = []string{"glob:*"}
collr.PerZoneStats.Includes = []string{"glob:*"}
require.NoError(t, collr.Init())
require.Error(t, collr.Check())
assert.Nil(t, job.Collect())
assert.Nil(t, collr.Collect())
}

View file

@ -10,31 +10,31 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (cd *CoreDNS) validateConfig() error {
if cd.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("url not set")
}
return nil
}
func (cd *CoreDNS) initPerServerMatcher() (matcher.Matcher, error) {
if cd.PerServerStats.Empty() {
func (c *Collector) initPerServerMatcher() (matcher.Matcher, error) {
if c.PerServerStats.Empty() {
return nil, nil
}
return cd.PerServerStats.Parse()
return c.PerServerStats.Parse()
}
func (cd *CoreDNS) initPerZoneMatcher() (matcher.Matcher, error) {
if cd.PerZoneStats.Empty() {
func (c *Collector) initPerZoneMatcher() (matcher.Matcher, error) {
if c.PerZoneStats.Empty() {
return nil, nil
}
return cd.PerZoneStats.Parse()
return c.PerZoneStats.Parse()
}
func (cd *CoreDNS) initPrometheusClient() (prometheus.Prometheus, error) {
client, err := web.NewHTTPClient(cd.ClientConfig)
func (c *Collector) initPrometheusClient() (prometheus.Prometheus, error) {
client, err := web.NewHTTPClient(c.ClientConfig)
if err != nil {
return nil, err
}
return prometheus.New(client, cd.RequestConfig), nil
return prometheus.New(client, c.RequestConfig), nil
}

View file

@ -16,8 +16,8 @@ const (
precision = 1000
)
func (cb *Couchbase) collect() (map[string]int64, error) {
ms, err := cb.scrapeCouchbase()
func (c *Collector) collect() (map[string]int64, error) {
ms, err := c.scrapeCouchbase()
if err != nil {
return nil, fmt.Errorf("error on scraping couchbase: %v", err)
}
@ -26,17 +26,17 @@ func (cb *Couchbase) collect() (map[string]int64, error) {
}
collected := make(map[string]int64)
cb.collectBasicStats(collected, ms)
c.collectBasicStats(collected, ms)
return collected, nil
}
func (cb *Couchbase) collectBasicStats(collected map[string]int64, ms *cbMetrics) {
func (c *Collector) collectBasicStats(collected map[string]int64, ms *cbMetrics) {
for _, b := range ms.BucketsBasicStats {
if !cb.collectedBuckets[b.Name] {
cb.collectedBuckets[b.Name] = true
cb.addBucketToCharts(b.Name)
if !c.collectedBuckets[b.Name] {
c.collectedBuckets[b.Name] = true
c.addBucketToCharts(b.Name)
}
bs := b.BasicStats
@ -51,72 +51,72 @@ func (cb *Couchbase) collectBasicStats(collected map[string]int64, ms *cbMetrics
}
}
func (cb *Couchbase) addBucketToCharts(bucket string) {
cb.addDimToChart(bucketQuotaPercentUsedChart.ID, &module.Dim{
func (c *Collector) addBucketToCharts(bucket string) {
c.addDimToChart(bucketQuotaPercentUsedChart.ID, &module.Dim{
ID: indexDimID(bucket, "quota_percent_used"),
Name: bucket,
Div: precision,
})
cb.addDimToChart(bucketOpsPerSecChart.ID, &module.Dim{
c.addDimToChart(bucketOpsPerSecChart.ID, &module.Dim{
ID: indexDimID(bucket, "ops_per_sec"),
Name: bucket,
Div: precision,
})
cb.addDimToChart(bucketDiskFetchesChart.ID, &module.Dim{
c.addDimToChart(bucketDiskFetchesChart.ID, &module.Dim{
ID: indexDimID(bucket, "disk_fetches"),
Name: bucket,
})
cb.addDimToChart(bucketItemCountChart.ID, &module.Dim{
c.addDimToChart(bucketItemCountChart.ID, &module.Dim{
ID: indexDimID(bucket, "item_count"),
Name: bucket,
})
cb.addDimToChart(bucketDiskUsedChart.ID, &module.Dim{
c.addDimToChart(bucketDiskUsedChart.ID, &module.Dim{
ID: indexDimID(bucket, "disk_used"),
Name: bucket,
})
cb.addDimToChart(bucketDataUsedChart.ID, &module.Dim{
c.addDimToChart(bucketDataUsedChart.ID, &module.Dim{
ID: indexDimID(bucket, "data_used"),
Name: bucket,
})
cb.addDimToChart(bucketMemUsedChart.ID, &module.Dim{
c.addDimToChart(bucketMemUsedChart.ID, &module.Dim{
ID: indexDimID(bucket, "mem_used"),
Name: bucket,
})
cb.addDimToChart(bucketVBActiveNumNonResidentChart.ID, &module.Dim{
c.addDimToChart(bucketVBActiveNumNonResidentChart.ID, &module.Dim{
ID: indexDimID(bucket, "vb_active_num_non_resident"),
Name: bucket,
})
}
func (cb *Couchbase) addDimToChart(chartID string, dim *module.Dim) {
chart := cb.Charts().Get(chartID)
func (c *Collector) addDimToChart(chartID string, dim *module.Dim) {
chart := c.Charts().Get(chartID)
if chart == nil {
cb.Warningf("error on adding '%s' dimension: can not find '%s' chart", dim.ID, chartID)
c.Warningf("error on adding '%s' dimension: can not find '%s' chart", dim.ID, chartID)
return
}
if err := chart.AddDim(dim); err != nil {
cb.Warning(err)
c.Warning(err)
return
}
chart.MarkNotCreated()
}
func (cb *Couchbase) scrapeCouchbase() (*cbMetrics, error) {
req, err := web.NewHTTPRequestWithPath(cb.RequestConfig, urlPathBucketsStats)
func (c *Collector) scrapeCouchbase() (*cbMetrics, error) {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathBucketsStats)
if err != nil {
return nil, err
}
req.URL.RawQuery = url.Values{"skipMap": []string{"true"}}.Encode()
ms := &cbMetrics{}
if err := web.DoHTTP(cb.httpClient).RequestJSON(req, &ms.BucketsBasicStats); err != nil {
if err := web.DoHTTP(c.httpClient).RequestJSON(req, &ms.BucketsBasicStats); err != nil {
return nil, err
}

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *Couchbase {
return &Couchbase{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -49,7 +49,7 @@ type Config struct {
web.HTTPConfig `yaml:",inline" json:""`
}
type Couchbase struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -59,33 +59,33 @@ type Couchbase struct {
collectedBuckets map[string]bool
}
func (cb *Couchbase) Configuration() any {
return cb.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (cb *Couchbase) Init() error {
err := cb.validateConfig()
func (c *Collector) Init() error {
err := c.validateConfig()
if err != nil {
return fmt.Errorf("check configuration: %v", err)
}
httpClient, err := cb.initHTTPClient()
httpClient, err := c.initHTTPClient()
if err != nil {
return fmt.Errorf("init HTTP client: %v", err)
}
cb.httpClient = httpClient
c.httpClient = httpClient
charts, err := cb.initCharts()
charts, err := c.initCharts()
if err != nil {
return fmt.Errorf("init charts: %v", err)
}
cb.charts = charts
c.charts = charts
return nil
}
func (cb *Couchbase) Check() error {
mx, err := cb.collect()
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
}
@ -96,14 +96,14 @@ func (cb *Couchbase) Check() error {
return nil
}
func (cb *Couchbase) Charts() *Charts {
return cb.charts
func (c *Collector) Charts() *Charts {
return c.charts
}
func (cb *Couchbase) Collect() map[string]int64 {
mx, err := cb.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
cb.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -112,9 +112,9 @@ func (cb *Couchbase) Collect() map[string]int64 {
return mx
}
func (cb *Couchbase) Cleanup() {
if cb.httpClient == nil {
func (c *Collector) Cleanup() {
if c.httpClient == nil {
return
}
cb.httpClient.CloseIdleConnections()
c.httpClient.CloseIdleConnections()
}

View file

@ -32,11 +32,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCouchbase_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Couchbase{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestCouchbase_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -68,21 +68,21 @@ func TestCouchbase_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cb := New()
cb.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, cb.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, cb.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestCouchbase_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepare func(*testing.T) (cb *Couchbase, cleanup func())
prepare func(*testing.T) (collr *Collector, cleanup func())
wantFail bool
}{
"success on valid response v6.6.0": {
@ -104,21 +104,21 @@ func TestCouchbase_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cb, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, cb.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, cb.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestCouchbase_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func(t *testing.T) (cb *Couchbase, cleanup func())
prepare func(t *testing.T) (collr *Collector, cleanup func())
wantCollected map[string]int64
}{
"success on valid response v6.6.0": {
@ -163,62 +163,62 @@ func TestCouchbase_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cb, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
mx := cb.Collect()
mx := collr.Collect()
assert.Equal(t, test.wantCollected, mx)
module.TestMetricsHasAllChartsDims(t, cb.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
})
}
}
func prepareCouchbaseV660(t *testing.T) (cb *Couchbase, cleanup func()) {
func prepareCouchbaseV660(t *testing.T) (collr *Collector, cleanup func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(dataVer660BucketsBasicStats)
}))
cb = New()
cb.URL = srv.URL
require.NoError(t, cb.Init())
collr = New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return cb, srv.Close
return collr, srv.Close
}
func prepareCouchbaseInvalidData(t *testing.T) (*Couchbase, func()) {
func prepareCouchbaseInvalidData(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
cb := New()
cb.URL = srv.URL
require.NoError(t, cb.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return cb, srv.Close
return collr, srv.Close
}
func prepareCouchbase404(t *testing.T) (*Couchbase, func()) {
func prepareCouchbase404(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
cb := New()
cb.URL = srv.URL
require.NoError(t, cb.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return cb, srv.Close
return collr, srv.Close
}
func prepareCouchbaseConnectionRefused(t *testing.T) (*Couchbase, func()) {
func prepareCouchbaseConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
cb := New()
cb.URL = "http://127.0.0.1:38001"
require.NoError(t, cb.Init())
collr := New()
collr.URL = "http://127.0.0.1:38001"
require.NoError(t, collr.Init())
return cb, func() {}
return collr, func() {}
}

View file

@ -10,7 +10,7 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (cb *Couchbase) initCharts() (*Charts, error) {
func (c *Collector) initCharts() (*Charts, error) {
var bucketCharts = module.Charts{
bucketQuotaPercentUsedChart.Copy(),
bucketOpsPerSecChart.Copy(),
@ -24,15 +24,15 @@ func (cb *Couchbase) initCharts() (*Charts, error) {
return bucketCharts.Copy(), nil
}
func (cb *Couchbase) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(cb.ClientConfig)
func (c *Collector) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(c.ClientConfig)
}
func (cb *Couchbase) validateConfig() error {
if cb.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("URL not set")
}
if _, err := web.NewHTTPRequest(cb.RequestConfig); err != nil {
if _, err := web.NewHTTPRequest(c.RequestConfig); err != nil {
return err
}
return nil

View file

@ -27,22 +27,22 @@ const (
httpStatusCodePrefixLen = len(httpStatusCodePrefix)
)
func (cdb *CouchDB) collect() (map[string]int64, error) {
ms := cdb.scrapeCouchDB()
func (c *Collector) collect() (map[string]int64, error) {
ms := c.scrapeCouchDB()
if ms.empty() {
return nil, nil
}
collected := make(map[string]int64)
cdb.collectNodeStats(collected, ms)
cdb.collectSystemStats(collected, ms)
cdb.collectActiveTasks(collected, ms)
cdb.collectDBStats(collected, ms)
c.collectNodeStats(collected, ms)
c.collectSystemStats(collected, ms)
c.collectActiveTasks(collected, ms)
c.collectDBStats(collected, ms)
return collected, nil
}
func (cdb *CouchDB) collectNodeStats(collected map[string]int64, ms *cdbMetrics) {
func (c *Collector) collectNodeStats(collected map[string]int64, ms *cdbMetrics) {
if !ms.hasNodeStats() {
return
}
@ -56,7 +56,7 @@ func (cdb *CouchDB) collectNodeStats(collected map[string]int64, ms *cdbMetrics)
}
}
func (cdb *CouchDB) collectSystemStats(collected map[string]int64, ms *cdbMetrics) {
func (c *Collector) collectSystemStats(collected map[string]int64, ms *cdbMetrics) {
if !ms.hasNodeSystem() {
return
}
@ -68,7 +68,7 @@ func (cdb *CouchDB) collectSystemStats(collected map[string]int64, ms *cdbMetric
collected["peak_msg_queue"] = findMaxMQSize(ms.NodeSystem.MessageQueues)
}
func (cdb *CouchDB) collectActiveTasks(collected map[string]int64, ms *cdbMetrics) {
func (c *Collector) collectActiveTasks(collected map[string]int64, ms *cdbMetrics) {
collected["active_tasks_indexer"] = 0
collected["active_tasks_database_compaction"] = 0
collected["active_tasks_replication"] = 0
@ -83,83 +83,83 @@ func (cdb *CouchDB) collectActiveTasks(collected map[string]int64, ms *cdbMetric
}
}
func (cdb *CouchDB) collectDBStats(collected map[string]int64, ms *cdbMetrics) {
func (c *Collector) collectDBStats(collected map[string]int64, ms *cdbMetrics) {
if !ms.hasDBStats() {
return
}
for _, dbStats := range ms.DBStats {
if dbStats.Error != "" {
cdb.Warning("database '", dbStats.Key, "' doesn't exist")
c.Warning("database '", dbStats.Key, "' doesn't exist")
continue
}
merge(collected, stm.ToMap(dbStats.Info), "db_"+dbStats.Key)
}
}
func (cdb *CouchDB) scrapeCouchDB() *cdbMetrics {
func (c *Collector) scrapeCouchDB() *cdbMetrics {
ms := &cdbMetrics{}
wg := &sync.WaitGroup{}
wg.Add(1)
go func() { defer wg.Done(); cdb.scrapeNodeStats(ms) }()
go func() { defer wg.Done(); c.scrapeNodeStats(ms) }()
wg.Add(1)
go func() { defer wg.Done(); cdb.scrapeSystemStats(ms) }()
go func() { defer wg.Done(); c.scrapeSystemStats(ms) }()
wg.Add(1)
go func() { defer wg.Done(); cdb.scrapeActiveTasks(ms) }()
go func() { defer wg.Done(); c.scrapeActiveTasks(ms) }()
if len(cdb.databases) > 0 {
if len(c.databases) > 0 {
wg.Add(1)
go func() { defer wg.Done(); cdb.scrapeDBStats(ms) }()
go func() { defer wg.Done(); c.scrapeDBStats(ms) }()
}
wg.Wait()
return ms
}
func (cdb *CouchDB) scrapeNodeStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(cdb.RequestConfig, fmt.Sprintf(urlPathOverviewStats, cdb.Config.Node))
func (c *Collector) scrapeNodeStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(c.RequestConfig, fmt.Sprintf(urlPathOverviewStats, c.Config.Node))
var stats cdbNodeStats
if err := cdb.client().RequestJSON(req, &stats); err != nil {
cdb.Warning(err)
if err := c.client().RequestJSON(req, &stats); err != nil {
c.Warning(err)
return
}
ms.NodeStats = &stats
}
func (cdb *CouchDB) scrapeSystemStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(cdb.RequestConfig, fmt.Sprintf(urlPathSystemStats, cdb.Config.Node))
func (c *Collector) scrapeSystemStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(c.RequestConfig, fmt.Sprintf(urlPathSystemStats, c.Config.Node))
var stats cdbNodeSystem
if err := cdb.client().RequestJSON(req, &stats); err != nil {
cdb.Warning(err)
if err := c.client().RequestJSON(req, &stats); err != nil {
c.Warning(err)
return
}
ms.NodeSystem = &stats
}
func (cdb *CouchDB) scrapeActiveTasks(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(cdb.RequestConfig, urlPathActiveTasks)
func (c *Collector) scrapeActiveTasks(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathActiveTasks)
var stats []cdbActiveTask
if err := cdb.client().RequestJSON(req, &stats); err != nil {
cdb.Warning(err)
if err := c.client().RequestJSON(req, &stats); err != nil {
c.Warning(err)
return
}
ms.ActiveTasks = stats
}
func (cdb *CouchDB) scrapeDBStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(cdb.RequestConfig, urlPathDatabases)
func (c *Collector) scrapeDBStats(ms *cdbMetrics) {
req, _ := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathDatabases)
req.Method = http.MethodPost
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
@ -167,18 +167,18 @@ func (cdb *CouchDB) scrapeDBStats(ms *cdbMetrics) {
var q struct {
Keys []string `json:"keys"`
}
q.Keys = cdb.databases
q.Keys = c.databases
body, err := json.Marshal(q)
if err != nil {
cdb.Error(err)
c.Error(err)
return
}
req.Body = io.NopCloser(bytes.NewReader(body))
var stats []cdbDBStats
if err := cdb.client().RequestJSON(req, &stats); err != nil {
cdb.Warning(err)
if err := c.client().RequestJSON(req, &stats); err != nil {
c.Warning(err)
return
}
@ -200,12 +200,12 @@ func findMaxMQSize(MessageQueues map[string]any) int64 {
return int64(maxSize)
}
func (cdb *CouchDB) pingCouchDB() error {
req, _ := web.NewHTTPRequest(cdb.RequestConfig)
func (c *Collector) pingCouchDB() error {
req, _ := web.NewHTTPRequest(c.RequestConfig)
var info struct{ Couchdb string }
if err := cdb.client().RequestJSON(req, &info); err != nil {
if err := c.client().RequestJSON(req, &info); err != nil {
return err
}
@ -216,8 +216,8 @@ func (cdb *CouchDB) pingCouchDB() error {
return nil
}
func (cdb *CouchDB) client() *web.Client {
return web.DoHTTP(cdb.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
func (c *Collector) client() *web.Client {
return web.DoHTTP(c.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
var msg struct {
Error string `json:"error"`
Reason string `json:"reason"`

View file

@ -29,8 +29,8 @@ func init() {
})
}
func New() *CouchDB {
return &CouchDB{
func New() *Collector {
return &Collector{
Config: Config{
HTTPConfig: web.HTTPConfig{
RequestConfig: web.RequestConfig{
@ -52,7 +52,7 @@ type Config struct {
Databases string `yaml:"databases,omitempty" json:"databases"`
}
type CouchDB struct {
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
@ -63,39 +63,39 @@ type CouchDB struct {
databases []string
}
func (cdb *CouchDB) Configuration() any {
return cdb.Config
func (c *Collector) Configuration() any {
return c.Config
}
func (cdb *CouchDB) Init() error {
err := cdb.validateConfig()
func (c *Collector) Init() error {
err := c.validateConfig()
if err != nil {
return fmt.Errorf("check configuration: %v", err)
}
cdb.databases = strings.Fields(cdb.Config.Databases)
c.databases = strings.Fields(c.Config.Databases)
httpClient, err := cdb.initHTTPClient()
httpClient, err := c.initHTTPClient()
if err != nil {
return fmt.Errorf("init HTTP client: %v", err)
}
cdb.httpClient = httpClient
c.httpClient = httpClient
charts, err := cdb.initCharts()
charts, err := c.initCharts()
if err != nil {
return fmt.Errorf("init charts: %v", err)
}
cdb.charts = charts
c.charts = charts
return nil
}
func (cdb *CouchDB) Check() error {
if err := cdb.pingCouchDB(); err != nil {
func (c *Collector) Check() error {
if err := c.pingCouchDB(); err != nil {
return err
}
mx, err := cdb.collect()
mx, err := c.collect()
if err != nil {
return err
}
@ -107,14 +107,14 @@ func (cdb *CouchDB) Check() error {
return nil
}
func (cdb *CouchDB) Charts() *Charts {
return cdb.charts
func (c *Collector) Charts() *Charts {
return c.charts
}
func (cdb *CouchDB) Collect() map[string]int64 {
mx, err := cdb.collect()
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
cdb.Error(err)
c.Error(err)
}
if len(mx) == 0 {
@ -123,9 +123,9 @@ func (cdb *CouchDB) Collect() map[string]int64 {
return mx
}
func (cdb *CouchDB) Cleanup() {
if cdb.httpClient == nil {
func (c *Collector) Cleanup() {
if c.httpClient == nil {
return
}
cdb.httpClient.CloseIdleConnections()
c.httpClient.CloseIdleConnections()
}

View file

@ -41,11 +41,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestCouchDB_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &CouchDB{}, dataConfigJSON, dataConfigYAML)
func TestCollector_ConfigurationSerialize(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestCouchDB_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantNumOfCharts int
@ -80,22 +80,22 @@ func TestCouchDB_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
es := New()
es.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, es.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, es.Init())
assert.Equal(t, test.wantNumOfCharts, len(*es.Charts()))
assert.NoError(t, collr.Init())
assert.Equal(t, test.wantNumOfCharts, len(*collr.Charts()))
}
})
}
}
func TestCouchDB_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepare func(*testing.T) (cdb *CouchDB, cleanup func())
prepare func(*testing.T) (collr *Collector, cleanup func())
wantFail bool
}{
"valid data": {prepare: prepareCouchDBValidData},
@ -106,37 +106,37 @@ func TestCouchDB_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cdb, cleanup := test.prepare(t)
collr, cleanup := test.prepare(t)
defer cleanup()
if test.wantFail {
assert.Error(t, cdb.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, cdb.Check())
assert.NoError(t, collr.Check())
}
})
}
}
func TestCouchDB_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.Nil(t, New().Charts())
}
func TestCouchDB_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
assert.NotPanics(t, New().Cleanup)
}
func TestCouchDB_Collect(t *testing.T) {
func TestCollector_Collect(t *testing.T) {
tests := map[string]struct {
prepare func() *CouchDB
prepare func() *Collector
wantCollected map[string]int64
checkCharts bool
}{
"all stats": {
prepare: func() *CouchDB {
cdb := New()
cdb.Config.Databases = "db1 db2"
return cdb
prepare: func() *Collector {
collr := New()
collr.Config.Databases = "db1 db2"
return collr
},
wantCollected: map[string]int64{
@ -225,11 +225,11 @@ func TestCouchDB_Collect(t *testing.T) {
checkCharts: true,
},
"wrong node": {
prepare: func() *CouchDB {
cdb := New()
cdb.Config.Node = "bad_node@bad_host"
cdb.Config.Databases = "db1 db2"
return cdb
prepare: func() *Collector {
collr := New()
collr.Config.Node = "bad_node@bad_host"
collr.Config.Databases = "db1 db2"
return collr
},
wantCollected: map[string]int64{
@ -259,10 +259,10 @@ func TestCouchDB_Collect(t *testing.T) {
checkCharts: false,
},
"wrong database": {
prepare: func() *CouchDB {
cdb := New()
cdb.Config.Databases = "bad_db db1 db2"
return cdb
prepare: func() *Collector {
collr := New()
collr.Config.Databases = "bad_db db1 db2"
return collr
},
wantCollected: map[string]int64{
@ -354,70 +354,70 @@ func TestCouchDB_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cdb, cleanup := prepareCouchDB(t, test.prepare)
collr, cleanup := prepareCouchDB(t, test.prepare)
defer cleanup()
var mx map[string]int64
for i := 0; i < 10; i++ {
mx = cdb.Collect()
mx = collr.Collect()
}
assert.Equal(t, test.wantCollected, mx)
if test.checkCharts {
module.TestMetricsHasAllChartsDims(t, cdb.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
}
})
}
}
func prepareCouchDB(t *testing.T, createCDB func() *CouchDB) (cdb *CouchDB, cleanup func()) {
func prepareCouchDB(t *testing.T, createCDB func() *Collector) (collr *Collector, cleanup func()) {
t.Helper()
cdb = createCDB()
collr = createCDB()
srv := prepareCouchDBEndpoint()
cdb.URL = srv.URL
collr.URL = srv.URL
require.NoError(t, cdb.Init())
require.NoError(t, collr.Init())
return cdb, srv.Close
return collr, srv.Close
}
func prepareCouchDBValidData(t *testing.T) (cdb *CouchDB, cleanup func()) {
func prepareCouchDBValidData(t *testing.T) (collr *Collector, cleanup func()) {
return prepareCouchDB(t, New)
}
func prepareCouchDBInvalidData(t *testing.T) (*CouchDB, func()) {
func prepareCouchDBInvalidData(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("hello and\n goodbye"))
}))
cdb := New()
cdb.URL = srv.URL
require.NoError(t, cdb.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return cdb, srv.Close
return collr, srv.Close
}
func prepareCouchDB404(t *testing.T) (*CouchDB, func()) {
func prepareCouchDB404(t *testing.T) (*Collector, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
cdb := New()
cdb.URL = srv.URL
require.NoError(t, cdb.Init())
collr := New()
collr.URL = srv.URL
require.NoError(t, collr.Init())
return cdb, srv.Close
return collr, srv.Close
}
func prepareCouchDBConnectionRefused(t *testing.T) (*CouchDB, func()) {
func prepareCouchDBConnectionRefused(t *testing.T) (*Collector, func()) {
t.Helper()
cdb := New()
cdb.URL = "http://127.0.0.1:38001"
require.NoError(t, cdb.Init())
collr := New()
collr.URL = "http://127.0.0.1:38001"
require.NoError(t, collr.Init())
return cdb, func() {}
return collr, func() {}
}
func prepareCouchDBEndpoint() *httptest.Server {

View file

@ -10,24 +10,24 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
func (cdb *CouchDB) validateConfig() error {
if cdb.URL == "" {
func (c *Collector) validateConfig() error {
if c.URL == "" {
return errors.New("URL not set")
}
if cdb.Node == "" {
if c.Node == "" {
return errors.New("'node' not set")
}
if _, err := web.NewHTTPRequest(cdb.RequestConfig); err != nil {
if _, err := web.NewHTTPRequest(c.RequestConfig); err != nil {
return err
}
return nil
}
func (cdb *CouchDB) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(cdb.ClientConfig)
func (c *Collector) initHTTPClient() (*http.Client, error) {
return web.NewHTTPClient(c.ClientConfig)
}
func (cdb *CouchDB) initCharts() (*Charts, error) {
func (c *Collector) initCharts() (*Charts, error) {
charts := module.Charts{}
if err := charts.Add(*dbActivityCharts.Copy()...); err != nil {
@ -39,7 +39,7 @@ func (cdb *CouchDB) initCharts() (*Charts, error) {
if err := charts.Add(*serverOperationsCharts.Copy()...); err != nil {
return nil, err
}
if len(cdb.databases) != 0 {
if len(c.databases) != 0 {
dbCharts := dbSpecificCharts.Copy()
if err := charts.Add(*dbCharts...); err != nil {
@ -47,7 +47,7 @@ func (cdb *CouchDB) initCharts() (*Charts, error) {
}
for _, chart := range *dbCharts {
for _, db := range cdb.databases {
for _, db := range c.databases {
if err := chart.AddDim(&module.Dim{ID: "db_" + db + "_" + chart.ID, Name: db}); err != nil {
return nil, err
}

View file

@ -117,7 +117,7 @@ var chartDeviceDirtySizeTmpl = module.Chart{
},
}
func (c *DmCache) addDeviceCharts(device string) {
func (c *Collector) addDeviceCharts(device string) {
charts := deviceChartsTmpl.Copy()
for _, chart := range *charts {
@ -135,7 +135,7 @@ func (c *DmCache) addDeviceCharts(device string) {
}
}
func (c *DmCache) removeDeviceCharts(device string) {
func (c *Collector) removeDeviceCharts(device string) {
px := fmt.Sprintf("dmcache_device_%s_", cleanDeviceName(device))
for _, chart := range *c.Charts() {

View file

@ -30,7 +30,7 @@ type dmCacheDevice struct {
dirtyBlocks int64
}
func (c *DmCache) collect() (map[string]int64, error) {
func (c *Collector) collect() (map[string]int64, error) {
bs, err := c.exec.cacheStatus()
if err != nil {
return nil, err
@ -45,7 +45,7 @@ func (c *DmCache) collect() (map[string]int64, error) {
return mx, nil
}
func (c *DmCache) collectCacheStatus(mx map[string]int64, data []byte) error {
func (c *Collector) collectCacheStatus(mx map[string]int64, data []byte) error {
var devices []*dmCacheDevice
sc := bufio.NewScanner(bytes.NewReader(data))

View file

@ -28,8 +28,8 @@ func init() {
})
}
func New() *DmCache {
return &DmCache{
func New() *Collector {
return &Collector{
Config: Config{
Timeout: confopt.Duration(time.Second * 2),
},
@ -43,27 +43,22 @@ type Config struct {
Timeout confopt.Duration `yaml:"timeout,omitempty" json:"timeout"`
}
type (
DmCache struct {
module.Base
Config `yaml:",inline" json:""`
type Collector struct {
module.Base
Config `yaml:",inline" json:""`
charts *module.Charts
charts *module.Charts
exec dmsetupCLI
exec dmsetupCli
devices map[string]bool
}
dmsetupCLI interface {
cacheStatus() ([]byte, error)
}
)
devices map[string]bool
}
func (c *DmCache) Configuration() any {
func (c *Collector) Configuration() any {
return c.Config
}
func (c *DmCache) Init() error {
func (c *Collector) Init() error {
dmsetup, err := c.initDmsetupCLI()
if err != nil {
return fmt.Errorf("dmsetup exec initialization: %v", err)
@ -73,7 +68,7 @@ func (c *DmCache) Init() error {
return nil
}
func (c *DmCache) Check() error {
func (c *Collector) Check() error {
mx, err := c.collect()
if err != nil {
return err
@ -86,11 +81,11 @@ func (c *DmCache) Check() error {
return nil
}
func (c *DmCache) Charts() *module.Charts {
func (c *Collector) Charts() *module.Charts {
return c.charts
}
func (c *DmCache) Collect() map[string]int64 {
func (c *Collector) Collect() map[string]int64 {
mx, err := c.collect()
if err != nil {
c.Error(err)
@ -103,4 +98,4 @@ func (c *DmCache) Collect() map[string]int64 {
return mx
}
func (c *DmCache) Cleanup() {}
func (c *Collector) Cleanup() {}

View file

@ -30,11 +30,11 @@ func Test_testDataIsValid(t *testing.T) {
}
}
func TestDmCace_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &DmCache{}, dataConfigJSON, dataConfigYAML)
func TestCollector_Configuration(t *testing.T) {
module.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
}
func TestDmCache_Init(t *testing.T) {
func TestCollector_Init(t *testing.T) {
tests := map[string]struct {
config Config
wantFail bool
@ -47,59 +47,59 @@ func TestDmCache_Init(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
lvm := New()
lvm.Config = test.config
collr := New()
collr.Config = test.config
if test.wantFail {
assert.Error(t, lvm.Init())
assert.Error(t, collr.Init())
} else {
assert.NoError(t, lvm.Init())
assert.NoError(t, collr.Init())
}
})
}
}
func TestDmCache_Cleanup(t *testing.T) {
func TestCollector_Cleanup(t *testing.T) {
tests := map[string]struct {
prepare func() *DmCache
prepare func() *Collector
}{
"not initialized exec": {
prepare: func() *DmCache {
prepare: func() *Collector {
return New()
},
},
"after check": {
prepare: func() *DmCache {
lvm := New()
lvm.exec = prepareMockOK()
_ = lvm.Check()
return lvm
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOK()
_ = collr.Check()
return collr
},
},
"after collect": {
prepare: func() *DmCache {
lvm := New()
lvm.exec = prepareMockOK()
_ = lvm.Collect()
return lvm
prepare: func() *Collector {
collr := New()
collr.exec = prepareMockOK()
_ = collr.Collect()
return collr
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
lvm := test.prepare()
collr := test.prepare()
assert.NotPanics(t, lvm.Cleanup)
assert.NotPanics(t, collr.Cleanup)
})
}
}
func TestDmCache_Charts(t *testing.T) {
func TestCollector_Charts(t *testing.T) {
assert.NotNil(t, New().Charts())
}
func TestDmCache_Check(t *testing.T) {
func TestCollector_Check(t *testing.T) {
tests := map[string]struct {
prepareMock func() *mockDmsetupExec
wantFail bool
@ -124,14 +124,14 @@ func TestDmCache_Check(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
dmcache := New()
collr := New()
mock := test.prepareMock()
dmcache.exec = mock
collr.exec = mock
if test.wantFail {
assert.Error(t, dmcache.Check())
assert.Error(t, collr.Check())
} else {
assert.NoError(t, dmcache.Check())
assert.NoError(t, collr.Check())
}
})
}
@ -187,17 +187,17 @@ func TestLVM_Collect(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
dmcache := New()
collr := New()
mock := test.prepareMock()
dmcache.exec = mock
collr.exec = mock
mx := dmcache.Collect()
mx := collr.Collect()
assert.Equal(t, test.wantMetrics, mx)
assert.Len(t, *dmcache.Charts(), test.wantCharts, "wantCharts")
assert.Len(t, *collr.Charts(), test.wantCharts, "wantCharts")
module.TestMetricsHasAllChartsDims(t, dmcache.Charts(), mx)
module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
})
}
}

View file

@ -13,6 +13,10 @@ import (
"github.com/netdata/netdata/go/plugins/logger"
)
type dmsetupCli interface {
cacheStatus() ([]byte, error)
}
func newDmsetupExec(ndsudoPath string, timeout time.Duration, log *logger.Logger) *dmsetupExec {
return &dmsetupExec{
Logger: log,

View file

@ -12,7 +12,7 @@ import (
"github.com/netdata/netdata/go/plugins/pkg/executable"
)
func (c *DmCache) initDmsetupCLI() (dmsetupCLI, error) {
func (c *Collector) initDmsetupCLI() (dmsetupCli, error) {
ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
if _, err := os.Stat(ndsudoPath); err != nil {
return nil, fmt.Errorf("ndsudo executable not found: %v", err)

View file

@ -13,33 +13,33 @@ const (
urlPathJSONStat = "/jsonstat"
)
func (d *DNSdist) collect() (map[string]int64, error) {
statistics, err := d.scrapeStatistics()
func (c *Collector) collect() (map[string]int64, error) {
statistics, err := c.scrapeStatistics()
if err != nil {
return nil, err
}
collected := make(map[string]int64)
d.collectStatistic(collected, statistics)
c.collectStatistic(collected, statistics)
return collected, nil
}
func (d *DNSdist) collectStatistic(collected map[string]int64, statistics *statisticMetrics) {
func (c *Collector) collectStatistic(collected map[string]int64, statistics *statisticMetrics) {
for metric, value := range stm.ToMap(statistics) {
collected[metric] = value
}
}
func (d *DNSdist) scrapeStatistics() (*statisticMetrics, error) {
req, err := web.NewHTTPRequestWithPath(d.RequestConfig, urlPathJSONStat)
func (c *Collector) scrapeStatistics() (*statisticMetrics, error) {
req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathJSONStat)
if err != nil {
return nil, err
}
req.URL.RawQuery = url.Values{"command": []string{"stats"}}.Encode()
var stats statisticMetrics
if err := web.DoHTTP(d.httpClient).RequestJSON(req, &stats); err != nil {
if err := web.DoHTTP(c.httpClient).RequestJSON(req, &stats); err != nil {
return nil, err
}

Some files were not shown because too many files have changed in this diff Show more