fix: add missing concurrency lock (#2098)

This commit is contained in:
Jan-Otto Kröpke
2025-07-04 11:14:49 +02:00
committed by GitHub
parent 7377d48f07
commit c3043693df
3 changed files with 23 additions and 7 deletions

View File

@@ -143,7 +143,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
}, },
} }
c.queryAllServicesBuffer = make([]byte, 1024*100) c.queryAllServicesBuffer = make([]byte, 1024*200)
c.info = prometheus.NewDesc( c.info = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "info"), prometheus.BuildFQName(types.Namespace, Name, "info"),
@@ -242,6 +242,15 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
} }
func (c *Collector) collectWorker(ch chan<- prometheus.Metric, service windows.ENUM_SERVICE_STATUS_PROCESS) { func (c *Collector) collectWorker(ch chan<- prometheus.Metric, service windows.ENUM_SERVICE_STATUS_PROCESS) {
if uintptr(unsafe.Pointer(service.ServiceName)) == uintptr(windows.InvalidHandle) {
c.logger.Log(context.Background(), slog.LevelWarn, "failed collecting service info",
slog.String("err", "ServiceName is 0xffffffffffffffff"),
slog.String("service", fmt.Sprintf("%+v", service)),
)
return
}
serviceName := windows.UTF16PtrToString(service.ServiceName) serviceName := windows.UTF16PtrToString(service.ServiceName)
if c.config.ServiceExclude.MatchString(serviceName) || !c.config.ServiceInclude.MatchString(serviceName) { if c.config.ServiceExclude.MatchString(serviceName) || !c.config.ServiceInclude.MatchString(serviceName) {
@@ -375,6 +384,8 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e
err error err error
) )
clear(c.queryAllServicesBuffer)
for { for {
currentBufferSize := uint32(cap(c.queryAllServicesBuffer)) currentBufferSize := uint32(cap(c.queryAllServicesBuffer))

View File

@@ -44,7 +44,6 @@ type MetricsHTTPHandler struct {
logger *slog.Logger logger *slog.Logger
options Options options Options
concurrencyCh chan struct{}
} }
type Options struct { type Options struct {
@@ -64,9 +63,6 @@ func New(logger *slog.Logger, metricCollectors *collector.Collection, options *O
metricCollectors: metricCollectors, metricCollectors: metricCollectors,
logger: logger, logger: logger,
options: *options, options: *options,
// We are expose metrics directly from the memory region of the Win32 API. We should not allow more than one request at a time.
concurrencyCh: make(chan struct{}, 1),
} }
if !options.DisableExporterMetrics { if !options.DisableExporterMetrics {

View File

@@ -20,6 +20,7 @@ package collector
import ( import (
"fmt" "fmt"
"log/slog" "log/slog"
"sync"
"time" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -28,6 +29,12 @@ import (
// Interface guard. // Interface guard.
var _ prometheus.Collector = (*Handler)(nil) var _ prometheus.Collector = (*Handler)(nil)
// We are expose metrics directly from the memory region of the Win32 API.
// We should not allow more than one request at a time.
//
//nolint:gochecknoglobals
var concurrencyMu sync.Mutex
// Handler implements [prometheus.Collector] for a set of Windows Collection. // Handler implements [prometheus.Collector] for a set of Windows Collection.
type Handler struct { type Handler struct {
maxScrapeDuration time.Duration maxScrapeDuration time.Duration
@@ -60,5 +67,7 @@ func (p *Handler) Describe(_ chan<- *prometheus.Desc) {}
// Collect sends the collected metrics from each of the Collection to // Collect sends the collected metrics from each of the Collection to
// prometheus. // prometheus.
func (p *Handler) Collect(ch chan<- prometheus.Metric) { func (p *Handler) Collect(ch chan<- prometheus.Metric) {
concurrencyMu.Lock()
p.collection.collectAll(ch, p.logger, p.maxScrapeDuration) p.collection.collectAll(ch, p.logger, p.maxScrapeDuration)
concurrencyMu.Unlock()
} }