collector: add stack trace, if collector panics (#1650)

This commit is contained in:
Jan-Otto Kröpke
2024-09-28 15:57:56 +02:00
committed by GitHub
parent 01e809315c
commit a1defadf1e
2 changed files with 26 additions and 6 deletions

View File

@@ -6,6 +6,7 @@ import (
"context" "context"
"fmt" "fmt"
"log/slog" "log/slog"
"runtime/debug"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -187,6 +188,7 @@ func (p *Prometheus) execute(name string, c Collector, scrapeCtx *types.ScrapeCo
if r := recover(); r != nil { if r := recover(); r != nil {
p.logger.Error("panic in collector "+name, p.logger.Error("panic in collector "+name,
slog.Any("panic", r), slog.Any("panic", r),
slog.Any("stack", string(debug.Stack())),
) )
} }
}() }()

View File

@@ -33,7 +33,8 @@ var ConfigDefaults = Config{
type Collector struct { type Collector struct {
config Config config Config
scheduledTasksCh chan *scheduledTaskResults scheduledTasksReqCh chan struct{}
scheduledTasksCh chan *scheduledTaskResults
lastResult *prometheus.Desc lastResult *prometheus.Desc
missedRuns *prometheus.Desc missedRuns *prometheus.Desc
@@ -140,15 +141,16 @@ func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
} }
func (c *Collector) Close(_ *slog.Logger) error { func (c *Collector) Close(_ *slog.Logger) error {
close(c.scheduledTasksCh) close(c.scheduledTasksReqCh)
c.scheduledTasksCh = nil c.scheduledTasksReqCh = nil
return nil return nil
} }
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error { func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
initErrCh := make(chan error) initErrCh := make(chan error)
c.scheduledTasksReqCh = make(chan struct{})
c.scheduledTasksCh = make(chan *scheduledTaskResults) c.scheduledTasksCh = make(chan *scheduledTaskResults)
go c.initializeScheduleService(initErrCh) go c.initializeScheduleService(initErrCh)
@@ -250,9 +252,21 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
} }
func (c *Collector) getScheduledTasks() ([]scheduledTask, error) { func (c *Collector) getScheduledTasks() ([]scheduledTask, error) {
c.scheduledTasksCh <- nil c.scheduledTasksReqCh <- struct{}{}
scheduledTasks := <-c.scheduledTasksCh scheduledTasks, ok := <-c.scheduledTasksCh
if !ok {
return []scheduledTask{}, nil
}
if scheduledTasks == nil {
return nil, errors.New("scheduled tasks channel is nil")
}
if scheduledTasks.err != nil {
return nil, scheduledTasks.err
}
return scheduledTasks.scheduledTasks, scheduledTasks.err return scheduledTasks.scheduledTasks, scheduledTasks.err
} }
@@ -309,7 +323,7 @@ func (c *Collector) initializeScheduleService(initErrCh chan<- error) {
scheduledTasks := make([]scheduledTask, 0, 100) scheduledTasks := make([]scheduledTask, 0, 100)
for range c.scheduledTasksCh { for range c.scheduledTasksReqCh {
func() { func() {
// Clear the slice to avoid memory leaks // Clear the slice to avoid memory leaks
clear(scheduledTasks) clear(scheduledTasks)
@@ -330,6 +344,10 @@ func (c *Collector) initializeScheduleService(initErrCh chan<- error) {
c.scheduledTasksCh <- &scheduledTaskResults{scheduledTasks: scheduledTasks, err: err} c.scheduledTasksCh <- &scheduledTaskResults{scheduledTasks: scheduledTasks, err: err}
}() }()
} }
close(c.scheduledTasksCh)
c.scheduledTasksCh = nil
} }
func fetchTasksRecursively(folder *ole.IDispatch, scheduledTasks *[]scheduledTask) error { func fetchTasksRecursively(folder *ole.IDispatch, scheduledTasks *[]scheduledTask) error {