diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a541908a..7c1d5ce4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -91,5 +91,5 @@ jobs: uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: # renovate: github=golangci/golangci-lint - version: v2.5.0 + version: v2.6.0 args: "--max-same-issues=0" diff --git a/internal/collector/logical_disk/logical_disk.go b/internal/collector/logical_disk/logical_disk.go index 2be4854c..479cffd3 100644 --- a/internal/collector/logical_disk/logical_disk.go +++ b/internal/collector/logical_disk/logical_disk.go @@ -775,6 +775,7 @@ func (c *Collector) workerBitlocker(ctx context.Context, initErrCh chan<- error) // Otherwise, attempting to initialize and run parallel queries across // goroutines will result in protected memory errors. runtime.LockOSThread() + defer runtime.UnlockOSThread() if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil { diff --git a/internal/collector/performancecounter/performancecounter.go b/internal/collector/performancecounter/performancecounter.go index eae7a841..c77cebe3 100644 --- a/internal/collector/performancecounter/performancecounter.go +++ b/internal/collector/performancecounter/performancecounter.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "log/slog" + "maps" "reflect" "regexp" "slices" @@ -184,7 +185,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { return reflect.StructField{ Name: strings.ToUpper(sanitizeMetricName(name)), - Type: reflect.TypeOf(float64(0)), + Type: reflect.TypeFor[float64](), Tag: reflect.StructTag(fmt.Sprintf(`perfdata:"%s"`, name)), }, nil }(counter.Name) @@ -200,13 +201,13 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error { if object.Instances != nil { fields = append(fields, reflect.StructField{ Name: "Name", - Type: reflect.TypeOf(""), + Type: reflect.TypeFor[string](), }) } fields = append(fields, reflect.StructField{ Name: "MetricType", - Type: reflect.TypeOf(prometheus.ValueType(0)), + Type: reflect.TypeFor[prometheus.ValueType](), }) valueType := reflect.StructOf(fields) @@ -321,7 +322,7 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob continue } - if field.Kind() != reflect.TypeOf(prometheus.ValueType(0)).Kind() { + if field.Kind() != reflect.TypeFor[prometheus.ValueType]().Kind() { errs = append(errs, fmt.Errorf("failed to cast MetricType for %s to prometheus.ValueType", counter.Name)) continue @@ -351,9 +352,7 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob } } - for key, value := range counter.Labels { - labels[key] = value - } + maps.Copy(labels, counter.Labels) switch counter.Type { case "counter": diff --git a/internal/collector/scheduled_task/scheduled_task.go b/internal/collector/scheduled_task/scheduled_task.go index 8100c152..00e3c117 100644 --- a/internal/collector/scheduled_task/scheduled_task.go +++ b/internal/collector/scheduled_task/scheduled_task.go @@ -248,6 +248,7 @@ func getScheduledTasks() (ScheduledTasks, error) { // Otherwise, attempting to initialize and run parallel queries across // goroutines will result in protected memory errors. runtime.LockOSThread() + defer runtime.UnlockOSThread() if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil { @@ -256,6 +257,7 @@ func getScheduledTasks() (ScheduledTasks, error) { return nil, err } } + defer ole.CoUninitialize() schedClassID, err := ole.ClassIDFrom(SCHEDULED_TASK_PROGRAM_ID) diff --git a/internal/collector/textfile/textfile.go b/internal/collector/textfile/textfile.go index 63f2b75e..fe777e22 100644 --- a/internal/collector/textfile/textfile.go +++ b/internal/collector/textfile/textfile.go @@ -25,6 +25,7 @@ import ( "os" "path/filepath" "reflect" + "slices" "sort" "strings" "time" @@ -183,17 +184,7 @@ func (c *Collector) convertMetricFamily(logger *slog.Logger, metricFamily *dto.M } for k := range allLabelNames { - present := false - - for _, name := range names { - if k == name { - present = true - - break - } - } - - if !present { + if !slices.Contains(names, k) { names = append(names, k) values = append(values, "") } diff --git a/internal/collector/textfile/textfile_test_test.go b/internal/collector/textfile/textfile_test_test.go index e522ba1a..664b42d7 100644 --- a/internal/collector/textfile/textfile_test_test.go +++ b/internal/collector/textfile/textfile_test_test.go @@ -64,6 +64,7 @@ func TestMultipleDirectories(t *testing.T) { err := val.Write(&metric) require.NoError(t, err) + //nolint:modernize,perfsprint got += metric.String() } @@ -102,6 +103,7 @@ func TestDuplicateFileName(t *testing.T) { err := val.Write(&metric) require.NoError(t, err) + //nolint:perfsprint got += metric.String() } diff --git a/internal/collector/update/update.go b/internal/collector/update/update.go index cbdad6e9..e54cc5cf 100644 --- a/internal/collector/update/update.go +++ b/internal/collector/update/update.go @@ -176,6 +176,7 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge // Otherwise, attempting to initialize and run parallel queries across // goroutines will result in protected memory errors. runtime.LockOSThread() + defer runtime.UnlockOSThread() if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil { diff --git a/internal/config/config.go b/internal/config/config.go index da311d89..6f7c99c4 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -96,12 +96,12 @@ func Parse(app *kingpin.Application, args []string) error { // ParseConfigFile manually parses the configuration file from the command line arguments. func ParseConfigFile(args []string) string { for i, cliFlag := range args { - if strings.HasPrefix(cliFlag, "--config.file=") { - return strings.TrimPrefix(cliFlag, "--config.file=") + if configFile, ok := strings.CutPrefix(cliFlag, "--config.file="); ok { + return configFile } - if strings.HasPrefix(cliFlag, "-config.file=") { - return strings.TrimPrefix(cliFlag, "-config.file=") + if configFile, ok := strings.CutPrefix(cliFlag, "-config.file="); ok { + return configFile } if strings.HasSuffix(cliFlag, "-config.file") { @@ -148,7 +148,7 @@ func NewConfigFileResolver(filePath string) (*Resolver, error) { return nil, fmt.Errorf("failed to rewind file: %w", err) } - var rawValues map[string]interface{} + var rawValues map[string]any decoder = yaml.NewDecoder(file) if err = decoder.Decode(&rawValues); err != nil { diff --git a/internal/config/flatten_test.go b/internal/config/flatten_test.go index 89d9bbd3..22987f16 100644 --- a/internal/config/flatten_test.go +++ b/internal/config/flatten_test.go @@ -36,7 +36,7 @@ func TestConfigFlattening(t *testing.T) { log: level: debug`) - var data map[string]interface{} + var data map[string]any err := yaml.Unmarshal(goodYamlConfig, &data) if err != nil { diff --git a/internal/headers/hcs/types.go b/internal/headers/hcs/types.go index f61e9332..85eb588b 100644 --- a/internal/headers/hcs/types.go +++ b/internal/headers/hcs/types.go @@ -46,7 +46,7 @@ type Properties struct { type ProcessDetails struct { ProcessId int32 `json:"ProcessId,omitempty"` ImageName string `json:"ImageName,omitempty"` - CreateTimestamp time.Time `json:"CreateTimestamp,omitempty"` + CreateTimestamp time.Time `json:"CreateTimestamp"` UserTime100ns int32 `json:"UserTime100ns,omitempty"` KernelTime100ns int32 `json:"KernelTime100ns,omitempty"` MemoryCommitBytes int32 `json:"MemoryCommitBytes,omitempty"` @@ -55,8 +55,8 @@ type ProcessDetails struct { } type Statistics struct { - Timestamp time.Time `json:"Timestamp,omitempty"` - ContainerStartTime time.Time `json:"ContainerStartTime,omitempty"` + Timestamp time.Time `json:"Timestamp"` + ContainerStartTime time.Time `json:"ContainerStartTime"` Uptime100ns uint64 `json:"Uptime100ns,omitempty"` Processor *ProcessorStats `json:"Processor,omitempty"` Memory *MemoryStats `json:"Memory,omitempty"` diff --git a/internal/headers/schedule_service/schedule_service.go b/internal/headers/schedule_service/schedule_service.go index 666b76ec..60123ce0 100644 --- a/internal/headers/schedule_service/schedule_service.go +++ b/internal/headers/schedule_service/schedule_service.go @@ -42,6 +42,7 @@ func (s *ScheduleService) Connect() error { // Otherwise, attempting to initialize and run parallel queries across // goroutines will result in protected memory errors. runtime.LockOSThread() + defer runtime.UnlockOSThread() if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil { diff --git a/internal/pdh/collector.go b/internal/pdh/collector.go index ef7e639b..29f3b5a9 100644 --- a/internal/pdh/collector.go +++ b/internal/pdh/collector.go @@ -110,7 +110,7 @@ func NewCollectorWithReflection(logger *slog.Logger, resultType CounterType, obj } if f, ok := valueType.FieldByName("MetricType"); ok { - if f.Type.Kind() == reflect.TypeOf(prometheus.ValueType(0)).Kind() { + if f.Type.Kind() == reflect.TypeFor[prometheus.ValueType]().Kind() { collector.metricsTypeIndexValue = f.Index[0] } } diff --git a/internal/pdh/registry/collector.go b/internal/pdh/registry/collector.go index dcbb7f4f..a868e977 100644 --- a/internal/pdh/registry/collector.go +++ b/internal/pdh/registry/collector.go @@ -53,9 +53,7 @@ func NewCollector[T any](object string, _ []string) (*Collector, error) { counters: make(map[string]Counter), } - var values [0]T - - valueType := reflect.TypeOf(values).Elem() + valueType := reflect.TypeFor[T]().Elem() if f, ok := valueType.FieldByName("Name"); ok { if f.Type.Kind() == reflect.String { @@ -81,9 +79,7 @@ func NewCollector[T any](object string, _ []string) (*Collector, error) { } } - if strings.HasSuffix(counterName, ",secondvalue") { - counterName = strings.TrimSuffix(counterName, ",secondvalue") - + if counterName, ok = strings.CutSuffix(counterName, ",secondvalue"); ok { counter.FieldIndexSecondValue = f.Index[0] } else { counter.FieldIndexValue = f.Index[0] diff --git a/internal/utils/testutils/testutils.go b/internal/utils/testutils/testutils.go index 6408299f..c2779546 100644 --- a/internal/utils/testutils/testutils.go +++ b/internal/utils/testutils/testutils.go @@ -64,7 +64,7 @@ func FuncBenchmarkCollector[C collector.Collector](b *testing.B, name string, co } } -func TestCollector[C collector.Collector, V interface{}](t *testing.T, fn func(*V) C, conf *V) { +func TestCollector[C collector.Collector, V any](t *testing.T, fn func(*V) C, conf *V) { t.Helper() var ( @@ -89,15 +89,11 @@ func TestCollector[C collector.Collector, V interface{}](t *testing.T, fn func(* }) wg := sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - + wg.Go(func() { for metric := range ch { metrics = append(metrics, metric) } - }() + }) err = c.Build(logger, miSession)