log: open the event log lazily, bound close, keep the service running, structured messages (#2734)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-16 02:31:55 +02:00
committed by GitHub
parent a1ac462daf
commit af2a7c3f6c
19 changed files with 610 additions and 81 deletions
+37 -31
View File
@@ -179,7 +179,9 @@ func (c *Collection) collectCollector(ctx context.Context, ch chan<- prometheus.
switch state.tryCollect() {
case started:
case notAvailable:
logger.LogAttrs(ctx, slog.LevelDebug, fmt.Sprintf("collector %s skipped, because it isn't initialized", name))
logger.LogAttrs(ctx, slog.LevelDebug, "collector skipped, because it isn't initialized",
slog.String("collector", name),
)
return unavailable
case busy:
@@ -188,7 +190,9 @@ func (c *Collection) collectCollector(ctx context.Context, ch chan<- prometheus.
level = slog.LevelWarn
}
logger.LogAttrs(ctx, level, fmt.Sprintf("collector %s skipped, because its call from an earlier scrape is still running", name))
logger.LogAttrs(ctx, level, "collector skipped, because its call from an earlier scrape is still running",
slog.String("collector", name),
)
return pending
}
@@ -239,9 +243,16 @@ func (c *Collection) collectCollector(ctx context.Context, ch chan<- prometheus.
c.sendCollectorDuration(ch, name, duration)
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
logger.LogAttrs(ctx, slog.LevelWarn, fmt.Sprintf("collector %s timeouted after %s, resulting in %d metrics", name, duration, numMetrics))
logger.LogAttrs(ctx, slog.LevelWarn, "collector timed out",
slog.String("collector", name),
slog.Duration("duration", duration),
slog.Int("metrics", numMetrics),
)
} else {
logger.LogAttrs(ctx, slog.LevelDebug, fmt.Sprintf("collector %s canceled after %s, resulting in %d metrics", name, duration, numMetrics),
logger.LogAttrs(ctx, slog.LevelDebug, "collector canceled",
slog.String("collector", name),
slog.Duration("duration", duration),
slog.Int("metrics", numMetrics),
slog.Any("err", ctx.Err()),
)
}
@@ -291,36 +302,31 @@ func (c *Collection) sendCollectorDuration(ch chan<- prometheus.Metric, name str
}
func logCollectorResult(ctx context.Context, logger *slog.Logger, name string, err error, duration time.Duration, numMetrics int) collectorStatusCode {
slogAttrs := make([]slog.Attr, 0)
result := "succeeded"
if err != nil {
if !expectedCollectionError(err) {
if errors.Is(err, pdh.ErrPerformanceCounterNotInitialized) {
err = fmt.Errorf("%w. Check application logs from initialization phase for more information", err)
}
logger.LogAttrs(ctx, slog.LevelWarn,
fmt.Sprintf("collector %s failed after %s, resulting in %d metrics", name, duration, numMetrics),
slog.Any("err", err),
)
return failed
}
slogAttrs = append(slogAttrs, slog.Any("err", err))
result = "succeeded with warnings"
attrs := []slog.Attr{
slog.String("collector", name),
slog.Duration("duration", duration),
slog.Int("metrics", numMetrics),
}
logger.LogAttrs(ctx, slog.LevelDebug, fmt.Sprintf(
"collector %s %s after %s, resulting in %d metrics", name, result, duration, numMetrics,
),
slogAttrs...,
)
if err == nil {
logger.LogAttrs(ctx, slog.LevelDebug, "collector succeeded", attrs...)
return success
return success
}
if expectedCollectionError(err) {
logger.LogAttrs(ctx, slog.LevelDebug, "collector succeeded with warnings", append(attrs, slog.Any("err", err))...)
return success
}
if errors.Is(err, pdh.ErrPerformanceCounterNotInitialized) {
err = fmt.Errorf("%w. Check application logs from initialization phase for more information", err)
}
logger.LogAttrs(ctx, slog.LevelWarn, "collector failed", append(attrs, slog.Any("err", err))...)
return failed
}
// expectedCollectionError checks every cause so an expected error cannot hide an independent failure.
+1 -1
View File
@@ -175,7 +175,7 @@ func TestCollectTimedOutCollectorDoesNotOverlap(t *testing.T) {
// The first call is still running, and no second call was started.
require.Equal(t, int32(1), slow.calls.Load())
require.Equal(t, int32(1), slow.maxActive.Load())
require.Equal(t, 1, logs.warnings("timeouted"))
require.Equal(t, 1, logs.warnings("timed out"))
require.Equal(t, 1, logs.warnings("is still running"))
// After the first call returns, the next scrape starts a new one.