From da15dacc462e8fc5b52d9dd7dfdc224480ad9825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 8 Dec 2024 20:07:40 +0100 Subject: [PATCH 1/8] support yaml documents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- internal/collector/performancecounter/performancecounter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index aed4b0c22..cb4f68091 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -16,7 +16,6 @@ package performancecounter import ( - "encoding/json" "fmt" "log/slog" "strings" @@ -26,6 +25,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus/client_golang/prometheus" + "gopkg.in/yaml.v3" ) const Name = "performancecounter" @@ -79,7 +79,7 @@ func NewWithFlags(app *kingpin.Application) *Collector { return nil } - if err := json.Unmarshal([]byte(objects), &c.config.Objects); err != nil { + if err := yaml.Unmarshal([]byte(objects), &c.config.Objects); err != nil { return fmt.Errorf("failed to parse objects: %w", err) } From 93ccd2322cdcf1bffbb12635e2210b9565663e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 8 Dec 2024 20:39:41 +0100 Subject: [PATCH 2/8] add err MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- internal/collector/mssql/mssql.go | 2 +- .../performancecounter/performancecounter.go | 179 ++++++++++++------ .../collector/performancecounter/types.go | 1 + pkg/collector/collect.go | 2 +- pkg/collector/map.go | 3 + 5 files changed, 131 insertions(+), 56 deletions(-) diff --git a/internal/collector/mssql/mssql.go b/internal/collector/mssql/mssql.go index db87764db..6d851b356 100644 --- a/internal/collector/mssql/mssql.go +++ b/internal/collector/mssql/mssql.go @@ -387,7 +387,7 @@ func (c *Collector) collect( slog.Any("err", err), ) } else { - c.logger.Debug(fmt.Sprintf("mssql class collector %s for instance %s succeeded after %s.", collector, sqlInstance, duration)) + c.logger.Debug(fmt.Sprintf("mssql class collector %s for instance %s succeeded after %s", collector, sqlInstance, duration)) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index cb4f68091..7882f5229 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -16,9 +16,11 @@ package performancecounter import ( + "errors" "fmt" "log/slog" "strings" + "time" "github.com/alecthomas/kingpin/v2" "github.com/prometheus-community/windows_exporter/internal/mi" @@ -44,6 +46,12 @@ type Collector struct { config Config logger *slog.Logger + + metricNameReplacer *strings.Replacer + + // meta + subCollectorScrapeDurationDesc *prometheus.Desc + subCollectorScrapeSuccessDesc *prometheus.Desc } func New(config *Config) *Collector { @@ -104,19 +112,29 @@ func (c *Collector) Close() error { func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { c.logger = logger.With(slog.String("collector", Name)) + var errs []error + for i, object := range c.config.Objects { + if object.Name == "" { + return fmt.Errorf("object name is required") + } + counters := make([]string, 0, len(object.Counters)) for j, counter := range object.Counters { counters = append(counters, counter.Name) if counter.Metric == "" { - c.config.Objects[i].Counters[j].Metric = sanitizeMetricName(fmt.Sprintf("%s_%s_%s_%s", types.Namespace, Name, object.Object, counter.Name)) + c.config.Objects[i].Counters[j].Metric = c.sanitizeMetricName( + fmt.Sprintf("%s_%s_%s_%s", types.Namespace, Name, object.Object, counter.Name), + ) } } collector, err := perfdata.NewCollector(object.Object, object.Instances, counters) if err != nil { - return fmt.Errorf("failed to create v2 collector: %w", err) + errs = append(errs, fmt.Errorf("failed collector for %s: %w", object.Name, err)) + + continue } if object.InstanceLabel == "" { @@ -126,85 +144,138 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { c.config.Objects[i].collector = collector } - return nil + c.metricNameReplacer = strings.NewReplacer( + ".", "", + "%", "", + "/", "_", + " ", "_", + "-", "_", + ) + + c.subCollectorScrapeDurationDesc = prometheus.NewDesc( + prometheus.BuildFQName(types.Namespace, Name, "collector_duration_seconds"), + "windows_exporter: Duration of an performancecounter child collection.", + []string{"collector"}, + nil, + ) + c.subCollectorScrapeSuccessDesc = prometheus.NewDesc( + prometheus.BuildFQName(types.Namespace, Name, "collector_success"), + "windows_exporter: Whether a performancecounter child collector was successful.", + []string{"collector"}, + nil, + ) + + return errors.Join() } // Collect sends the metric values for each metric // to the provided prometheus Metric channel. func (c *Collector) Collect(ch chan<- prometheus.Metric) error { + errs := make([]error, 0, len(c.config.Objects)) + for _, perfDataObject := range c.config.Objects { - collectedPerfData, err := perfDataObject.collector.Collect() + startTime := time.Now() + err := c.collectObject(ch, perfDataObject) + duration := time.Since(startTime) + success := 1.0 + if err != nil { - return fmt.Errorf("failed to collect data: %w", err) + errs = append(errs, fmt.Errorf("failed to collect object %s: %w", perfDataObject.Name, err)) + success = 0.0 + + c.logger.Debug(fmt.Sprintf("performancecounter collector %s failed after %s", perfDataObject.Name, duration), + slog.Any("err", err), + ) + } else { + c.logger.Debug(fmt.Sprintf("performancecounter collector %s succeeded after %s", perfDataObject.Name, duration)) } - for collectedInstance, collectedInstanceCounters := range collectedPerfData { - for _, counter := range perfDataObject.Counters { - collectedCounterValue, ok := collectedInstanceCounters[counter.Name] - if !ok { - c.logger.Warn(fmt.Sprintf("counter %s not found in collected data", counter.Name)) + ch <- prometheus.MustNewConstMetric( + c.subCollectorScrapeSuccessDesc, + prometheus.GaugeValue, + success, + perfDataObject.Name, + ) + + ch <- prometheus.MustNewConstMetric( + c.subCollectorScrapeDurationDesc, + prometheus.GaugeValue, + duration.Seconds(), + perfDataObject.Name, + ) + } + + return nil +} - continue - } +func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Object) error { + collectedPerfData, err := perfDataObject.collector.Collect() + if err != nil { + return fmt.Errorf("failed to collect data: %w", err) + } - labels := make(prometheus.Labels, len(counter.Labels)+1) - if collectedInstance != perfdata.InstanceEmpty { - labels[perfDataObject.InstanceLabel] = collectedInstance - } + var errs []error - for key, value := range counter.Labels { - labels[key] = value - } + for collectedInstance, collectedInstanceCounters := range collectedPerfData { + for _, counter := range perfDataObject.Counters { + collectedCounterValue, ok := collectedInstanceCounters[counter.Name] + if !ok { + errs = append(errs, fmt.Errorf("counter %s not found in collected data", counter.Name)) - var metricType prometheus.ValueType + continue + } - switch counter.Type { - case "counter": - metricType = prometheus.CounterValue - case "gauge": - metricType = prometheus.GaugeValue - default: - metricType = collectedCounterValue.Type - } + labels := make(prometheus.Labels, len(counter.Labels)+2) + labels["collector"] = perfDataObject.Name + if collectedInstance != perfdata.InstanceEmpty { + labels[perfDataObject.InstanceLabel] = collectedInstance + } + + for key, value := range counter.Labels { + labels[key] = value + } + + var metricType prometheus.ValueType + + switch counter.Type { + case "counter": + metricType = prometheus.CounterValue + case "gauge": + metricType = prometheus.GaugeValue + default: + metricType = collectedCounterValue.Type + } + + ch <- prometheus.MustNewConstMetric( + prometheus.NewDesc( + counter.Metric, + "windows_exporter: custom Performance Counter metric", + nil, + labels, + ), + metricType, + collectedCounterValue.FirstValue, + ) + + if collectedCounterValue.SecondValue != 0 { ch <- prometheus.MustNewConstMetric( prometheus.NewDesc( - counter.Metric, + counter.Metric+"_second", "windows_exporter: custom Performance Counter metric", nil, labels, ), metricType, - collectedCounterValue.FirstValue, + collectedCounterValue.SecondValue, ) - - if collectedCounterValue.SecondValue != 0 { - ch <- prometheus.MustNewConstMetric( - prometheus.NewDesc( - counter.Metric+"_second", - "windows_exporter: custom Performance Counter metric", - nil, - labels, - ), - metricType, - collectedCounterValue.SecondValue, - ) - } } } } - return nil + return errors.Join() } -func sanitizeMetricName(name string) string { - replacer := strings.NewReplacer( - ".", "", - "%", "", - "/", "_", - " ", "_", - "-", "_", - ) - - return strings.Trim(replacer.Replace(strings.ToLower(name)), "_") +func (c *Collector) sanitizeMetricName(name string) string { + return strings.Trim(c.metricNameReplacer.Replace(strings.ToLower(name)), "_") } diff --git a/internal/collector/performancecounter/types.go b/internal/collector/performancecounter/types.go index 3fe91c0a3..efe8c12ff 100644 --- a/internal/collector/performancecounter/types.go +++ b/internal/collector/performancecounter/types.go @@ -18,6 +18,7 @@ package performancecounter import "github.com/prometheus-community/windows_exporter/internal/perfdata" type Object struct { + Name string `json:"name" yaml:"name"` Object string `json:"object" yaml:"object"` Instances []string `json:"instances" yaml:"instances"` Counters []Counter `json:"counters" yaml:"counters"` diff --git a/pkg/collector/collect.go b/pkg/collector/collect.go index c684dc691..a2b580236 100644 --- a/pkg/collector/collect.go +++ b/pkg/collector/collect.go @@ -207,7 +207,7 @@ func (c *Collection) collectCollector(ch chan<- prometheus.Metric, logger *slog. if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, types.ErrNoData) { loggerFn := logger.Warn if errors.Is(err, perfdata.ErrPerformanceCounterNotInitialized) || errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) { - loggerFn = logger.Debug + err = fmt.Errorf("%w. Check application logs from initialization pharse for more information", err) } loggerFn(fmt.Sprintf("collector %s failed after %s, resulting in %d metrics", name, duration, numMetrics), diff --git a/pkg/collector/map.go b/pkg/collector/map.go index ec45e7751..957aebfe9 100644 --- a/pkg/collector/map.go +++ b/pkg/collector/map.go @@ -128,6 +128,9 @@ var BuildersWithFlags = map[string]BuilderWithFlags[Collector]{ vmware.Name: NewBuilderWithFlags(vmware.NewWithFlags), } +// Available returns a sorted list of available collectors. +// +//goland:noinspection GoUnusedExportedFunction func Available() []string { return slices.Sorted(maps.Keys(BuildersWithFlags)) } From d99d6b9bf7e3392f3cf9396928c002f065055ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sun, 8 Dec 2024 23:43:51 +0100 Subject: [PATCH 3/8] add more stricter checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- docs/collector.performancecounter.md | 47 +++++++++++++++++-- .../performancecounter/performancecounter.go | 30 +++++++++++- .../performancecounter_test_test.go | 23 +++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/docs/collector.performancecounter.md b/docs/collector.performancecounter.md index 778b6f0bd..16c906f02 100644 --- a/docs/collector.performancecounter.md +++ b/docs/collector.performancecounter.md @@ -13,9 +13,28 @@ The performancecounter collector exposes any configured metric. ### `--collector.performancecounter.objects` -Objects is a list of objects to collect metrics from. The value takes the form of a JSON array of strings. YAML is also supported. +Objects is a list of objects to collect metrics from. The value takes the form of a JSON array of strings. +YAML is supported. -The collector supports only english named counter. Localized counter-names are not supported. +The collector supports only English-named counter. Localized counter-names aren’t supported. + +> [!CAUTION] +> If you are using a configuration file, the value must be kept as a string. +> +> Use a `|-` to keep the value as a string. + +#### Example + +```yaml +collector: + performancecounter: + objects: |- + - name: memory + object: "Memory" + counters: + - name: "Cache Faults/sec" + type: "counter" # optional +``` #### Schema @@ -25,7 +44,8 @@ YAML: Click to expand YAML schema ```yaml -- object: "Processor Information" +- name: cpu # free text name + object: "Processor Information" # Performance counter object name instances: ["*"] instance_label: "core" counters: @@ -37,7 +57,8 @@ YAML: metric: windows_performancecounter_processor_information_processor_time # optional labels: state: idle -- object: "Memory" +- name: memory + object: "Memory" counters: - name: "Cache Faults/sec" type: "counter" # optional @@ -51,6 +72,7 @@ YAML: ```json [ { + "name": "cpu", "object": "Processor Information", "instances": [ "*" @@ -74,6 +96,7 @@ YAML: ] }, { + "name": "memory", "object": "Memory", "counters": [ { @@ -86,6 +109,11 @@ YAML: ``` +#### name + +The name is used to identify the object in the logs and metrics. +Must unique across all objects. + #### object ObjectName is the Object to query for, like Processor, DirectoryServices, LogicalDisk or similar. @@ -186,6 +214,17 @@ windows_performancecounter_processor_information_processor_time{core="0,8",state windows_performancecounter_processor_information_processor_time{core="0,9",state="active"} 1.0059484375e+11 windows_performancecounter_processor_information_processor_time{core="0,9",state="idle"} 10059.484375 ``` +> [!NOTE] +> If you are using a configuration file, the value must be keep as string. + +Example: + +```yaml +collector: + performancecounter: + objects: | +``` + ## Metrics diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index 7882f5229..26a593d21 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "log/slog" + "slices" "strings" "time" @@ -112,15 +113,42 @@ func (c *Collector) Close() error { func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { c.logger = logger.With(slog.String("collector", Name)) - var errs []error + names := make([]string, 0, len(c.config.Objects)) + errs := make([]error, 0, len(c.config.Objects)) for i, object := range c.config.Objects { if object.Name == "" { return fmt.Errorf("object name is required") } + if object.Object == "" { + errs = append(errs, fmt.Errorf("object %s: object is required", object.Name)) + + continue + } + + if slices.Contains(names, object.Name) { + errs = append(errs, fmt.Errorf("object %s: name is duplicated", object.Name)) + + continue + } + + names = append(names, object.Name) + counters := make([]string, 0, len(object.Counters)) for j, counter := range object.Counters { + if counter.Name == "" { + errs = append(errs, errors.New("counter name is required")) + + continue + } + + if slices.Contains(counters, counter.Name) { + errs = append(errs, fmt.Errorf("counter name %s is duplicated", counter.Name)) + + continue + } + counters = append(counters, counter.Name) if counter.Metric == "" { diff --git a/internal/collector/performancecounter/performancecounter_test_test.go b/internal/collector/performancecounter/performancecounter_test_test.go index 6424156d3..c63371c07 100644 --- a/internal/collector/performancecounter/performancecounter_test_test.go +++ b/internal/collector/performancecounter/performancecounter_test_test.go @@ -49,31 +49,48 @@ func TestCollector(t *testing.T) { t.Parallel() for _, tc := range []struct { + name string object string instances []string instanceLabel string + buildErr error counters []performancecounter.Counter expectedMetrics *regexp.Regexp }{ { + name: "memory", object: "Memory", instances: nil, + buildErr: nil, counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}}, expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_memory_available_bytes windows_exporter: custom Performance Counter metric\S*\s*# TYPE windows_performancecounter_memory_available_bytes gauge\s*windows_performancecounter_memory_available_bytes \d`), }, { + name: "process", object: "Process", instances: []string{"*"}, + buildErr: nil, counters: []performancecounter.Counter{{Name: "Thread Count", Type: "counter"}}, expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_process_thread_count windows_exporter: custom Performance Counter metric\S*\s*# TYPE windows_performancecounter_process_thread_count counter\s*windows_performancecounter_process_thread_count\{instance=".+"} \d`), }, { + name: "processor_information", object: "Processor Information", instances: []string{"*"}, instanceLabel: "core", + buildErr: nil, counters: []performancecounter.Counter{{Name: "% Processor Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "active"}}, {Name: "% Idle Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "idle"}}}, expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_processor_information_processor_time windows_exporter: custom Performance Counter metric\s+# TYPE windows_performancecounter_processor_information_processor_time counter\s+windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9.e+]+\s+windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9.e+]+`), }, + { + name: "", + object: "Processor Information", + instances: nil, + instanceLabel: "", + buildErr: fmt.Errorf("object name is empty"), + counters: nil, + expectedMetrics: nil, + }, } { t.Run(tc.object, func(t *testing.T) { t.Parallel() @@ -91,6 +108,12 @@ func TestCollector(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, nil)) err := perfDataCollector.Build(logger, nil) + if tc.buildErr != nil { + require.ErrorIs(t, err, tc.buildErr) + + return + } + require.NoError(t, err) registry := prometheus.NewRegistry() From c465d0fc4b0af676572af384c4fd83602b39c9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 9 Dec 2024 01:09:20 +0100 Subject: [PATCH 4/8] process: fix metric labels for multiple process instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- config.yaml | 9 +- .../performancecounter/performancecounter.go | 47 +++++----- .../performancecounter_test_test.go | 85 +++++++++++++------ 3 files changed, 95 insertions(+), 46 deletions(-) diff --git a/config.yaml b/config.yaml index 07222f730..d26e5f893 100644 --- a/config.yaml +++ b/config.yaml @@ -1,9 +1,16 @@ # example configuration file for windows_exporter collectors: - enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,process,remote_fx,service,system,tcp,time,terminal_services,textfile + enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,performancecounter,process,remote_fx,service,system,tcp,time,terminal_services,textfile collector: service: include: "windows_exporter" + performancecounter: + objects: |- + - name: memory + object: "Memory" + counters: + - name: "Cache Faults/sec" + type: "counter" # optional log: level: warn diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index 26a593d21..1095f737f 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -48,6 +48,8 @@ type Collector struct { logger *slog.Logger + objects []Object + metricNameReplacer *strings.Replacer // meta @@ -113,6 +115,15 @@ func (c *Collector) Close() error { func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { c.logger = logger.With(slog.String("collector", Name)) + c.metricNameReplacer = strings.NewReplacer( + ".", "", + "%", "", + "/", "_", + " ", "_", + "-", "_", + ) + + c.objects = make([]Object, 0, len(c.config.Objects)) names := make([]string, 0, len(c.config.Objects)) errs := make([]error, 0, len(c.config.Objects)) @@ -137,8 +148,15 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { counters := make([]string, 0, len(object.Counters)) for j, counter := range object.Counters { + if counter.Metric == "" { + c.config.Objects[i].Counters[j].Metric = c.sanitizeMetricName( + fmt.Sprintf("%s_%s_%s_%s", types.Namespace, Name, object.Object, counter.Name), + ) + } + if counter.Name == "" { errs = append(errs, errors.New("counter name is required")) + c.config.Objects = slices.Delete(c.config.Objects, i, 1) continue } @@ -150,12 +168,6 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { } counters = append(counters, counter.Name) - - if counter.Metric == "" { - c.config.Objects[i].Counters[j].Metric = c.sanitizeMetricName( - fmt.Sprintf("%s_%s_%s_%s", types.Namespace, Name, object.Object, counter.Name), - ) - } } collector, err := perfdata.NewCollector(object.Object, object.Instances, counters) @@ -166,19 +178,13 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { } if object.InstanceLabel == "" { - c.config.Objects[i].InstanceLabel = "instance" + object.InstanceLabel = "instance" } - c.config.Objects[i].collector = collector - } + object.collector = collector - c.metricNameReplacer = strings.NewReplacer( - ".", "", - "%", "", - "/", "_", - " ", "_", - "-", "_", - ) + c.objects = append(c.objects, object) + } c.subCollectorScrapeDurationDesc = prometheus.NewDesc( prometheus.BuildFQName(types.Namespace, Name, "collector_duration_seconds"), @@ -193,15 +199,15 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { nil, ) - return errors.Join() + return errors.Join(errs...) } // Collect sends the metric values for each metric // to the provided prometheus Metric channel. func (c *Collector) Collect(ch chan<- prometheus.Metric) error { - errs := make([]error, 0, len(c.config.Objects)) + errs := make([]error, 0, len(c.objects)) - for _, perfDataObject := range c.config.Objects { + for _, perfDataObject := range c.objects { startTime := time.Now() err := c.collectObject(ch, perfDataObject) duration := time.Since(startTime) @@ -253,8 +259,7 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob continue } - labels := make(prometheus.Labels, len(counter.Labels)+2) - labels["collector"] = perfDataObject.Name + labels := make(prometheus.Labels, len(counter.Labels)+1) if collectedInstance != perfdata.InstanceEmpty { labels[perfDataObject.InstanceLabel] = collectedInstance diff --git a/internal/collector/performancecounter/performancecounter_test_test.go b/internal/collector/performancecounter/performancecounter_test_test.go index c63371c07..c83d57793 100644 --- a/internal/collector/performancecounter/performancecounter_test_test.go +++ b/internal/collector/performancecounter/performancecounter_test_test.go @@ -53,51 +53,87 @@ func TestCollector(t *testing.T) { object string instances []string instanceLabel string - buildErr error + buildErr string counters []performancecounter.Counter expectedMetrics *regexp.Regexp }{ { - name: "memory", - object: "Memory", - instances: nil, - buildErr: nil, - counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}}, - expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_memory_available_bytes windows_exporter: custom Performance Counter metric\S*\s*# TYPE windows_performancecounter_memory_available_bytes gauge\s*windows_performancecounter_memory_available_bytes \d`), + name: "memory", + object: "Memory", + instances: nil, + buildErr: "", + counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}}, + expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection. +# TYPE windows_performancecounter_collector_duration_seconds gauge +windows_performancecounter_collector_duration_seconds\{collector="memory"} [0-9.e+-]+ +# HELP windows_performancecounter_collector_success windows_exporter: Whether a performancecounter child collector was successful. +# TYPE windows_performancecounter_collector_success gauge +windows_performancecounter_collector_success\{collector="memory"} 1 +# HELP windows_performancecounter_memory_available_bytes windows_exporter: custom Performance Counter metric +# TYPE windows_performancecounter_memory_available_bytes gauge +windows_performancecounter_memory_available_bytes [0-9.e+-]+`), }, { - name: "process", - object: "Process", - instances: []string{"*"}, - buildErr: nil, - counters: []performancecounter.Counter{{Name: "Thread Count", Type: "counter"}}, - expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_process_thread_count windows_exporter: custom Performance Counter metric\S*\s*# TYPE windows_performancecounter_process_thread_count counter\s*windows_performancecounter_process_thread_count\{instance=".+"} \d`), + name: "process", + object: "Process", + instances: []string{"*"}, + buildErr: "", + counters: []performancecounter.Counter{{Name: "Thread Count", Type: "counter"}}, + expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection. +# TYPE windows_performancecounter_collector_duration_seconds gauge +windows_performancecounter_collector_duration_seconds\{collector="process"} [0-9.e+-]+ +# HELP windows_performancecounter_collector_success windows_exporter: Whether a performancecounter child collector was successful. +# TYPE windows_performancecounter_collector_success gauge +windows_performancecounter_collector_success\{collector="process"} 1 +# HELP windows_performancecounter_process_thread_count windows_exporter: custom Performance Counter metric +# TYPE windows_performancecounter_process_thread_count counter +windows_performancecounter_process_thread_count\{instance=".+"} [0-9.e+-]+ +.*`), }, { - name: "processor_information", - object: "Processor Information", - instances: []string{"*"}, - instanceLabel: "core", - buildErr: nil, - counters: []performancecounter.Counter{{Name: "% Processor Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "active"}}, {Name: "% Idle Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "idle"}}}, - expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_processor_information_processor_time windows_exporter: custom Performance Counter metric\s+# TYPE windows_performancecounter_processor_information_processor_time counter\s+windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9.e+]+\s+windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9.e+]+`), + name: "processor_information", + object: "Processor Information", + instances: []string{"*"}, + instanceLabel: "core", + buildErr: "", + counters: []performancecounter.Counter{{Name: "% Processor Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "active"}}, {Name: "% Idle Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "idle"}}}, + expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection. +# TYPE windows_performancecounter_collector_duration_seconds gauge +windows_performancecounter_collector_duration_seconds\{collector="processor_information"} [0-9.e+-]+ +# HELP windows_performancecounter_collector_success windows_exporter: Whether a performancecounter child collector was successful. +# TYPE windows_performancecounter_collector_success gauge +windows_performancecounter_collector_success\{collector="processor_information"} 1 +# HELP windows_performancecounter_processor_information_processor_time windows_exporter: custom Performance Counter metric +# TYPE windows_performancecounter_processor_information_processor_time counter +windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9.e+-]+ +windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9.e+-]+ +.*`), }, { name: "", object: "Processor Information", instances: nil, instanceLabel: "", - buildErr: fmt.Errorf("object name is empty"), + buildErr: "object name is required", counters: nil, expectedMetrics: nil, }, + { + name: "double_counter", + object: "Memory", + instances: nil, + buildErr: "counter name Available Bytes is duplicated", + counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}, {Name: "Available Bytes", Type: "gauge"}}, + expectedMetrics: nil, + }, } { - t.Run(tc.object, func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { t.Parallel() perfDataCollector := performancecounter.New(&performancecounter.Config{ Objects: []performancecounter.Object{ { + Name: tc.name, Object: tc.object, Instances: tc.instances, InstanceLabel: tc.instanceLabel, @@ -108,8 +144,8 @@ func TestCollector(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, nil)) err := perfDataCollector.Build(logger, nil) - if tc.buildErr != nil { - require.ErrorIs(t, err, tc.buildErr) + if tc.buildErr != "" { + require.ErrorContains(t, err, tc.buildErr) return } @@ -124,6 +160,7 @@ func TestCollector(t *testing.T) { got := rw.Body.String() assert.NotEmpty(t, got) + require.NotEmpty(t, tc.expectedMetrics) assert.Regexp(t, tc.expectedMetrics, got) }) } From 456277d62ac912592d249d4c3fed9acd7cd2f844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 9 Dec 2024 08:36:04 +0100 Subject: [PATCH 5/8] process: fix metric labels for multiple process instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- internal/collector/performancecounter/performancecounter.go | 6 +++--- .../performancecounter/performancecounter_test_test.go | 1 + internal/collector/performancecounter/types.go | 2 +- pkg/collector/collect.go | 1 + tools/end-to-end-test.ps1 | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index 1095f737f..0527e0cfc 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -129,7 +129,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { for i, object := range c.config.Objects { if object.Name == "" { - return fmt.Errorf("object name is required") + return errors.New("object name is required") } if object.Object == "" { @@ -145,8 +145,8 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { } names = append(names, object.Name) - counters := make([]string, 0, len(object.Counters)) + for j, counter := range object.Counters { if counter.Metric == "" { c.config.Objects[i].Counters[j].Metric = c.sanitizeMetricName( @@ -239,7 +239,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { ) } - return nil + return errors.Join(errs...) } func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Object) error { diff --git a/internal/collector/performancecounter/performancecounter_test_test.go b/internal/collector/performancecounter/performancecounter_test_test.go index c83d57793..6d482c4bb 100644 --- a/internal/collector/performancecounter/performancecounter_test_test.go +++ b/internal/collector/performancecounter/performancecounter_test_test.go @@ -144,6 +144,7 @@ windows_performancecounter_processor_information_processor_time\{core="0,0",stat logger := slog.New(slog.NewTextHandler(io.Discard, nil)) err := perfDataCollector.Build(logger, nil) + if tc.buildErr != "" { require.ErrorContains(t, err, tc.buildErr) diff --git a/internal/collector/performancecounter/types.go b/internal/collector/performancecounter/types.go index efe8c12ff..a01d56918 100644 --- a/internal/collector/performancecounter/types.go +++ b/internal/collector/performancecounter/types.go @@ -18,7 +18,7 @@ package performancecounter import "github.com/prometheus-community/windows_exporter/internal/perfdata" type Object struct { - Name string `json:"name" yaml:"name"` + Name string `json:"name" yaml:"name"` Object string `json:"object" yaml:"object"` Instances []string `json:"instances" yaml:"instances"` Counters []Counter `json:"counters" yaml:"counters"` diff --git a/pkg/collector/collect.go b/pkg/collector/collect.go index a2b580236..233bd27a7 100644 --- a/pkg/collector/collect.go +++ b/pkg/collector/collect.go @@ -206,6 +206,7 @@ func (c *Collection) collectCollector(ch chan<- prometheus.Metric, logger *slog. if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, types.ErrNoData) { loggerFn := logger.Warn + if errors.Is(err, perfdata.ErrPerformanceCounterNotInitialized) || errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) { err = fmt.Errorf("%w. Check application logs from initialization pharse for more information", err) } diff --git a/tools/end-to-end-test.ps1 b/tools/end-to-end-test.ps1 index 85e5bc9cb..49de5b5a8 100644 --- a/tools/end-to-end-test.ps1 +++ b/tools/end-to-end-test.ps1 @@ -26,7 +26,7 @@ $exporter_proc = Start-Process ` -PassThru ` -FilePath ..\windows_exporter.exe ` -ArgumentList "--log.level=debug","--web.disable-exporter-metrics","--collectors.enabled=[defaults],cpu_info,textfile,process,pagefile,performancecounter,scheduled_task,tcp,udp,time,system,service,logical_disk,printer,os,net,memory,logon,cache","--collector.process.include=explorer.exe","--collector.scheduled_task.include=.*GAEvents","--collector.service.include=Themes","--collector.textfile.directories=$($textfile_dir)",@" ---collector.performancecounter.objects="[{\"object\":\"Processor Information\",\"instances\":[\"*\"],\"instance_label\":\"core\",\"counters\":[{\"name\":\"% Processor Time\",\"metric\":\"windows_performancecounter_processor_information_processor_time\",\"labels\":{\"state\":\"active\"}},{\"name\":\"% Idle Time\",\"metric\":\"windows_performancecounter_processor_information_processor_time\",\"labels\":{\"state\":\"idle\"}}]},{\"object\":\"Memory\",\"counters\":[{\"name\":\"Cache Faults/sec\",\"type\":\"counter\"}]}]" +--collector.performancecounter.objects="[{\"name\":\"cpu\",\"object\":\"Processor Information\",\"instances\":[\"*\"],\"instance_label\":\"core\",\"counters\":[{\"name\":\"% Processor Time\",\"metric\":\"windows_performancecounter_processor_information_processor_time\",\"labels\":{\"state\":\"active\"}},{\"name\":\"% Idle Time\",\"metric\":\"windows_performancecounter_processor_information_processor_time\",\"labels\":{\"state\":\"idle\"}}]},{\"name\":\"memory\",\"object\":\"Memory\",\"counters\":[{\"name\":\"Cache Faults/sec\",\"type\":\"counter\"}]}]" "@ ` -WindowStyle Hidden ` -RedirectStandardOutput "$($temp_dir)/windows_exporter.log" ` From a1f5a5d6fbe8465cb810a12e130cf794da738ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 9 Dec 2024 09:12:46 +0100 Subject: [PATCH 6/8] process: fix metric labels for multiple process instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- cmd/windows_exporter/main.go | 17 +++++++++++--- internal/collector/ad/ad.go | 3 ++- internal/collector/adcs/adcs.go | 3 ++- internal/collector/adfs/adfs.go | 5 +++-- internal/collector/cache/cache.go | 3 ++- internal/collector/dfsr/dfsr.go | 7 +++--- internal/collector/dhcp/dhcp.go | 3 ++- internal/collector/dns/dns.go | 3 ++- .../exchange/exchange_active_sync.go | 3 ++- .../exchange/exchange_ad_access_processes.go | 3 ++- .../exchange/exchange_autodiscover.go | 3 ++- .../exchange/exchange_availability_service.go | 3 ++- .../collector/exchange/exchange_http_proxy.go | 3 ++- .../exchange/exchange_mapi_http_emsmdb.go | 3 ++- .../exchange/exchange_outlook_web_access.go | 3 ++- .../exchange/exchange_rpc_client_access.go | 3 ++- .../exchange/exchange_transport_queues.go | 3 ++- .../exchange/exchange_workload_management.go | 3 ++- internal/collector/memory/memory.go | 3 ++- .../collector/mssql/mssql_access_methods.go | 3 ++- .../mssql/mssql_availability_replica.go | 3 ++- .../collector/mssql/mssql_buffer_manager.go | 3 ++- internal/collector/mssql/mssql_database.go | 3 ++- .../collector/mssql/mssql_database_replica.go | 3 ++- .../mssql/mssql_general_statistics.go | 3 ++- internal/collector/mssql/mssql_locks.go | 3 ++- .../collector/mssql/mssql_memory_manager.go | 3 ++- internal/collector/mssql/mssql_sql_errors.go | 3 ++- internal/collector/mssql/mssql_sql_stats.go | 3 ++- .../collector/mssql/mssql_transactions.go | 3 ++- internal/collector/mssql/mssql_wait_stats.go | 3 ++- internal/collector/nps/nps.go | 5 +++-- .../performancecounter/performancecounter.go | 7 +++--- internal/collector/vmware/vmware.go | 5 +++-- internal/types/errors.go | 9 -------- pkg/collector/collect.go | 4 ++-- pkg/collector/collection.go | 2 ++ pkg/public/error.go | 22 +++++++++++++++++++ tools/e2e-output.txt | 4 ++++ 39 files changed, 117 insertions(+), 54 deletions(-) create mode 100644 pkg/public/error.go diff --git a/cmd/windows_exporter/main.go b/cmd/windows_exporter/main.go index f28d3a20c..0d6b9919d 100644 --- a/cmd/windows_exporter/main.go +++ b/cmd/windows_exporter/main.go @@ -22,6 +22,7 @@ package main import ( // Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts. "github.com/prometheus-community/windows_exporter/internal/windowsservice" + "github.com/prometheus-community/windows_exporter/pkg/public" "context" "errors" @@ -207,9 +208,19 @@ func run() int { // Initialize collectors before loading if err = collectors.Build(logger); err != nil { for _, err := range utils.SplitError(err) { - logger.Warn("couldn't initialize collector", - slog.Any("err", err), - ) + for _, ignoreErr := range public.ErrsBuildCanIgnored { + if errors.Is(err, ignoreErr) { + logger.Warn("couldn't initialize collector", + slog.Any("err", err), + ) + } else { + logger.Error("couldn't initialize collector", + slog.Any("err", err), + ) + + return 1 + } + } } } diff --git a/internal/collector/ad/ad.go b/internal/collector/ad/ad.go index b7edf0cf1..81b30f67f 100644 --- a/internal/collector/ad/ad.go +++ b/internal/collector/ad/ad.go @@ -23,6 +23,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -671,7 +672,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData["NTDS"] if !ok { - return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/adcs/adcs.go b/internal/collector/adcs/adcs.go index dd3ce99e5..0a0501e66 100644 --- a/internal/collector/adcs/adcs.go +++ b/internal/collector/adcs/adcs.go @@ -24,6 +24,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -191,7 +192,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", public.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/adfs/adfs.go b/internal/collector/adfs/adfs.go index af57558e7..5a92afae1 100644 --- a/internal/collector/adfs/adfs.go +++ b/internal/collector/adfs/adfs.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -435,13 +436,13 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { instanceKey := slices.Collect(maps.Keys(data)) if len(instanceKey) == 0 { - return fmt.Errorf("failed to collect ADFS metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect ADFS metrics: %w", public.ErrNoData) } adfsData, ok := data[instanceKey[0]] if !ok { - return fmt.Errorf("failed to collect ADFS metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect ADFS metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/cache/cache.go b/internal/collector/cache/cache.go index e894e112e..3220429d5 100644 --- a/internal/collector/cache/cache.go +++ b/internal/collector/cache/cache.go @@ -23,6 +23,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -322,7 +323,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { cacheData, ok := data[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect Cache metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect Cache metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/dfsr/dfsr.go b/internal/collector/dfsr/dfsr.go index 272756a39..fbebac9be 100644 --- a/internal/collector/dfsr/dfsr.go +++ b/internal/collector/dfsr/dfsr.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -543,7 +544,7 @@ func (c *Collector) collectPDHConnection(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", public.ErrNoData) } for name, connection := range perfData { @@ -621,7 +622,7 @@ func (c *Collector) collectPDHFolder(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", public.ErrNoData) } for name, folder := range perfData { @@ -825,7 +826,7 @@ func (c *Collector) collectPDHVolume(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", public.ErrNoData) } for name, volume := range perfData { diff --git a/internal/collector/dhcp/dhcp.go b/internal/collector/dhcp/dhcp.go index 0d67d7007..42f0ad187 100644 --- a/internal/collector/dhcp/dhcp.go +++ b/internal/collector/dhcp/dhcp.go @@ -23,6 +23,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -288,7 +289,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect DHCP Server metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DHCP Server metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/dns/dns.go b/internal/collector/dns/dns.go index 3e5dee7d5..4597834df 100644 --- a/internal/collector/dns/dns.go +++ b/internal/collector/dns/dns.go @@ -23,6 +23,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -284,7 +285,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect DNS metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect DNS metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/exchange/exchange_active_sync.go b/internal/collector/exchange/exchange_active_sync.go index 06c2e87ee..77072d687 100644 --- a/internal/collector/exchange/exchange_active_sync.go +++ b/internal/collector/exchange/exchange_active_sync.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -72,7 +73,7 @@ func (c *Collector) collectActiveSync(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_ad_access_processes.go b/internal/collector/exchange/exchange_ad_access_processes.go index dbf41031e..7a3b58e1b 100644 --- a/internal/collector/exchange/exchange_ad_access_processes.go +++ b/internal/collector/exchange/exchange_ad_access_processes.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -88,7 +89,7 @@ func (c *Collector) collectADAccessProcesses(ch chan<- prometheus.Metric) error } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", public.ErrNoData) } labelUseCount := make(map[string]int) diff --git a/internal/collector/exchange/exchange_autodiscover.go b/internal/collector/exchange/exchange_autodiscover.go index 5e5f48131..d75f0ce71 100644 --- a/internal/collector/exchange/exchange_autodiscover.go +++ b/internal/collector/exchange/exchange_autodiscover.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -52,7 +53,7 @@ func (c *Collector) collectAutoDiscover(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_availability_service.go b/internal/collector/exchange/exchange_availability_service.go index 7e57ee892..7a40deca4 100644 --- a/internal/collector/exchange/exchange_availability_service.go +++ b/internal/collector/exchange/exchange_availability_service.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -52,7 +53,7 @@ func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) erro } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_http_proxy.go b/internal/collector/exchange/exchange_http_proxy.go index 4e4691bce..d25bf96cb 100644 --- a/internal/collector/exchange/exchange_http_proxy.go +++ b/internal/collector/exchange/exchange_http_proxy.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -96,7 +97,7 @@ func (c *Collector) collectHTTPProxy(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", public.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/exchange/exchange_mapi_http_emsmdb.go b/internal/collector/exchange/exchange_mapi_http_emsmdb.go index a36c1e372..e9ce3ff59 100644 --- a/internal/collector/exchange/exchange_mapi_http_emsmdb.go +++ b/internal/collector/exchange/exchange_mapi_http_emsmdb.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -56,7 +57,7 @@ func (c *Collector) collectMapiHttpEmsmdb(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_outlook_web_access.go b/internal/collector/exchange/exchange_outlook_web_access.go index e3f1a4995..750d99251 100644 --- a/internal/collector/exchange/exchange_outlook_web_access.go +++ b/internal/collector/exchange/exchange_outlook_web_access.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -64,7 +65,7 @@ func (c *Collector) collectOWA(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_rpc_client_access.go b/internal/collector/exchange/exchange_rpc_client_access.go index f68ecaacc..d62d2c954 100644 --- a/internal/collector/exchange/exchange_rpc_client_access.go +++ b/internal/collector/exchange/exchange_rpc_client_access.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -96,7 +97,7 @@ func (c *Collector) collectRPC(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange RpcClientAccess metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange RpcClientAccess metrics: %w", public.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_transport_queues.go b/internal/collector/exchange/exchange_transport_queues.go index 34b6db683..840cc4b14 100644 --- a/internal/collector/exchange/exchange_transport_queues.go +++ b/internal/collector/exchange/exchange_transport_queues.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -200,7 +201,7 @@ func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchangeTransport Queues metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchangeTransport Queues metrics: %w", public.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/exchange/exchange_workload_management.go b/internal/collector/exchange/exchange_workload_management.go index 5094b02d4..2d2b0a2e9 100644 --- a/internal/collector/exchange/exchange_workload_management.go +++ b/internal/collector/exchange/exchange_workload_management.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -88,7 +89,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ch chan<- prometheus.Metr } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads metrics: %w", public.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/memory/memory.go b/internal/collector/memory/memory.go index a3eab5c77..beeb88ce1 100644 --- a/internal/collector/memory/memory.go +++ b/internal/collector/memory/memory.go @@ -28,6 +28,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -431,7 +432,7 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect Memory metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect Memory metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/mssql/mssql_access_methods.go b/internal/collector/mssql/mssql_access_methods.go index b37a56b6b..0337b30ca 100644 --- a/internal/collector/mssql/mssql_access_methods.go +++ b/internal/collector/mssql/mssql_access_methods.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -454,7 +455,7 @@ func (c *Collector) collectAccessMethods(ch chan<- prometheus.Metric) error { func (c *Collector) collectAccessMethodsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_availability_replica.go b/internal/collector/mssql/mssql_availability_replica.go index 0817e11b4..a1bb4d87a 100644 --- a/internal/collector/mssql/mssql_availability_replica.go +++ b/internal/collector/mssql/mssql_availability_replica.go @@ -22,6 +22,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -140,7 +141,7 @@ func (c *Collector) collectAvailabilityReplica(ch chan<- prometheus.Metric) erro func (c *Collector) collectAvailabilityReplicaInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_buffer_manager.go b/internal/collector/mssql/mssql_buffer_manager.go index 12e297c0f..befb2b7ed 100644 --- a/internal/collector/mssql/mssql_buffer_manager.go +++ b/internal/collector/mssql/mssql_buffer_manager.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -264,7 +265,7 @@ func (c *Collector) collectBufferManager(ch chan<- prometheus.Metric) error { func (c *Collector) collectBufferManagerInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_database.go b/internal/collector/mssql/mssql_database.go index bc6a337fb..72c775c89 100644 --- a/internal/collector/mssql/mssql_database.go +++ b/internal/collector/mssql/mssql_database.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -492,7 +493,7 @@ func (c *Collector) collectDatabases(ch chan<- prometheus.Metric) error { func (c *Collector) collectDatabasesInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_database_replica.go b/internal/collector/mssql/mssql_database_replica.go index d89f50856..96906b5da 100644 --- a/internal/collector/mssql/mssql_database_replica.go +++ b/internal/collector/mssql/mssql_database_replica.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -274,7 +275,7 @@ func (c *Collector) collectDatabaseReplica(ch chan<- prometheus.Metric) error { func (c *Collector) collectDatabaseReplicaInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_general_statistics.go b/internal/collector/mssql/mssql_general_statistics.go index 4a8248606..abd37d9c9 100644 --- a/internal/collector/mssql/mssql_general_statistics.go +++ b/internal/collector/mssql/mssql_general_statistics.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -274,7 +275,7 @@ func (c *Collector) collectGeneralStatistics(ch chan<- prometheus.Metric) error func (c *Collector) collectGeneralStatisticsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_locks.go b/internal/collector/mssql/mssql_locks.go index 503befd67..6de3a038c 100644 --- a/internal/collector/mssql/mssql_locks.go +++ b/internal/collector/mssql/mssql_locks.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -130,7 +131,7 @@ func (c *Collector) collectLocks(ch chan<- prometheus.Metric) error { func (c *Collector) collectLocksInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_memory_manager.go b/internal/collector/mssql/mssql_memory_manager.go index 9d397629c..91838316d 100644 --- a/internal/collector/mssql/mssql_memory_manager.go +++ b/internal/collector/mssql/mssql_memory_manager.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -237,7 +238,7 @@ func (c *Collector) collectMemoryManager(ch chan<- prometheus.Metric) error { func (c *Collector) collectMemoryManagerInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_sql_errors.go b/internal/collector/mssql/mssql_sql_errors.go index 8f4392c51..8046acc5b 100644 --- a/internal/collector/mssql/mssql_sql_errors.go +++ b/internal/collector/mssql/mssql_sql_errors.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -68,7 +69,7 @@ func (c *Collector) collectSQLErrors(ch chan<- prometheus.Metric) error { func (c *Collector) collectSQLErrorsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_sql_stats.go b/internal/collector/mssql/mssql_sql_stats.go index f68234952..66673ce88 100644 --- a/internal/collector/mssql/mssql_sql_stats.go +++ b/internal/collector/mssql/mssql_sql_stats.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -156,7 +157,7 @@ func (c *Collector) collectSQLStats(ch chan<- prometheus.Metric) error { func (c *Collector) collectSQLStatsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_transactions.go b/internal/collector/mssql/mssql_transactions.go index fc8ecea7e..cd0fe200d 100644 --- a/internal/collector/mssql/mssql_transactions.go +++ b/internal/collector/mssql/mssql_transactions.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -176,7 +177,7 @@ func (c *Collector) collectTransactions(ch chan<- prometheus.Metric) error { // - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-transactions-object func (c *Collector) collectTransactionsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_wait_stats.go b/internal/collector/mssql/mssql_wait_stats.go index 720ac31f1..48b7ce192 100644 --- a/internal/collector/mssql/mssql_wait_stats.go +++ b/internal/collector/mssql/mssql_wait_stats.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -166,7 +167,7 @@ func (c *Collector) collectWaitStats(ch chan<- prometheus.Metric) error { func (c *Collector) collectWaitStatsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return types.ErrCollectorNotInitialized + return public.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/nps/nps.go b/internal/collector/nps/nps.go index aa4e37a48..9b53db55c 100644 --- a/internal/collector/nps/nps.go +++ b/internal/collector/nps/nps.go @@ -24,6 +24,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -314,7 +315,7 @@ func (c *Collector) collectAccept(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect NPS Authentication Server metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect NPS Authentication Server metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( @@ -406,7 +407,7 @@ func (c *Collector) collectAccounting(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect NPS Accounting Server metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect NPS Accounting Server metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index 0527e0cfc..b00f5d610 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -125,7 +125,8 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { c.objects = make([]Object, 0, len(c.config.Objects)) names := make([]string, 0, len(c.config.Objects)) - errs := make([]error, 0, len(c.config.Objects)) + + var errs []error for i, object := range c.config.Objects { if object.Name == "" { @@ -205,7 +206,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { // Collect sends the metric values for each metric // to the provided prometheus Metric channel. func (c *Collector) Collect(ch chan<- prometheus.Metric) error { - errs := make([]error, 0, len(c.objects)) + var errs []error for _, perfDataObject := range c.objects { startTime := time.Now() @@ -306,7 +307,7 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob } } - return errors.Join() + return errors.Join(errs...) } func (c *Collector) sanitizeMetricName(name string) string { diff --git a/internal/collector/vmware/vmware.go b/internal/collector/vmware/vmware.go index 2aaf5687a..8f31c8ac9 100644 --- a/internal/collector/vmware/vmware.go +++ b/internal/collector/vmware/vmware.go @@ -25,6 +25,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -267,7 +268,7 @@ func (c *Collector) collectMem(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect VM Memory metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect VM Memory metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( @@ -353,7 +354,7 @@ func (c *Collector) collectCpu(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceTotal] if !ok { - return fmt.Errorf("failed to collect VM CPU metrics: %w", types.ErrNoData) + return fmt.Errorf("failed to collect VM CPU metrics: %w", public.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/types/errors.go b/internal/types/errors.go index da4f4c1c1..2ed131a0b 100644 --- a/internal/types/errors.go +++ b/internal/types/errors.go @@ -12,12 +12,3 @@ // limitations under the License. package types - -import ( - "errors" -) - -var ( - ErrCollectorNotInitialized = errors.New("collector not initialized") - ErrNoData = errors.New("no data") -) diff --git a/pkg/collector/collect.go b/pkg/collector/collect.go index 233bd27a7..36f6cac78 100644 --- a/pkg/collector/collect.go +++ b/pkg/collector/collect.go @@ -25,7 +25,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" - "github.com/prometheus-community/windows_exporter/internal/types" + "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -204,7 +204,7 @@ func (c *Collection) collectCollector(ch chan<- prometheus.Metric, logger *slog. return pending } - if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, types.ErrNoData) { + if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, public.ErrNoData) { loggerFn := logger.Warn if errors.Is(err, perfdata.ErrPerformanceCounterNotInitialized) || errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) { diff --git a/pkg/collector/collection.go b/pkg/collector/collection.go index de71a2d68..fed7b81ef 100644 --- a/pkg/collector/collection.go +++ b/pkg/collector/collection.go @@ -196,6 +196,8 @@ func (c *Collection) Enable(enabledCollectors []string) error { } // Build To be called by the exporter for collector initialization. +// Instead, fail fast, it will try to build all collectors and return all errors. +// errors are joined with errors.Join. func (c *Collection) Build(logger *slog.Logger) error { c.startTime = gotime.Now() diff --git a/pkg/public/error.go b/pkg/public/error.go new file mode 100644 index 000000000..1e65979f9 --- /dev/null +++ b/pkg/public/error.go @@ -0,0 +1,22 @@ +package public + +import ( + "errors" + + "github.com/prometheus-community/windows_exporter/internal/mi" + "github.com/prometheus-community/windows_exporter/internal/perfdata" +) + +var ( + ErrCollectorNotInitialized = errors.New("collector not initialized") + ErrNoData = errors.New("no data") +) + +var ( + // ErrsBuildCanIgnored indicates errors that can be ignored during build. + // This is used to allow end users to enable collectors that are available on all systems, e.g. mssql. + ErrsBuildCanIgnored = []error{ + perfdata.ErrNoData, + mi.MI_RESULT_INVALID_NAMESPACE, + } +) diff --git a/tools/e2e-output.txt b/tools/e2e-output.txt index 680ed5e96..c03cfbd02 100644 --- a/tools/e2e-output.txt +++ b/tools/e2e-output.txt @@ -319,6 +319,10 @@ windows_exporter_collector_timeout{collector="udp"} 0 # TYPE windows_pagefile_free_bytes gauge # HELP windows_pagefile_limit_bytes Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files # TYPE windows_pagefile_limit_bytes gauge +# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection. +# TYPE windows_performancecounter_collector_duration_seconds gauge +# HELP windows_performancecounter_collector_success windows_exporter: Whether a performancecounter child collector was successful. +# TYPE windows_performancecounter_collector_success gauge # HELP windows_performancecounter_memory_cache_faults_sec windows_exporter: custom Performance Counter metric # TYPE windows_performancecounter_memory_cache_faults_sec counter # HELP windows_performancecounter_processor_information_processor_time windows_exporter: custom Performance Counter metric From d68a1644fabdfbc645f7caad74c6294cfb1b6eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 9 Dec 2024 18:53:51 +0100 Subject: [PATCH 7/8] process: fix metric labels for multiple process instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- .run/all.run.xml | 4 +-- cmd/windows_exporter/main.go | 25 ++++++------------- internal/collector/ad/ad.go | 3 +-- internal/collector/adcs/adcs.go | 3 +-- internal/collector/adfs/adfs.go | 5 ++-- internal/collector/cache/cache.go | 3 +-- internal/collector/dfsr/dfsr.go | 7 +++--- internal/collector/dhcp/dhcp.go | 3 +-- internal/collector/dns/dns.go | 3 +-- .../exchange/exchange_active_sync.go | 3 +-- .../exchange/exchange_ad_access_processes.go | 3 +-- .../exchange/exchange_autodiscover.go | 3 +-- .../exchange/exchange_availability_service.go | 3 +-- .../collector/exchange/exchange_http_proxy.go | 3 +-- .../exchange/exchange_mapi_http_emsmdb.go | 3 +-- .../exchange/exchange_outlook_web_access.go | 3 +-- .../exchange/exchange_rpc_client_access.go | 3 +-- .../exchange/exchange_transport_queues.go | 3 +-- .../exchange/exchange_workload_management.go | 3 +-- internal/collector/memory/memory.go | 3 +-- .../collector/mssql/mssql_access_methods.go | 3 +-- .../mssql/mssql_availability_replica.go | 3 +-- .../collector/mssql/mssql_buffer_manager.go | 3 +-- internal/collector/mssql/mssql_database.go | 3 +-- .../collector/mssql/mssql_database_replica.go | 3 +-- .../mssql/mssql_general_statistics.go | 3 +-- internal/collector/mssql/mssql_locks.go | 3 +-- .../collector/mssql/mssql_memory_manager.go | 3 +-- internal/collector/mssql/mssql_sql_errors.go | 3 +-- internal/collector/mssql/mssql_sql_stats.go | 3 +-- .../collector/mssql/mssql_transactions.go | 3 +-- internal/collector/mssql/mssql_wait_stats.go | 3 +-- internal/collector/nps/nps.go | 5 ++-- .../performancecounter/performancecounter.go | 2 -- internal/collector/vmware/vmware.go | 5 ++-- internal/types/errors.go | 7 ++++++ pkg/collector/collect.go | 4 +-- pkg/collector/collection.go | 15 ++++++++++- pkg/public/error.go | 22 ---------------- 39 files changed, 70 insertions(+), 115 deletions(-) delete mode 100644 pkg/public/error.go diff --git a/.run/all.run.xml b/.run/all.run.xml index 65ec0a71d..5b5035b88 100644 --- a/.run/all.run.xml +++ b/.run/all.run.xml @@ -2,7 +2,7 @@ - + @@ -10,4 +10,4 @@ - \ No newline at end of file + diff --git a/cmd/windows_exporter/main.go b/cmd/windows_exporter/main.go index 0d6b9919d..99e3fc63d 100644 --- a/cmd/windows_exporter/main.go +++ b/cmd/windows_exporter/main.go @@ -20,10 +20,6 @@ package main //goland:noinspection GoUnsortedImport //nolint:gofumpt import ( - // Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts. - "github.com/prometheus-community/windows_exporter/internal/windowsservice" - "github.com/prometheus-community/windows_exporter/pkg/public" - "context" "errors" "fmt" @@ -38,6 +34,9 @@ import ( "strings" "time" + // Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts. + "github.com/prometheus-community/windows_exporter/internal/windowsservice" + "github.com/alecthomas/kingpin/v2" "github.com/prometheus-community/windows_exporter/internal/config" "github.com/prometheus-community/windows_exporter/internal/httphandler" @@ -208,19 +207,11 @@ func run() int { // Initialize collectors before loading if err = collectors.Build(logger); err != nil { for _, err := range utils.SplitError(err) { - for _, ignoreErr := range public.ErrsBuildCanIgnored { - if errors.Is(err, ignoreErr) { - logger.Warn("couldn't initialize collector", - slog.Any("err", err), - ) - } else { - logger.Error("couldn't initialize collector", - slog.Any("err", err), - ) - - return 1 - } - } + logger.Error("couldn't initialize collector", + slog.Any("err", err), + ) + + return 1 } } diff --git a/internal/collector/ad/ad.go b/internal/collector/ad/ad.go index 81b30f67f..b7edf0cf1 100644 --- a/internal/collector/ad/ad.go +++ b/internal/collector/ad/ad.go @@ -23,7 +23,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -672,7 +671,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData["NTDS"] if !ok { - return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/adcs/adcs.go b/internal/collector/adcs/adcs.go index 0a0501e66..dd3ce99e5 100644 --- a/internal/collector/adcs/adcs.go +++ b/internal/collector/adcs/adcs.go @@ -24,7 +24,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -192,7 +191,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", types.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/adfs/adfs.go b/internal/collector/adfs/adfs.go index 5a92afae1..af57558e7 100644 --- a/internal/collector/adfs/adfs.go +++ b/internal/collector/adfs/adfs.go @@ -26,7 +26,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -436,13 +435,13 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { instanceKey := slices.Collect(maps.Keys(data)) if len(instanceKey) == 0 { - return fmt.Errorf("failed to collect ADFS metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect ADFS metrics: %w", types.ErrNoData) } adfsData, ok := data[instanceKey[0]] if !ok { - return fmt.Errorf("failed to collect ADFS metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect ADFS metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/cache/cache.go b/internal/collector/cache/cache.go index 3220429d5..e894e112e 100644 --- a/internal/collector/cache/cache.go +++ b/internal/collector/cache/cache.go @@ -23,7 +23,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -323,7 +322,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { cacheData, ok := data[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect Cache metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect Cache metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/dfsr/dfsr.go b/internal/collector/dfsr/dfsr.go index fbebac9be..272756a39 100644 --- a/internal/collector/dfsr/dfsr.go +++ b/internal/collector/dfsr/dfsr.go @@ -26,7 +26,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -544,7 +543,7 @@ func (c *Collector) collectPDHConnection(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", types.ErrNoData) } for name, connection := range perfData { @@ -622,7 +621,7 @@ func (c *Collector) collectPDHFolder(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", types.ErrNoData) } for name, folder := range perfData { @@ -826,7 +825,7 @@ func (c *Collector) collectPDHVolume(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", types.ErrNoData) } for name, volume := range perfData { diff --git a/internal/collector/dhcp/dhcp.go b/internal/collector/dhcp/dhcp.go index 42f0ad187..0d67d7007 100644 --- a/internal/collector/dhcp/dhcp.go +++ b/internal/collector/dhcp/dhcp.go @@ -23,7 +23,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -289,7 +288,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect DHCP Server metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DHCP Server metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/dns/dns.go b/internal/collector/dns/dns.go index 4597834df..3e5dee7d5 100644 --- a/internal/collector/dns/dns.go +++ b/internal/collector/dns/dns.go @@ -23,7 +23,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -285,7 +284,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect DNS metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect DNS metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/exchange/exchange_active_sync.go b/internal/collector/exchange/exchange_active_sync.go index 77072d687..06c2e87ee 100644 --- a/internal/collector/exchange/exchange_active_sync.go +++ b/internal/collector/exchange/exchange_active_sync.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -73,7 +72,7 @@ func (c *Collector) collectActiveSync(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_ad_access_processes.go b/internal/collector/exchange/exchange_ad_access_processes.go index 7a3b58e1b..dbf41031e 100644 --- a/internal/collector/exchange/exchange_ad_access_processes.go +++ b/internal/collector/exchange/exchange_ad_access_processes.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -89,7 +88,7 @@ func (c *Collector) collectADAccessProcesses(ch chan<- prometheus.Metric) error } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", types.ErrNoData) } labelUseCount := make(map[string]int) diff --git a/internal/collector/exchange/exchange_autodiscover.go b/internal/collector/exchange/exchange_autodiscover.go index d75f0ce71..5e5f48131 100644 --- a/internal/collector/exchange/exchange_autodiscover.go +++ b/internal/collector/exchange/exchange_autodiscover.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -53,7 +52,7 @@ func (c *Collector) collectAutoDiscover(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_availability_service.go b/internal/collector/exchange/exchange_availability_service.go index 7a40deca4..7e57ee892 100644 --- a/internal/collector/exchange/exchange_availability_service.go +++ b/internal/collector/exchange/exchange_availability_service.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -53,7 +52,7 @@ func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) erro } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_http_proxy.go b/internal/collector/exchange/exchange_http_proxy.go index d25bf96cb..4e4691bce 100644 --- a/internal/collector/exchange/exchange_http_proxy.go +++ b/internal/collector/exchange/exchange_http_proxy.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -97,7 +96,7 @@ func (c *Collector) collectHTTPProxy(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", types.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/exchange/exchange_mapi_http_emsmdb.go b/internal/collector/exchange/exchange_mapi_http_emsmdb.go index e9ce3ff59..a36c1e372 100644 --- a/internal/collector/exchange/exchange_mapi_http_emsmdb.go +++ b/internal/collector/exchange/exchange_mapi_http_emsmdb.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -57,7 +56,7 @@ func (c *Collector) collectMapiHttpEmsmdb(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_outlook_web_access.go b/internal/collector/exchange/exchange_outlook_web_access.go index 750d99251..e3f1a4995 100644 --- a/internal/collector/exchange/exchange_outlook_web_access.go +++ b/internal/collector/exchange/exchange_outlook_web_access.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -65,7 +64,7 @@ func (c *Collector) collectOWA(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_rpc_client_access.go b/internal/collector/exchange/exchange_rpc_client_access.go index d62d2c954..f68ecaacc 100644 --- a/internal/collector/exchange/exchange_rpc_client_access.go +++ b/internal/collector/exchange/exchange_rpc_client_access.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -97,7 +96,7 @@ func (c *Collector) collectRPC(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange RpcClientAccess metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange RpcClientAccess metrics: %w", types.ErrNoData) } for _, data := range perfData { diff --git a/internal/collector/exchange/exchange_transport_queues.go b/internal/collector/exchange/exchange_transport_queues.go index 840cc4b14..34b6db683 100644 --- a/internal/collector/exchange/exchange_transport_queues.go +++ b/internal/collector/exchange/exchange_transport_queues.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -201,7 +200,7 @@ func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error { } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchangeTransport Queues metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchangeTransport Queues metrics: %w", types.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/exchange/exchange_workload_management.go b/internal/collector/exchange/exchange_workload_management.go index 2d2b0a2e9..5094b02d4 100644 --- a/internal/collector/exchange/exchange_workload_management.go +++ b/internal/collector/exchange/exchange_workload_management.go @@ -20,7 +20,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -89,7 +88,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ch chan<- prometheus.Metr } if len(perfData) == 0 { - return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads metrics: %w", types.ErrNoData) } for name, data := range perfData { diff --git a/internal/collector/memory/memory.go b/internal/collector/memory/memory.go index beeb88ce1..a3eab5c77 100644 --- a/internal/collector/memory/memory.go +++ b/internal/collector/memory/memory.go @@ -28,7 +28,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -432,7 +431,7 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect Memory metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect Memory metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/mssql/mssql_access_methods.go b/internal/collector/mssql/mssql_access_methods.go index 0337b30ca..b37a56b6b 100644 --- a/internal/collector/mssql/mssql_access_methods.go +++ b/internal/collector/mssql/mssql_access_methods.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -455,7 +454,7 @@ func (c *Collector) collectAccessMethods(ch chan<- prometheus.Metric) error { func (c *Collector) collectAccessMethodsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_availability_replica.go b/internal/collector/mssql/mssql_availability_replica.go index a1bb4d87a..0817e11b4 100644 --- a/internal/collector/mssql/mssql_availability_replica.go +++ b/internal/collector/mssql/mssql_availability_replica.go @@ -22,7 +22,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -141,7 +140,7 @@ func (c *Collector) collectAvailabilityReplica(ch chan<- prometheus.Metric) erro func (c *Collector) collectAvailabilityReplicaInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_buffer_manager.go b/internal/collector/mssql/mssql_buffer_manager.go index befb2b7ed..12e297c0f 100644 --- a/internal/collector/mssql/mssql_buffer_manager.go +++ b/internal/collector/mssql/mssql_buffer_manager.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -265,7 +264,7 @@ func (c *Collector) collectBufferManager(ch chan<- prometheus.Metric) error { func (c *Collector) collectBufferManagerInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_database.go b/internal/collector/mssql/mssql_database.go index 72c775c89..bc6a337fb 100644 --- a/internal/collector/mssql/mssql_database.go +++ b/internal/collector/mssql/mssql_database.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -493,7 +492,7 @@ func (c *Collector) collectDatabases(ch chan<- prometheus.Metric) error { func (c *Collector) collectDatabasesInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_database_replica.go b/internal/collector/mssql/mssql_database_replica.go index 96906b5da..d89f50856 100644 --- a/internal/collector/mssql/mssql_database_replica.go +++ b/internal/collector/mssql/mssql_database_replica.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -275,7 +274,7 @@ func (c *Collector) collectDatabaseReplica(ch chan<- prometheus.Metric) error { func (c *Collector) collectDatabaseReplicaInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_general_statistics.go b/internal/collector/mssql/mssql_general_statistics.go index abd37d9c9..4a8248606 100644 --- a/internal/collector/mssql/mssql_general_statistics.go +++ b/internal/collector/mssql/mssql_general_statistics.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -275,7 +274,7 @@ func (c *Collector) collectGeneralStatistics(ch chan<- prometheus.Metric) error func (c *Collector) collectGeneralStatisticsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_locks.go b/internal/collector/mssql/mssql_locks.go index 6de3a038c..503befd67 100644 --- a/internal/collector/mssql/mssql_locks.go +++ b/internal/collector/mssql/mssql_locks.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -131,7 +130,7 @@ func (c *Collector) collectLocks(ch chan<- prometheus.Metric) error { func (c *Collector) collectLocksInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_memory_manager.go b/internal/collector/mssql/mssql_memory_manager.go index 91838316d..9d397629c 100644 --- a/internal/collector/mssql/mssql_memory_manager.go +++ b/internal/collector/mssql/mssql_memory_manager.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -238,7 +237,7 @@ func (c *Collector) collectMemoryManager(ch chan<- prometheus.Metric) error { func (c *Collector) collectMemoryManagerInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_sql_errors.go b/internal/collector/mssql/mssql_sql_errors.go index 8046acc5b..8f4392c51 100644 --- a/internal/collector/mssql/mssql_sql_errors.go +++ b/internal/collector/mssql/mssql_sql_errors.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -69,7 +68,7 @@ func (c *Collector) collectSQLErrors(ch chan<- prometheus.Metric) error { func (c *Collector) collectSQLErrorsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_sql_stats.go b/internal/collector/mssql/mssql_sql_stats.go index 66673ce88..f68234952 100644 --- a/internal/collector/mssql/mssql_sql_stats.go +++ b/internal/collector/mssql/mssql_sql_stats.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -157,7 +156,7 @@ func (c *Collector) collectSQLStats(ch chan<- prometheus.Metric) error { func (c *Collector) collectSQLStatsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_transactions.go b/internal/collector/mssql/mssql_transactions.go index cd0fe200d..fc8ecea7e 100644 --- a/internal/collector/mssql/mssql_transactions.go +++ b/internal/collector/mssql/mssql_transactions.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -177,7 +176,7 @@ func (c *Collector) collectTransactions(ch chan<- prometheus.Metric) error { // - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-transactions-object func (c *Collector) collectTransactionsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/mssql/mssql_wait_stats.go b/internal/collector/mssql/mssql_wait_stats.go index 48b7ce192..720ac31f1 100644 --- a/internal/collector/mssql/mssql_wait_stats.go +++ b/internal/collector/mssql/mssql_wait_stats.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -167,7 +166,7 @@ func (c *Collector) collectWaitStats(ch chan<- prometheus.Metric) error { func (c *Collector) collectWaitStatsInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *perfdata.Collector) error { if perfDataCollector == nil { - return public.ErrCollectorNotInitialized + return types.ErrCollectorNotInitialized } perfData, err := perfDataCollector.Collect() diff --git a/internal/collector/nps/nps.go b/internal/collector/nps/nps.go index 9b53db55c..aa4e37a48 100644 --- a/internal/collector/nps/nps.go +++ b/internal/collector/nps/nps.go @@ -24,7 +24,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -315,7 +314,7 @@ func (c *Collector) collectAccept(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect NPS Authentication Server metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect NPS Authentication Server metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( @@ -407,7 +406,7 @@ func (c *Collector) collectAccounting(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect NPS Accounting Server metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect NPS Accounting Server metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index b00f5d610..99452a07b 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -174,8 +174,6 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { collector, err := perfdata.NewCollector(object.Object, object.Instances, counters) if err != nil { errs = append(errs, fmt.Errorf("failed collector for %s: %w", object.Name, err)) - - continue } if object.InstanceLabel == "" { diff --git a/internal/collector/vmware/vmware.go b/internal/collector/vmware/vmware.go index 8f31c8ac9..2aaf5687a 100644 --- a/internal/collector/vmware/vmware.go +++ b/internal/collector/vmware/vmware.go @@ -25,7 +25,6 @@ import ( "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/utils" - "github.com/prometheus-community/windows_exporter/pkg/public" "github.com/prometheus/client_golang/prometheus" ) @@ -268,7 +267,7 @@ func (c *Collector) collectMem(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceEmpty] if !ok { - return fmt.Errorf("failed to collect VM Memory metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect VM Memory metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( @@ -354,7 +353,7 @@ func (c *Collector) collectCpu(ch chan<- prometheus.Metric) error { data, ok := perfData[perfdata.InstanceTotal] if !ok { - return fmt.Errorf("failed to collect VM CPU metrics: %w", public.ErrNoData) + return fmt.Errorf("failed to collect VM CPU metrics: %w", types.ErrNoData) } ch <- prometheus.MustNewConstMetric( diff --git a/internal/types/errors.go b/internal/types/errors.go index 2ed131a0b..3694d7cc9 100644 --- a/internal/types/errors.go +++ b/internal/types/errors.go @@ -12,3 +12,10 @@ // limitations under the License. package types + +import "errors" + +var ( + ErrCollectorNotInitialized = errors.New("collector not initialized") + ErrNoData = errors.New("no data") +) diff --git a/pkg/collector/collect.go b/pkg/collector/collect.go index 36f6cac78..233bd27a7 100644 --- a/pkg/collector/collect.go +++ b/pkg/collector/collect.go @@ -25,7 +25,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/mi" "github.com/prometheus-community/windows_exporter/internal/perfdata" - "github.com/prometheus-community/windows_exporter/pkg/public" + "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus/client_golang/prometheus" ) @@ -204,7 +204,7 @@ func (c *Collection) collectCollector(ch chan<- prometheus.Metric, logger *slog. return pending } - if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, public.ErrNoData) { + if err != nil && !errors.Is(err, perfdata.ErrNoData) && !errors.Is(err, types.ErrNoData) { loggerFn := logger.Warn if errors.Is(err, perfdata.ErrPerformanceCounterNotInitialized) || errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) { diff --git a/pkg/collector/collection.go b/pkg/collector/collection.go index fed7b81ef..8a47067ae 100644 --- a/pkg/collector/collection.go +++ b/pkg/collector/collection.go @@ -74,6 +74,7 @@ import ( "github.com/prometheus-community/windows_exporter/internal/collector/update" "github.com/prometheus-community/windows_exporter/internal/collector/vmware" "github.com/prometheus-community/windows_exporter/internal/mi" + "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus/client_golang/prometheus" ) @@ -210,7 +211,6 @@ func (c *Collection) Build(logger *slog.Logger) error { wg.Add(len(c.collectors)) errCh := make(chan error, len(c.collectors)) - errs := make([]error, 0, len(c.collectors)) for _, collector := range c.collectors { go func() { @@ -226,7 +226,20 @@ func (c *Collection) Build(logger *slog.Logger) error { close(errCh) + var errs []error + for err := range errCh { + if errors.Is(err, perfdata.ErrNoData) || + errors.Is(err, perfdata.NewPdhError(perfdata.PdhCstatusNoObject)) || + errors.Is(err, perfdata.NewPdhError(perfdata.PdhCstatusNoCounter)) || + errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) { + logger.Warn("couldn't initialize collector", + slog.Any("err", err), + ) + + continue + } + errs = append(errs, err) } diff --git a/pkg/public/error.go b/pkg/public/error.go deleted file mode 100644 index 1e65979f9..000000000 --- a/pkg/public/error.go +++ /dev/null @@ -1,22 +0,0 @@ -package public - -import ( - "errors" - - "github.com/prometheus-community/windows_exporter/internal/mi" - "github.com/prometheus-community/windows_exporter/internal/perfdata" -) - -var ( - ErrCollectorNotInitialized = errors.New("collector not initialized") - ErrNoData = errors.New("no data") -) - -var ( - // ErrsBuildCanIgnored indicates errors that can be ignored during build. - // This is used to allow end users to enable collectors that are available on all systems, e.g. mssql. - ErrsBuildCanIgnored = []error{ - perfdata.ErrNoData, - mi.MI_RESULT_INVALID_NAMESPACE, - } -) From f9adbcb236464500f966081f29e179e4712554f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 9 Dec 2024 19:07:04 +0100 Subject: [PATCH 8/8] process: fix metric labels for multiple process instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- cmd/windows_exporter/main.go | 6 +++--- pkg/collector/collection.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/windows_exporter/main.go b/cmd/windows_exporter/main.go index 99e3fc63d..63a47d10c 100644 --- a/cmd/windows_exporter/main.go +++ b/cmd/windows_exporter/main.go @@ -20,6 +20,9 @@ package main //goland:noinspection GoUnsortedImport //nolint:gofumpt import ( + // Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts. + "github.com/prometheus-community/windows_exporter/internal/windowsservice" + "context" "errors" "fmt" @@ -34,9 +37,6 @@ import ( "strings" "time" - // Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts. - "github.com/prometheus-community/windows_exporter/internal/windowsservice" - "github.com/alecthomas/kingpin/v2" "github.com/prometheus-community/windows_exporter/internal/config" "github.com/prometheus-community/windows_exporter/internal/httphandler" diff --git a/pkg/collector/collection.go b/pkg/collector/collection.go index 8a47067ae..c79f36386 100644 --- a/pkg/collector/collection.go +++ b/pkg/collector/collection.go @@ -226,7 +226,7 @@ func (c *Collection) Build(logger *slog.Logger) error { close(errCh) - var errs []error + errs := make([]error, 0, len(c.collectors)) for err := range errCh { if errors.Is(err, perfdata.ErrNoData) ||