@cryptotaxi247 / netdata-1 / commits / 733f4fbfd

chore(go.d): log data collection duration when skipping tick (#21425)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Ilya Mashchenko committed Dec 8, 2025 at 22:09 UTC 733f4fbfd6c5bd5758c327fc9e07fc3242f73d88
1 file changed +39 -7
src/go/plugin/go.d/agent/module/job.go
+39 -7
@@ -176,7 +176,10 @@ type Job struct {
176 dumpMode bool
177 dumpAnalyzer interface{} // Will be *agent.DumpAnalyzer but avoid circular dependency
178
179 - consecutiveSkips int // tracks consecutive tick skips
179 + skipStateMu sync.Mutex
180 + consecutiveSkips int
181 + collectStartTime time.Time // when current collection started
182 + collectStopTime time.Time // when current collection finished
183 }
184
185 type collectedMetrics struct {
@@ -301,12 +304,21 @@ func (j *Job) UpdateVnode(vnode *vnodes.VirtualNode) {
304 func (j *Job) Tick(clock int) {
305 select {
306 case j.tick <- clock:
304 - j.consecutiveSkips = 0
307 default:
306 - if j.consecutiveSkips++; j.consecutiveSkips >= 2 {
307 - j.Warningf("skipping data collection: previous run is still in progress (skipped %d times in a row)", j.consecutiveSkips)
308 - } else {
309 - j.Info("skipping data collection: previous run is still in progress")
308 + if j.shouldCollect(clock) {
309 + j.skipStateMu.Lock()
310 + j.consecutiveSkips++
311 + consecutiveSkips := j.consecutiveSkips
312 + startTime := j.collectStartTime
313 + j.skipStateMu.Unlock()
314 +
315 + if startTime.IsZero() {
316 + j.Infof("skipping data collection: waiting for first collection to start (interval %ds)", j.updateEvery)
317 + } else if consecutiveSkips >= 2 {
318 + j.Warningf("skipping data collection: previous run is still in progress for %s (skipped %d times in a row, interval %ds)", time.Since(startTime), consecutiveSkips, j.updateEvery)
319 + } else {
320 + j.Infof("skipping data collection: previous run is still in progress for %s (interval %ds)", time.Since(startTime), j.updateEvery)
321 + }
322 }
323 }
324 }
@@ -322,8 +334,24 @@ LOOP:
334 case <-j.stop:
335 break LOOP
336 case t := <-j.tick:
325 - if t%(j.updateEvery+j.penalty()) == 0 {
337 + if j.shouldCollect(t) {
338 + j.skipStateMu.Lock()
339 + if j.consecutiveSkips > 0 {
340 + if j.collectStopTime.IsZero() {
341 + j.Infof("data collection resumed (skipped %d times)", j.consecutiveSkips)
342 + } else {
343 + j.Infof("data collection resumed after %s (skipped %d times)", j.collectStopTime.Sub(j.collectStartTime), j.consecutiveSkips)
344 + }
345 + j.consecutiveSkips = 0
346 + }
347 + j.collectStartTime = time.Now()
348 + j.skipStateMu.Unlock()
349 +
350 j.runOnce()
351 +
352 + j.skipStateMu.Lock()
353 + j.collectStopTime = time.Now()
354 + j.skipStateMu.Unlock()
355 }
356 }
357 }
@@ -339,6 +367,10 @@ func (j *Job) Stop() {
367 <-j.stop
368 }
369
370 +func (j *Job) shouldCollect(clock int) bool {
371 + return clock%(j.updateEvery+j.penalty()) == 0
372 +}
373 +
374 func (j *Job) disableAutoDetection() {
375 j.AutoDetectEvery = 0
376 }