Skip to content

Conversation

@dricross
Copy link
Contributor

@dricross dricross commented Sep 5, 2025

Description of the issue

Check lint is failing on PRs:

Failed executing command with error: can't load config: the Go language version (go1.24) used to build golangci-lint is lower than the targeted Go version (1.25.0)

We recently bumped to go1.25 but apparently that PR skipped the lint check so it didn't catch this incompatibility 🫠 We have to upgrade from v1.64.2 all the way to v2.4.0 since that's when go1.25 support was added, which incurred some new linting rules.

The upgrade from v1.x to v2.x comes with a new format for the .golangci-lint.yml file. Migrated to v2 format using the following command:

% golangci-lint migrate --skip-validation
WARN The configuration comments are not migrated. 
WARN Details about the migration: https://golangci-lint.run/docs/product/migration-guide/ 
WARN The configuration `run.timeout` is ignored. By default, in v2, the timeout is disabled. 

Output of make lint after upgrading and migrating:

% make lint
#Install from source for golangci-lint is not recommended based on https://golangci-lint.run/usage/install/#install-from-source so using binary
#installation
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b /local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools v2.4.0
golangci/golangci-lint info checking GitHub for tag 'v2.4.0'
golangci/golangci-lint info found version: 2.4.0 for v2.4.0/linux/amd64
golangci/golangci-lint info installed /local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools/golangci-lint
# Using 04bfe4e to get SPDX template changes that are not present in the most recent tag v1.0.0
# This is required to be able to easily omit the year in our license header.
GOBIN=/local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools go install github.com/google/addlicense@04bfe4e
Check License finished successfully
GOBIN=/local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools go install github.com/pavius/impi/cmd/[email protected]
go: finding module for package github.com/kisielk/gotool
go: found github.com/kisielk/gotool in github.com/kisielk/gotool v1.0.0
# Skip plugins/plugins.go
Check import order/grouping finished
/local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools/golangci-lint run ./...
internal/k8sCommon/k8sclient/kubernetes_utils.go:86:9: QF1008: could remove embedded field "ObjectMeta" from selector (staticcheck)
        if pod.ObjectMeta.OwnerReferences != nil {
               ^
internal/k8sCommon/k8sclient/kubernetes_utils.go:87:32: QF1008: could remove embedded field "ObjectMeta" from selector (staticcheck)
                for _, ownerRef := range pod.ObjectMeta.OwnerReferences {
                                             ^
internal/k8sCommon/k8sclient/kubernetes_utils.go:92:4: QF1003: could use tagged switch on ownerRef.Kind (staticcheck)
                        if ownerRef.Kind == "ReplicaSet" {
                        ^
internal/k8sCommon/k8sclient/kubernetes_utils_test.go:207:6: QF1008: could remove embedded field "ObjectMeta" from selector (staticcheck)
        pod.ObjectMeta.OwnerReferences = nil
            ^
internal/state/range.go:385:3: QF1003: could use tagged switch on count (staticcheck)
                if count == 0 {
                ^
plugins/inputs/logfile/tail/tail.go:426:22: ST1005: error strings should not be capitalized (staticcheck)
                                lineObject.Err = errors.New(msg)
                                                 ^
plugins/inputs/prometheus/start.go:39:2: ST1019(related information): other import of "github.com/prometheus/prometheus/config" (staticcheck)
        promconfig "github.com/prometheus/prometheus/config"
        ^
plugins/outputs/cloudwatch/cloudwatch.go:486:42: QF1008: could remove embedded field "MetricDatum" from selector (staticcheck)
                        if index == 0 && c.IsDropping(*metric.MetricDatum.MetricName) {
                                                              ^
plugins/outputs/cloudwatch/cloudwatch.go:558:42: QF1008: could remove embedded field "MetricDatum" from selector (staticcheck)
                        if index == 0 && c.IsDropping(*metric.MetricDatum.MetricName) {
                                                              ^
plugins/processors/ec2tagger/ec2tagger.go:357:9: QF1008: could remove embedded field "Config" from selector (staticcheck)
                        if t.Config.MiddlewareID != nil {
                             ^
plugins/processors/ec2tagger/ec2tagger.go:358:51: QF1008: could remove embedded field "Config" from selector (staticcheck)
                                awsmiddleware.TryConfigure(t.logger, host, *t.Config.MiddlewareID, awsmiddleware.SDKv1(&client.Handlers))
                                                                              ^
plugins/processors/ec2tagger/ec2tagger.go:387:17: QF1001: could apply De Morgan's law (staticcheck)
                needRefresh = !(len(t.EC2InstanceTagKeys) == 1 && t.EC2InstanceTagKeys[0] == "*")
                              ^
plugins/processors/ec2tagger/ec2tagger.go:412:17: QF1001: could apply De Morgan's law (staticcheck)
                needRefresh = !(len(t.EBSDeviceKeys) == 1 && t.EBSDeviceKeys[0] == "*")
                              ^
receiver/awsnvmereceiver/scraper.go:188:28: QF1008: could remove embedded field "TelemetrySettings" from selector (staticcheck)
                logger:         settings.TelemetrySettings.Logger,
                                         ^
receiver/awsnvmereceiver/scraper.go:201:24: QF1008: could remove embedded field "MetricsBuilderConfig" from selector (staticcheck)
                if ts.IsEnabled(&cfg.MetricsBuilderConfig.Metrics) {
                                     ^
receiver/awsnvmereceiver/scraper_test.go:64:11: QF1008: could remove embedded field "TelemetrySettings" from selector (staticcheck)
        settings.TelemetrySettings.Logger = logger
                 ^
receiver/awsnvmereceiver/scraper_test.go:86:11: QF1008: could remove embedded field "TelemetrySettings" from selector (staticcheck)
        settings.TelemetrySettings.Logger = logger
                 ^
receiver/awsnvmereceiver/scraper_test.go:375:3: QF1003: could use tagged switch on devicePath (staticcheck)
                if devicePath == "/dev/nvme0n1" {
                ^
receiver/awsnvmereceiver/scraper_test.go:612:6: QF1008: could remove embedded field "MetricsBuilderConfig" from selector (staticcheck)
        cfg.MetricsBuilderConfig.Metrics.DiskioInstanceStoreTotalReadOps.Enabled = false
            ^
receiver/awsnvmereceiver/scraper_test.go:613:6: QF1008: could remove embedded field "MetricsBuilderConfig" from selector (staticcheck)
        cfg.MetricsBuilderConfig.Metrics.DiskioInstanceStoreTotalWriteOps.Enabled = false
            ^
translator/translate/otel/receiver/prometheus/translator.go:99:35: QF1008: could remove embedded field "Config" from selector (staticcheck)
                        cfg.TargetAllocator.TLSSetting.Config.CAFile = defaultTLSCaPath
                                                       ^
21 issues:
* staticcheck: 21
make: *** [lint] Error 1

Another lint error showed up after the PR check ran:

/home/runner/work/amazon-cloudwatch-agent/amazon-cloudwatch-agent/build/tools/golangci-lint run ./...
Error: translator/translate/logs/logs_collected/windows_events/ruleMaxPersistState.go:4:9: var-naming: don't use an underscore in package name (revive)
package windows_events
        ^
1 issues:
* revive: 1

More lint issues showed up after adjusting the windows_events package name:

/local/home/dricross/workplace/amazon-cloudwatch-agent/build/tools/golangci-lint run ./...
translator/translate/logs/logs_collected/windowsevents/collect_list/collectlist.go:51:1: named return "returnKey" with type "string" found (nonamedreturns)
func (c *CollectList) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) {
^
translator/translate/logs/logs_collected/windowsevents/collect_list/ruleEventFormat.go:22:1: named return "returnKey" with type "string" found (nonamedreturns)
func (r *EventFormat) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) {
^
translator/translate/logs/logs_collected/windowsevents/windows_event.go:31:1: named return "returnKey" with type "string" found (nonamedreturns)
func (w *WindowsEvent) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) {
^
translator/translate/logs/logs_collected/windowsevents/collect_list/collectlist.go:94:6: var-naming: func addFixedJsonConfig should be addFixedJSONConfig (revive)
func addFixedJsonConfig(result map[string]interface{}) {
     ^
translator/translate/logs/logs_collected/windowsevents/ruleFileStateFolder.go:12:37: unused-parameter: parameter 'input' seems to be unused, consider removing or renaming it as _ (revive)
func (f *FileStateFolder) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) {
                                    ^
translator/translate/logs/logs_collected/windowsevents/windows_event.go:48:9: indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive)
        } else {
                translator.AddInfoMessages("", "No windows event log configuration found.")
                return "", '"'
        }
translator/translate/logs/logs_collected/windowsevents/windows_event_test.go:18:6: var-naming: var rawJsonString should be rawJSONString (revive)
        var rawJsonString = `
            ^
translator/translate/logs/logs_collected/windowsevents/collect_list/collectlist.go:38:5: var eventLevelMapping is unused (unused)
var eventLevelMapping = map[string]string{
    ^
8 issues:
* nonamedreturns: 3
* revive: 4
* unused: 1

Description of changes

  • Bump linter to be compatible with go1.25
  • Apply linting fixes
  • Add go.mod and Makefile to linting file filters. If we bump the Go version or the linter version, this will make the lint check step run

License

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Tests

  • make lint

Requirements

Before commiting your code, please do the following steps.

  1. Run make fmt and make fmt-sh
  2. Run make lint

Integration Tests

To run integration tests against this PR, add the ready for testing label.

@dricross dricross marked this pull request as ready for review September 5, 2025 14:39
@dricross dricross requested a review from a team as a code owner September 5, 2025 14:39
the-mann
the-mann previously approved these changes Sep 5, 2025
Copy link
Contributor

@the-mann the-mann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you!!

Comment on lines -61 to -65
# Package name based on field in JSON
- path: 'translator/translate/logs/logs_collected/windows_events'
text: "var-naming: don't use an underscore in package name"
linters:
- revive
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realize this exception was in the original config and wasn't moved in the migration until after I fixed it.

#Install from source for golangci-lint is not recommended based on https://golangci-lint.run/usage/install/#install-from-source so using binary
#installation
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLS_BIN_DIR) v1.64.2
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(TOOLS_BIN_DIR) v2.4.0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

master -> HEAD more closely aligns with recommendation: https://golangci-lint.run/docs/welcome/install/#binaries

"github.com/prometheus/common/promslog"
"github.com/prometheus/common/version"
"github.com/prometheus/prometheus/config"
promconfig "github.com/prometheus/prometheus/config"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already imported in the preceding line

Comment on lines -387 to +396
//When the specified key is "*", there is no way for us to check if all
//tags are fetched. So there is no need to do refresh in this case.
needRefresh = !(len(t.EC2InstanceTagKeys) == 1 && t.EC2InstanceTagKeys[0] == "*")
needRefresh = len(t.EC2InstanceTagKeys) != 1 || t.EC2InstanceTagKeys[0] != "*"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check my De Morgan's application. Feels like something that's easy to mess up.

@@ -35,20 +35,13 @@ type CollectList struct {
}

var customizedJSONConfigKeys = []string{"event_name", EventLevelsKey}
var eventLevelMapping = map[string]string{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused var

@dricross
Copy link
Contributor Author

dricross commented Sep 5, 2025

Ran into too many issues with various linting issues and flaky unit tests to solve reasonably quickly. Ended up reverting the Go bump: #1851. When we re-do the Go bump we'll look into these.

@dricross dricross closed this Sep 5, 2025
@the-mann the-mann reopened this Dec 11, 2025
dricross and others added 10 commits December 11, 2025 17:37
Add Linux build constraint to constants.go to match the build constraints
of the files that use these constants. The constants are only used in
Linux-specific code (metrics_unix.go and util_unix.go), so they should
only be compiled on Linux systems.

This resolves the 'unused' linter warnings that occurred when running
golangci-lint on non-Linux systems.
Replace the Linux build constraint with specific nolint:unused comments
for each constant. This approach:
- Keeps constants available across all platforms
- Suppresses false positive unused warnings from golangci-lint
- Is more explicit about why the linter warnings are being ignored
- Maintains better code clarity with explanatory comments

The constants are used in Linux-specific files (metrics_unix.go and
util_unix.go) but appear unused when linting on other platforms.
Revert the test changes that replaced assert.InDelta with assert.Equal.
The original code correctly used InDelta with epsilon tolerance for
floating-point comparisons, which is necessary when dealing with
mathematical calculations that may have small precision differences
across Go versions or platforms.

The assert.Equal change was causing test failures due to tiny precision
differences in floating-point calculations (e.g., 13.656854249492378 vs
13.65685424949238). Using InDelta with appropriate epsilon tolerance
is the correct approach for floating-point test assertions.
- Reset go.mod to main branch baseline
- Update Go version from 1.24.9 to 1.25.5
- Run go mod tidy to update dependencies
- Maintains all previous linting fixes for nvme constants
- Fix package naming issues with nolint comments for existing packages
- Apply De Morgan's law optimizations in kafkabroker extract
- Fix error string capitalization and punctuation issues
- Remove duplicate import in downloader
- Replace strings.Replace with strings.ReplaceAll for efficiency

All 13 linting issues from golangci-lint v2.4.0 are now resolved.
Add nolint:revive comments to all files in internal/detector/util package:
- process.go
- util.go
- scan.go
- process_test.go
- scan_test.go

This addresses the CI/CD linting issue that wasn't caught locally due to
golangci-lint file discovery inconsistencies.
- Add exclusions for meaningless package names and naming conventions
- Remove nolint comments in favor of proper exclusions
- Fix TlsKey -> TLSKey naming convention
- Remove duplicate TLSKey constant definition
- Apply gofmt formatting

All linting issues are now resolved with proper exclusions rather than suppressions.
- Restored nolint:revive comments for package naming issues
- Restored nolint:revive comments for constant naming issues
- Removed golangci-lint exclusions added in this branch
- Applied gofmt formatting
- Keep TLSKey naming fix and duplicate constant removal

All linting issues suppressed with inline nolint comments.
@the-mann the-mann added the ready for testing Indicates this PR is ready for integration tests to run label Dec 12, 2025
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
return fmt.Errorf("E! %s process exited with non-zero status: %d", command, exitErr.ExitCode())
return fmt.Errorf("e! %s process exited with non-zero status: %d", command, exitErr.ExitCode())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we use the E! in a lot more places in the code - so Id keep it as is for now for consistency.

Copy link
Contributor

@the-mann the-mann Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, not sure why the linter changed this one. i'll find which rule changed this and disable it

- Restore uppercase E! in cmdwrapper.go for consistency with codebase
- Add global exclusion for ST1005 staticcheck rule to preserve established error logging convention
- Remove need for individual nolint comments throughout codebase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for testing Indicates this PR is ready for integration tests to run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants