improvement(go.d.plugin): add data collection status chart (#18981)
Ilya Mashchenko committed
Nov 9, 2024 at 21:43 UTC
5ecedd74c9be24a080703d486a06dd5ebfbf8998
1 file changed
+77
-45
src/go/plugin/go.d/agent/module/job.go
+77
-45
@@ -8,8 +8,6 @@ import (
8
"fmt"
9
"io"
10
"log/slog"
11
- "os"
12
- "regexp"
11
"runtime/debug"
12
"strings"
13
"sync"
@@ -34,26 +32,31 @@ func shouldObsoleteCharts() bool {
32
return obsoleteCharts
33
}
34
37
-var reSpace = regexp.MustCompile(`\s+`)
38
-
39
-var ndInternalMonitoringDisabled = os.Getenv("NETDATA_INTERNALS_MONITORING") == "NO"
40
-
41
-func newRuntimeChart(pluginName string) *Chart {
42
- // this is needed to keep the same name as we had before https://github.com/netdata/netdata/go/plugins/plugin/go.d/issues/650
43
- ctxName := pluginName
44
- if ctxName == "go.d" {
45
- ctxName = "go"
35
+func newCollectStatusChart(pluginName string) *Chart {
36
+ return &Chart{
37
+ typ: "netdata",
38
+ Title: "Data Collection Status",
39
+ Units: "status",
40
+ Fam: pluginName,
41
+ Ctx: "netdata.plugin_data_collection_status",
42
+ Priority: 144000,
43
+ Dims: Dims{
44
+ {ID: "success"},
45
+ {ID: "failed"},
46
+ },
47
}
47
- ctxName = reSpace.ReplaceAllString(ctxName, "_")
48
+}
49
+
50
+func newCollectDurationChart(pluginName string) *Chart {
51
return &Chart{
52
typ: "netdata",
50
- Title: "Execution time",
53
+ Title: "Data Collection Duration",
54
Units: "ms",
55
Fam: pluginName,
53
- Ctx: fmt.Sprintf("netdata.%s_plugin_execution_time", ctxName),
56
+ Ctx: "netdata.plugin_data_collection_duration",
57
Priority: 145000,
58
Dims: Dims{
56
- {ID: "time"},
59
+ {ID: "duration"},
60
},
61
}
62
}
@@ -93,21 +96,22 @@ func NewJob(cfg JobConfig) *Job {
96
AutoDetectEvery: cfg.AutoDetectEvery,
97
AutoDetectTries: infTries,
98
96
- pluginName: cfg.PluginName,
97
- name: cfg.Name,
98
- moduleName: cfg.ModuleName,
99
- fullName: cfg.FullName,
100
- updateEvery: cfg.UpdateEvery,
101
- priority: cfg.Priority,
102
- isStock: cfg.IsStock,
103
- module: cfg.Module,
104
- labels: cfg.Labels,
105
- out: cfg.Out,
106
- runChart: newRuntimeChart(cfg.PluginName),
107
- stop: make(chan struct{}),
108
- tick: make(chan int),
109
- buf: &buf,
110
- api: netdataapi.New(&buf),
99
+ pluginName: cfg.PluginName,
100
+ name: cfg.Name,
101
+ moduleName: cfg.ModuleName,
102
+ fullName: cfg.FullName,
103
+ updateEvery: cfg.UpdateEvery,
104
+ priority: cfg.Priority,
105
+ isStock: cfg.IsStock,
106
+ module: cfg.Module,
107
+ labels: cfg.Labels,
108
+ out: cfg.Out,
109
+ collectStatusChart: newCollectStatusChart(cfg.PluginName),
110
+ collectDurationChart: newCollectDurationChart(cfg.PluginName),
111
+ stop: make(chan struct{}),
112
+ tick: make(chan int),
113
+ buf: &buf,
114
+ api: netdataapi.New(&buf),
115
116
vnodeGUID: cfg.VnodeGUID,
117
vnodeHostname: cfg.VnodeHostname,
@@ -149,12 +153,13 @@ type Job struct {
153
initialized bool
154
panicked bool
155
152
- runChart *Chart
153
- charts *Charts
154
- tick chan int
155
- out io.Writer
156
- buf *bytes.Buffer
157
- api *netdataapi.API
156
+ collectStatusChart *Chart
157
+ collectDurationChart *Chart
158
+ charts *Charts
159
+ tick chan int
160
+ out io.Writer
161
+ buf *bytes.Buffer
162
+ api *netdataapi.API
163
164
retries int
165
prevRun time.Time
@@ -304,10 +309,15 @@ func (j *Job) Cleanup() {
309
}
310
_ = j.api.HOST(j.vnodeGUID)
311
307
- if j.runChart.created {
308
- j.runChart.MarkRemove()
309
- j.createChart(j.runChart)
312
+ if j.collectStatusChart.created {
313
+ j.collectStatusChart.MarkRemove()
314
+ j.createChart(j.collectStatusChart)
315
}
316
+ if j.collectDurationChart.created {
317
+ j.collectDurationChart.MarkRemove()
318
+ j.createChart(j.collectDurationChart)
319
+ }
320
+
321
if j.charts != nil {
322
for _, chart := range *j.charts {
323
if chart.created {
@@ -410,9 +420,14 @@ func (j *Job) processMetrics(metrics map[string]int64, startTime time.Time, sinc
420
421
_ = j.api.HOST(j.vnodeGUID)
422
413
- if !ndInternalMonitoringDisabled && !j.runChart.created {
414
- j.runChart.ID = fmt.Sprintf("execution_time_of_%s", j.FullName())
415
- j.createChart(j.runChart)
423
+ if !j.collectStatusChart.created {
424
+ j.collectStatusChart.ID = fmt.Sprintf("%s_%s_data_collection_status", cleanPluginName(j.pluginName), j.FullName())
425
+ j.createChart(j.collectStatusChart)
426
+ }
427
+
428
+ if !j.collectDurationChart.created {
429
+ j.collectDurationChart.ID = fmt.Sprintf("%s_%s_data_collection_duration", cleanPluginName(j.pluginName), j.FullName())
430
+ j.createChart(j.collectDurationChart)
431
}
432
433
elapsed := int64(durationTo(time.Since(startTime), time.Millisecond))
@@ -442,12 +457,17 @@ func (j *Job) processMetrics(metrics map[string]int64, startTime time.Time, sinc
457
}
458
*j.charts = (*j.charts)[:i]
459
460
+ j.updateChart(
461
+ j.collectStatusChart,
462
+ map[string]int64{"success": boolToInt(updated > 0), "failed": boolToInt(updated == 0)},
463
+ sinceLastRun,
464
+ )
465
+
466
if updated == 0 {
467
return false
468
}
448
- if !ndInternalMonitoringDisabled {
449
- j.updateChart(j.runChart, map[string]int64{"time": elapsed}, sinceLastRun)
450
- }
469
+
470
+ j.updateChart(j.collectDurationChart, map[string]int64{"duration": elapsed}, sinceLastRun)
471
472
return true
473
}
@@ -648,4 +668,16 @@ func handleZero(v int) int {
668
return v
669
}
670
671
+func boolToInt(b bool) int64 {
672
+ if b {
673
+ return 1
674
+ }
675
+ return 0
676
+}
677
+
678
+func cleanPluginName(name string) string {
679
+ r := strings.NewReplacer(" ", "_", ".", "_")
680
+ return r.Replace(name)
681
+}
682
+
683
var lblReplacer = strings.NewReplacer("'", "")