@cryptotaxi247 / netdata-1 / commits / 5ecedd74c

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("'", "")