diff --git a/NOTICE.txt b/NOTICE.txt
index 76189f17cce..c40525550dc 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -20797,37 +20797,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------------
-Dependency : github.com/joeshaw/multierror
-Version: v0.0.0-20140124173710-69b34d4ec901
-Licence type (autodetected): MIT
---------------------------------------------------------------------------------
-
-Contents of probable licence file $GOMODCACHE/github.com/joeshaw/multierror@v0.0.0-20140124173710-69b34d4ec901/LICENSE:
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Joe Shaw
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-
--------------------------------------------------------------------------------
Dependency : github.com/jonboulle/clockwork
Version: v0.2.2
diff --git a/auditbeat/helper/hasher/hasher.go b/auditbeat/helper/hasher/hasher.go
index d0612ab731d..7eac11b264c 100644
--- a/auditbeat/helper/hasher/hasher.go
+++ b/auditbeat/helper/hasher/hasher.go
@@ -23,6 +23,7 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
+ "errors"
"fmt"
"hash"
"io"
@@ -32,7 +33,6 @@ import (
"github.com/cespare/xxhash/v2"
"github.com/dustin/go-humanize"
- "github.com/joeshaw/multierror"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/sha3"
"golang.org/x/time/rate"
@@ -138,7 +138,7 @@ type Config struct {
// Validate validates the config.
func (c *Config) Validate() error {
- var errs multierror.Errors
+ var errs []error
for _, ht := range c.HashTypes {
if !ht.IsValid() {
@@ -160,7 +160,7 @@ func (c *Config) Validate() error {
errs = append(errs, fmt.Errorf("invalid scan_rate_per_sec value: %w", err))
}
- return errs.Err()
+ return errors.Join(errs...)
}
// FileHasher hashes the contents of files.
diff --git a/auditbeat/module/auditd/config.go b/auditbeat/module/auditd/config.go
index 6762a3924a9..32ca4413528 100644
--- a/auditbeat/module/auditd/config.go
+++ b/auditbeat/module/auditd/config.go
@@ -22,6 +22,7 @@ package auditd
import (
"bufio"
"bytes"
+ "errors"
"fmt"
"io"
"os"
@@ -30,8 +31,6 @@ import (
"strings"
"time"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/go-libaudit/v2/rule"
"github.com/elastic/go-libaudit/v2/rule/flags"
@@ -93,7 +92,7 @@ var defaultConfig = Config{
// Validate validates the rules specified in the config.
func (c *Config) Validate() error {
- var errs multierror.Errors
+ var errs []error
err := c.loadRules()
if err != nil {
errs = append(errs, err)
@@ -115,7 +114,7 @@ func (c *Config) Validate() error {
"'%v' (use unicast, multicast, or don't set a value)", c.SocketType))
}
- return errs.Err()
+ return errors.Join(errs...)
}
// Rules returns a list of rules specified in the config.
@@ -191,7 +190,7 @@ func (c Config) failureMode() (uint32, error) {
// errors will be logged as warnings and any successfully parsed rules will be
// returned.
func readRules(reader io.Reader, source string, knownRules ruleSet, log *logp.Logger) (rules []auditRule, err error) {
- var errs multierror.Errors
+ var errs []error
s := bufio.NewScanner(reader)
for lineNum := 1; s.Scan(); lineNum++ {
@@ -229,9 +228,9 @@ func readRules(reader io.Reader, source string, knownRules ruleSet, log *logp.Lo
if len(errs) != 0 {
if log == nil {
- return nil, fmt.Errorf("failed loading rules: %w", errs.Err())
+ return nil, fmt.Errorf("failed loading rules: %w", errors.Join(errs...))
}
- log.Warnf("errors loading rules: %v", errs.Err())
+ log.Warnf("errors loading rules: %v", errors.Join(errs...))
}
return rules, nil
}
diff --git a/auditbeat/module/file_integrity/config.go b/auditbeat/module/file_integrity/config.go
index db934b02789..182463ebdd4 100644
--- a/auditbeat/module/file_integrity/config.go
+++ b/auditbeat/module/file_integrity/config.go
@@ -28,7 +28,6 @@ import (
"strings"
"github.com/dustin/go-humanize"
- "github.com/joeshaw/multierror"
"github.com/elastic/beats/v7/libbeat/common/match"
)
@@ -131,7 +130,7 @@ func (c *Config) Validate() error {
sort.Strings(c.Paths)
c.Paths = deduplicate(c.Paths)
- var errs multierror.Errors
+ var errs []error
var err error
nextHash:
@@ -187,7 +186,7 @@ nextHash:
errs = append(errs, errors.New("backend can only be specified on linux"))
}
- return errs.Err()
+ return errors.Join(errs...)
}
// deduplicate deduplicates the given sorted string slice. The returned slice
diff --git a/auditbeat/module/file_integrity/config_test.go b/auditbeat/module/file_integrity/config_test.go
index 6104a01cfb8..725c73eac00 100644
--- a/auditbeat/module/file_integrity/config_test.go
+++ b/auditbeat/module/file_integrity/config_test.go
@@ -24,7 +24,6 @@ import (
"regexp/syntax"
"testing"
- "github.com/joeshaw/multierror"
"github.com/stretchr/testify/assert"
conf "github.com/elastic/elastic-agent-libs/config"
@@ -85,11 +84,13 @@ func TestConfigInvalid(t *testing.T) {
t.Fatal("expected ucfg.Error")
}
- merr, ok := ucfgErr.Reason().(*multierror.MultiError)
+ merr, ok := ucfgErr.Reason().(interface {
+ Unwrap() []error
+ })
if !ok {
- t.Fatal("expected MultiError")
+ t.Fatal("expected slice error unwrapper")
}
- assert.Len(t, merr.Errors, 4)
+ assert.Len(t, merr.Unwrap(), 4)
config, err = conf.NewConfigFrom(map[string]interface{}{
"paths": []string{"/usr/bin"},
diff --git a/auditbeat/module/file_integrity/fileinfo_posix.go b/auditbeat/module/file_integrity/fileinfo_posix.go
index d87c8fc4e20..dd654a20e89 100644
--- a/auditbeat/module/file_integrity/fileinfo_posix.go
+++ b/auditbeat/module/file_integrity/fileinfo_posix.go
@@ -21,13 +21,13 @@ package file_integrity
import (
"bytes"
+ "errors"
"fmt"
"os"
"os/user"
"strconv"
"syscall"
- "github.com/joeshaw/multierror"
"github.com/pkg/xattr"
)
@@ -61,7 +61,7 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) {
}
// Lookup UID and GID
- var errs multierror.Errors
+ var errs []error
owner, err := user.LookupId(strconv.Itoa(int(fileInfo.UID)))
if err != nil {
errs = append(errs, err)
@@ -81,7 +81,7 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) {
errs = append(errs, err)
}
- return fileInfo, errs.Err()
+ return fileInfo, errors.Join(errs...)
}
func fillExtendedAttributes(md *Metadata, path string) {
diff --git a/auditbeat/module/file_integrity/fileinfo_windows.go b/auditbeat/module/file_integrity/fileinfo_windows.go
index 0ab8055b5fb..8f8caec8b40 100644
--- a/auditbeat/module/file_integrity/fileinfo_windows.go
+++ b/auditbeat/module/file_integrity/fileinfo_windows.go
@@ -20,14 +20,13 @@
package file_integrity
import (
+ "errors"
"fmt"
"os"
"syscall"
"time"
"unsafe"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/common/file"
)
@@ -40,12 +39,12 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) {
return nil, fmt.Errorf("unexpected fileinfo sys type %T for %v", info.Sys(), path)
}
- var errs multierror.Errors
+ var errs []error
state := file.GetOSState(info)
fileInfo := &Metadata{
- Inode: uint64(state.IdxHi<<32 + state.IdxLo),
+ Inode: state.IdxHi<<32 + state.IdxLo,
Mode: info.Mode(),
Size: uint64(info.Size()),
MTime: time.Unix(0, attrs.LastWriteTime.Nanoseconds()).UTC(),
@@ -73,7 +72,7 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) {
if fileInfo.Origin, err = GetFileOrigin(path); err != nil {
errs = append(errs, fmt.Errorf("GetFileOrigin failed: %w", err))
}
- return fileInfo, errs.Err()
+ return fileInfo, errors.Join(errs...)
}
// fileOwner returns the SID and name (domain\user) of the file's owner.
@@ -89,10 +88,11 @@ func fileOwner(path string) (sid, owner string, err error) {
OwnerSecurityInformation, &securityID, nil, nil, nil, &securityDescriptor); err != nil {
return "", "", fmt.Errorf("failed on GetSecurityInfo for %v: %w", path, err)
}
+ //nolint:errcheck // ignore
defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(securityDescriptor)))
// Convert SID to a string and lookup the username.
- var errs multierror.Errors
+ var errs []error
sid, err = securityID.String()
if err != nil {
errs = append(errs, err)
@@ -105,5 +105,5 @@ func fileOwner(path string) (sid, owner string, err error) {
owner = fmt.Sprintf(`%s\%s`, domain, account)
}
- return sid, owner, errs.Err()
+ return sid, owner, errors.Join(errs...)
}
diff --git a/auditbeat/module/file_integrity/monitor/recursive.go b/auditbeat/module/file_integrity/monitor/recursive.go
index 6cdb98f8464..aac80af46ad 100644
--- a/auditbeat/module/file_integrity/monitor/recursive.go
+++ b/auditbeat/module/file_integrity/monitor/recursive.go
@@ -18,12 +18,12 @@
package monitor
import (
+ "errors"
"fmt"
"os"
"path/filepath"
"github.com/fsnotify/fsnotify"
- "github.com/joeshaw/multierror"
"github.com/elastic/elastic-agent-libs/logp"
)
@@ -113,7 +113,7 @@ func (watcher *recursiveWatcher) addRecursive(path string) error {
return nil
}
- var errs multierror.Errors
+ var errs []error
if err := watcher.watchFile(path, nil); err != nil {
errs = append(errs, fmt.Errorf("failed adding watcher to '%s': %w", path, err))
}
@@ -147,7 +147,7 @@ func (watcher *recursiveWatcher) addRecursive(path string) error {
if err != nil {
errs = append(errs, fmt.Errorf("failed to walk path '%s': %w", path, err))
}
- return errs.Err()
+ return errors.Join(errs...)
}
func (watcher *recursiveWatcher) close() error {
diff --git a/auditbeat/tracing/perfevent.go b/auditbeat/tracing/perfevent.go
index 36f595aa676..0aae609a01f 100644
--- a/auditbeat/tracing/perfevent.go
+++ b/auditbeat/tracing/perfevent.go
@@ -29,7 +29,6 @@ import (
"time"
"unsafe"
- "github.com/joeshaw/multierror"
"golang.org/x/sys/unix"
"github.com/elastic/go-perf"
@@ -336,7 +335,7 @@ func (c *PerfChannel) Close() error {
defer close(c.errC)
defer close(c.lostC)
}
- var errs multierror.Errors
+ var errs []error
for _, ev := range c.events {
if err := ev.Disable(); err != nil {
errs = append(errs, fmt.Errorf("failed to disable event channel: %w", err))
@@ -345,7 +344,7 @@ func (c *PerfChannel) Close() error {
errs = append(errs, fmt.Errorf("failed to close event channel: %w", err))
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// doneWrapperContext is a custom context.Context that is tailored to
diff --git a/auditbeat/tracing/tracefs.go b/auditbeat/tracing/tracefs.go
index 532eb75ca45..77ed5600293 100644
--- a/auditbeat/tracing/tracefs.go
+++ b/auditbeat/tracing/tracefs.go
@@ -21,14 +21,13 @@ package tracing
import (
"bufio"
+ "errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
-
- "github.com/joeshaw/multierror"
)
const (
@@ -53,7 +52,7 @@ type TraceFS struct {
// It autodetects a tracefs mounted on /sys/kernel/tracing or via
// debugfs at /sys/kernel/debug/tracing.
func NewTraceFS() (*TraceFS, error) {
- var errs multierror.Errors
+ var errs []error
ptr, err := NewTraceFSWithPath(traceFSPath)
if err != nil {
errs = append(errs, err)
@@ -64,7 +63,7 @@ func NewTraceFS() (*TraceFS, error) {
errs = nil
}
}
- return ptr, errs.Err()
+ return ptr, errors.Join(errs...)
}
// NewTraceFSWithPath creates a new accessor for the event tracing feature
diff --git a/dev-tools/mage/integtest.go b/dev-tools/mage/integtest.go
index 0b881a21e49..323853a1691 100644
--- a/dev-tools/mage/integtest.go
+++ b/dev-tools/mage/integtest.go
@@ -24,7 +24,6 @@ import (
"path/filepath"
"strconv"
- "github.com/joeshaw/multierror"
"github.com/magefile/mage/mg"
)
@@ -115,7 +114,7 @@ func (steps IntegrationTestSteps) Teardown(env map[string]string) error {
}
func (steps IntegrationTestSteps) teardownFrom(start int, env map[string]string) error {
- var errs multierror.Errors
+ var errs []error
for i := start; i >= 0; i-- {
if mg.Verbose() {
fmt.Printf("Teardown %s...\n", steps[i].Name())
@@ -124,7 +123,7 @@ func (steps IntegrationTestSteps) teardownFrom(start int, env map[string]string)
errs = append(errs, fmt.Errorf("%s teardown failed: %w", steps[i].Name(), err))
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// IntegrationTester is interface used by the actual test runner.
@@ -287,7 +286,9 @@ func (r *IntegrationRunner) Test(mageTarget string, test func() error) (err erro
inTeardown := false
defer func() {
if recoverErr := recover(); recoverErr != nil {
- err = recoverErr.(error)
+ if rerr, ok := recoverErr.(error); ok {
+ err = rerr
+ }
if !inTeardown {
// ignore errors
_ = r.steps.Teardown(r.env)
@@ -317,13 +318,13 @@ func (r *IntegrationRunner) Test(mageTarget string, test func() error) (err erro
// Test runs the test on each runner and collects the errors.
func (r IntegrationRunners) Test(mageTarget string, test func() error) error {
- var errs multierror.Errors
+ var errs []error
for _, runner := range r {
if err := runner.Test(mageTarget, test); err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func passThroughEnvs(env map[string]string, passthrough ...string) {
diff --git a/dev-tools/mage/modules.go b/dev-tools/mage/modules.go
index 14b7f7ab118..b41c68d6201 100644
--- a/dev-tools/mage/modules.go
+++ b/dev-tools/mage/modules.go
@@ -18,13 +18,12 @@
package mage
import (
+ "errors"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"strings"
- "github.com/joeshaw/multierror"
"gopkg.in/yaml.v2"
)
@@ -54,7 +53,7 @@ func GenerateDirModulesD() error {
}
moduleName := parts[1]
- config, err := ioutil.ReadFile(f)
+ config, err := os.ReadFile(f)
if err != nil {
return err
}
@@ -68,7 +67,7 @@ func GenerateDirModulesD() error {
}
target := filepath.Join("modules.d", moduleName+".yml.disabled")
- err = ioutil.WriteFile(createDir(target), []byte(data), 0644)
+ err = os.WriteFile(createDir(target), []byte(data), 0644)
if err != nil {
return err
}
@@ -100,7 +99,7 @@ func ValidateDirModulesDDatasetsDisabled() error {
if err != nil {
return err
}
- var errs multierror.Errors
+ var errs []error
for path, cfg := range cfgs {
// A config.yml is a list of module configurations.
for modIdx, mod := range cfg {
@@ -118,7 +117,7 @@ func ValidateDirModulesDDatasetsDisabled() error {
}
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func loadModulesD() (modules map[string][]moduleDefinition, err error) {
@@ -128,7 +127,7 @@ func loadModulesD() (modules map[string][]moduleDefinition, err error) {
}
modules = make(map[string][]moduleDefinition, len(files))
for _, file := range files {
- contents, err := ioutil.ReadFile(file)
+ contents, err := os.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("reading %s: %w", file, err)
}
diff --git a/filebeat/fileset/pipelines.go b/filebeat/fileset/pipelines.go
index c58a7c13edc..434ec8e7137 100644
--- a/filebeat/fileset/pipelines.go
+++ b/filebeat/fileset/pipelines.go
@@ -19,11 +19,10 @@ package fileset
import (
"encoding/json"
+ "errors"
"fmt"
"strings"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/version"
)
@@ -100,14 +99,14 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool
// Rollback pipelines and return errors
// TODO: Instead of attempting to load all pipelines and then rolling back loaded ones when there's an
// error, validate all pipelines before loading any of them. This requires https://github.com/elastic/elasticsearch/issues/35495.
- errs := multierror.Errors{err}
+ errs := []error{err}
for _, pipelineID := range pipelineIDsLoaded {
err = DeletePipeline(esClient, pipelineID)
if err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
}
}
diff --git a/go.mod b/go.mod
index 3e2fe304b67..c9fd7c5aa3f 100644
--- a/go.mod
+++ b/go.mod
@@ -100,7 +100,6 @@ require (
github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3
github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95
github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd
- github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
github.com/jonboulle/clockwork v0.2.2
github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd
github.com/jpillora/backoff v1.0.0 // indirect
diff --git a/go.sum b/go.sum
index ba2722f5baa..7817e64e754 100644
--- a/go.sum
+++ b/go.sum
@@ -640,8 +640,6 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
-github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
diff --git a/libbeat/cfgfile/list.go b/libbeat/cfgfile/list.go
index 3a9e3429d29..3def249856d 100644
--- a/libbeat/cfgfile/list.go
+++ b/libbeat/cfgfile/list.go
@@ -22,7 +22,6 @@ import (
"fmt"
"sync"
- "github.com/joeshaw/multierror"
"github.com/mitchellh/hashstructure"
"github.com/elastic/beats/v7/libbeat/beat"
@@ -85,7 +84,7 @@ func (r *RunnerList) Reload(configs []*reload.ConfigWithMeta) error {
r.mutex.Lock()
defer r.mutex.Unlock()
- var errs multierror.Errors
+ var errs []error
startList := map[uint64]*reload.ConfigWithMeta{}
stopList := r.copyRunnerList()
@@ -179,7 +178,7 @@ func (r *RunnerList) Reload(configs []*reload.ConfigWithMeta) error {
// above it is done asynchronously.
moduleRunning.Set(int64(len(r.runners)))
- return errs.Err()
+ return errors.Join(errs...)
}
// Stop all runners
diff --git a/libbeat/cfgfile/reload.go b/libbeat/cfgfile/reload.go
index 930bd56eafd..ee3f0d58fac 100644
--- a/libbeat/cfgfile/reload.go
+++ b/libbeat/cfgfile/reload.go
@@ -18,13 +18,12 @@
package cfgfile
import (
+ "errors"
"fmt"
"path/filepath"
"sync"
"time"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common/reload"
"github.com/elastic/elastic-agent-libs/config"
@@ -262,7 +261,7 @@ func (rl *Reloader) Load(runnerFactory RunnerFactory) {
func (rl *Reloader) loadConfigs(files []string) ([]*reload.ConfigWithMeta, error) {
// Load all config objects
result := []*reload.ConfigWithMeta{}
- var errs multierror.Errors
+ var errs []error
for _, file := range files {
configs, err := LoadList(file)
if err != nil {
@@ -276,7 +275,7 @@ func (rl *Reloader) loadConfigs(files []string) ([]*reload.ConfigWithMeta, error
}
}
- return result, errs.Err()
+ return result, errors.Join(errs...)
}
// Stop stops the reloader and waits for all modules to properly stop
diff --git a/libbeat/common/cfgwarn/removed.go b/libbeat/common/cfgwarn/removed.go
index 84144c8d984..3de5754cd49 100644
--- a/libbeat/common/cfgwarn/removed.go
+++ b/libbeat/common/cfgwarn/removed.go
@@ -18,23 +18,22 @@
package cfgwarn
import (
+ "errors"
"fmt"
"strings"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/elastic-agent-libs/config"
)
func checkRemovedSettings(cfg *config.C, settings ...string) error {
- var errs multierror.Errors
+ var errs []error
for _, setting := range settings {
if err := checkRemovedSetting(cfg, setting); err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func checkRemovedSetting(cfg *config.C, setting string) error {
diff --git a/libbeat/common/cfgwarn/removed_test.go b/libbeat/common/cfgwarn/removed_test.go
index 50ebb6eefd0..8e0c674c355 100644
--- a/libbeat/common/cfgwarn/removed_test.go
+++ b/libbeat/common/cfgwarn/removed_test.go
@@ -21,7 +21,6 @@ import (
"errors"
"testing"
- "github.com/joeshaw/multierror"
"github.com/stretchr/testify/assert"
"github.com/elastic/elastic-agent-libs/config"
@@ -93,7 +92,7 @@ func TestRemovedSettings(t *testing.T) {
cfg: config.MustNewConfigFrom(map[string]interface{}{
"hello.world": "ok",
}),
- expected: multierror.Errors{errors.New("setting 'hello' has been removed")}.Err(),
+ expected: errors.Join(errors.New("setting 'hello' has been removed")),
},
{
name: "multiple obsolete settings",
@@ -102,10 +101,10 @@ func TestRemovedSettings(t *testing.T) {
"hello.world": "ok",
"bad": "true",
}),
- expected: multierror.Errors{
+ expected: errors.Join(
errors.New("setting 'hello' has been removed"),
errors.New("setting 'bad' has been removed"),
- }.Err(),
+ ),
},
{
name: "multiple obsolete settings not on first level",
@@ -114,10 +113,10 @@ func TestRemovedSettings(t *testing.T) {
"filebeat.prospectors": "ok",
"filebeat.config.prospectors": map[string]interface{}{"ok": "ok1"},
}),
- expected: multierror.Errors{
+ expected: errors.Join(
errors.New("setting 'filebeat.config.prospectors' has been removed"),
errors.New("setting 'filebeat.prospectors' has been removed"),
- }.Err(),
+ ),
},
}
diff --git a/libbeat/common/schema/mapstriface/mapstriface.go b/libbeat/common/schema/mapstriface/mapstriface.go
index d06119a5bf0..508072822e8 100644
--- a/libbeat/common/schema/mapstriface/mapstriface.go
+++ b/libbeat/common/schema/mapstriface/mapstriface.go
@@ -76,8 +76,6 @@ import (
"fmt"
"time"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/schema"
"github.com/elastic/elastic-agent-libs/logp"
@@ -92,13 +90,13 @@ type ConvMap struct {
}
// Map drills down in the data dictionary by using the key
-func (convMap ConvMap) Map(key string, event mapstr.M, data map[string]interface{}) multierror.Errors {
+func (convMap ConvMap) Map(key string, event mapstr.M, data map[string]interface{}) []error {
d, err := mapstr.M(data).GetValue(convMap.Key)
if err != nil {
err := schema.NewKeyNotFoundError(convMap.Key)
err.Optional = convMap.Optional
err.Required = convMap.Required
- return multierror.Errors{err}
+ return []error{err}
}
switch subData := d.(type) {
case map[string]interface{}, mapstr.M:
@@ -116,7 +114,7 @@ func (convMap ConvMap) Map(key string, event mapstr.M, data map[string]interface
msg := fmt.Sprintf("expected dictionary, found %T", subData)
err := schema.NewWrongFormatError(convMap.Key, msg)
logp.Err("%s", err.Error())
- return multierror.Errors{err}
+ return []error{err}
}
}
diff --git a/libbeat/common/schema/mapstriface/mapstriface_test.go b/libbeat/common/schema/mapstriface/mapstriface_test.go
index a96a15ba0c8..9a357a735f7 100644
--- a/libbeat/common/schema/mapstriface/mapstriface_test.go
+++ b/libbeat/common/schema/mapstriface/mapstriface_test.go
@@ -19,6 +19,7 @@ package mapstriface
import (
"encoding/json"
+ "errors"
"testing"
"time"
@@ -244,9 +245,10 @@ func TestFullFieldPathInErrors(t *testing.T) {
}
_, errs := c.Schema.ApplyTo(mapstr.M{}, c.Input)
- assert.Error(t, errs.Err(), c.Description)
+ assert.NotEmpty(t, errs, c.Description)
if assert.Equal(t, 1, len(errs), c.Description) {
- keyErr, ok := errs[0].(s.KeyError)
+ var keyErr s.KeyError
+ ok := errors.As(errs[0], &keyErr)
if assert.True(t, ok, c.Description) {
assert.Equal(t, c.Expected, keyErr.Key(), c.Description)
}
diff --git a/libbeat/common/schema/mapstrstr/mapstrstr_test.go b/libbeat/common/schema/mapstrstr/mapstrstr_test.go
index acd77a62c6d..1d2e58c57ff 100644
--- a/libbeat/common/schema/mapstrstr/mapstrstr_test.go
+++ b/libbeat/common/schema/mapstrstr/mapstrstr_test.go
@@ -18,6 +18,7 @@
package mapstrstr
import (
+ "errors"
"testing"
"time"
@@ -124,9 +125,10 @@ func TestKeyInErrors(t *testing.T) {
}
_, errs := c.Schema.ApplyTo(mapstr.M{}, c.Input)
- assert.Error(t, errs.Err(), c.Description)
+ assert.NotEmpty(t, errs, c.Description)
if assert.Equal(t, 1, len(errs), c.Description) {
- keyErr, ok := errs[0].(s.KeyError)
+ var keyErr s.KeyError
+ ok := errors.As(errs[0], &keyErr)
if assert.True(t, ok, c.Description) {
assert.Equal(t, c.Expected, keyErr.Key(), c.Description)
}
diff --git a/libbeat/common/schema/options.go b/libbeat/common/schema/options.go
index de69b851cfc..6905c4f6b4c 100644
--- a/libbeat/common/schema/options.go
+++ b/libbeat/common/schema/options.go
@@ -18,7 +18,7 @@
package schema
import (
- "github.com/joeshaw/multierror"
+ "errors"
"github.com/elastic/elastic-agent-libs/mapstr"
)
@@ -27,50 +27,53 @@ import (
var DefaultApplyOptions = []ApplyOption{AllRequired}
// ApplyOption modifies the result of Apply
-type ApplyOption func(mapstr.M, multierror.Errors) (mapstr.M, multierror.Errors)
+type ApplyOption func(mapstr.M, []error) (mapstr.M, []error)
// AllRequired considers any missing field as an error, except if explicitly
// set as optional
-func AllRequired(event mapstr.M, errors multierror.Errors) (mapstr.M, multierror.Errors) {
+func AllRequired(event mapstr.M, errs []error) (mapstr.M, []error) {
k := 0
- for i, err := range errors {
- if err, ok := err.(*KeyNotFoundError); ok {
- if err.Optional {
+ for i, err := range errs {
+ var keyErr *KeyNotFoundError
+ if errors.As(err, &keyErr) {
+ if keyErr.Optional {
continue
}
}
- errors[k] = errors[i]
+ errs[k] = errs[i]
k++
}
- return event, errors[:k]
+ return event, errs[:k]
}
// FailOnRequired considers missing fields as an error only if they are set
// as required
-func FailOnRequired(event mapstr.M, errors multierror.Errors) (mapstr.M, multierror.Errors) {
+func FailOnRequired(event mapstr.M, errs []error) (mapstr.M, []error) {
k := 0
- for i, err := range errors {
- if err, ok := err.(*KeyNotFoundError); ok {
- if !err.Required {
+ for i, err := range errs {
+ var keyErr *KeyNotFoundError
+ if errors.As(err, &keyErr) {
+ if !keyErr.Required {
continue
}
}
- errors[k] = errors[i]
+ errs[k] = errs[i]
k++
}
- return event, errors[:k]
+ return event, errs[:k]
}
// NotFoundKeys calls a function with the list of missing keys as parameter
func NotFoundKeys(cb func(keys []string)) ApplyOption {
- return func(event mapstr.M, errors multierror.Errors) (mapstr.M, multierror.Errors) {
+ return func(event mapstr.M, errs []error) (mapstr.M, []error) {
var keys []string
- for _, err := range errors {
- if err, ok := err.(*KeyNotFoundError); ok {
- keys = append(keys, err.Key())
+ for _, err := range errs {
+ var keyErr *KeyNotFoundError
+ if errors.As(err, &keyErr) {
+ keys = append(keys, keyErr.Key())
}
}
cb(keys)
- return event, errors
+ return event, errs
}
}
diff --git a/libbeat/common/schema/options_test.go b/libbeat/common/schema/options_test.go
index 3b99117f313..2eac62dc0a9 100644
--- a/libbeat/common/schema/options_test.go
+++ b/libbeat/common/schema/options_test.go
@@ -22,7 +22,6 @@ import (
"errors"
- "github.com/joeshaw/multierror"
"github.com/stretchr/testify/assert"
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -32,19 +31,19 @@ func TestApplyOptions(t *testing.T) {
cases := []struct {
Description string
Options []ApplyOption
- Errors multierror.Errors
+ Errors []error
ExpectError bool
}{
{
"all fields required, no error",
[]ApplyOption{AllRequired},
- multierror.Errors{},
+ nil,
false,
},
{
"all fields required, an error",
[]ApplyOption{AllRequired},
- multierror.Errors{
+ []error{
NewKeyNotFoundError("foo"),
},
true,
@@ -52,7 +51,7 @@ func TestApplyOptions(t *testing.T) {
{
"all fields required, some other error, it should fail",
[]ApplyOption{AllRequired},
- multierror.Errors{
+ []error{
errors.New("something bad happened"),
},
true,
@@ -60,7 +59,7 @@ func TestApplyOptions(t *testing.T) {
{
"all fields required, an error, collecting missing keys doesn't alter result",
[]ApplyOption{NotFoundKeys(func([]string) {}), AllRequired},
- multierror.Errors{
+ []error{
NewKeyNotFoundError("foo"),
},
true,
@@ -68,7 +67,7 @@ func TestApplyOptions(t *testing.T) {
{
"fail on required, an error, not required",
[]ApplyOption{FailOnRequired},
- multierror.Errors{
+ []error{
&KeyNotFoundError{errorKey: errorKey{"foo"}, Required: false},
},
false,
@@ -76,7 +75,7 @@ func TestApplyOptions(t *testing.T) {
{
"fail on required, an error, required",
[]ApplyOption{FailOnRequired},
- multierror.Errors{
+ []error{
&KeyNotFoundError{errorKey: errorKey{"foo"}, Required: true},
},
true,
@@ -84,7 +83,7 @@ func TestApplyOptions(t *testing.T) {
{
"fail on required, some other error, it should fail",
[]ApplyOption{FailOnRequired},
- multierror.Errors{
+ []error{
errors.New("something bad happened"),
},
true,
@@ -98,9 +97,9 @@ func TestApplyOptions(t *testing.T) {
event, errors = opt(event, errors)
}
if c.ExpectError {
- assert.Error(t, errors.Err(), c.Description)
+ assert.NotEmpty(t, errors, c.Description)
} else {
- assert.NoError(t, errors.Err(), c.Description)
+ assert.Empty(t, errors, c.Description)
}
}
}
@@ -108,31 +107,31 @@ func TestApplyOptions(t *testing.T) {
func TestNotFoundKeys(t *testing.T) {
cases := []struct {
Description string
- Errors multierror.Errors
+ Errors []error
Expected []string
}{
{
"empty errors, no key",
- multierror.Errors{},
+ nil,
[]string{},
},
{
"key not found error",
- multierror.Errors{
+ []error{
NewKeyNotFoundError("foo"),
},
[]string{"foo"},
},
{
"only another error, so no key",
- multierror.Errors{
+ []error{
NewWrongFormatError("foo", ""),
},
[]string{},
},
{
"two errors, only one is key not found",
- multierror.Errors{
+ []error{
NewKeyNotFoundError("foo"),
NewWrongFormatError("bar", ""),
},
diff --git a/libbeat/common/schema/schema.go b/libbeat/common/schema/schema.go
index ad95ee64492..511fbf9dc79 100644
--- a/libbeat/common/schema/schema.go
+++ b/libbeat/common/schema/schema.go
@@ -18,7 +18,7 @@
package schema
import (
- "github.com/joeshaw/multierror"
+ "errors"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -33,7 +33,7 @@ type Schema map[string]Mapper
type Mapper interface {
// Map applies the Mapper conversion on the data and adds the result
// to the event on the key.
- Map(key string, event mapstr.M, data map[string]interface{}) multierror.Errors
+ Map(key string, event mapstr.M, data map[string]interface{}) []error
HasKey(key string) bool
}
@@ -52,18 +52,19 @@ type Converter func(key string, data map[string]interface{}) (interface{}, error
// Map applies the conversion on the data and adds the result
// to the event on the key.
-func (conv Conv) Map(key string, event mapstr.M, data map[string]interface{}) multierror.Errors {
+func (conv Conv) Map(key string, event mapstr.M, data map[string]interface{}) []error {
value, err := conv.Func(conv.Key, data)
if err != nil {
- if err, keyNotFound := err.(*KeyNotFoundError); keyNotFound {
- err.Optional = conv.Optional
- err.Required = conv.Required
+ var keyErr *KeyNotFoundError
+ if errors.As(err, &keyErr) {
+ keyErr.Optional = conv.Optional
+ keyErr.Required = conv.Required
}
if conv.IgnoreAllErrors {
logp.Debug("schema", "ignoring error for key %q: %s", key, err)
return nil
}
- return multierror.Errors{err}
+ return []error{err}
}
event[key] = value
return nil
@@ -77,7 +78,7 @@ func (conv Conv) HasKey(key string) bool {
type Object map[string]Mapper
// Map applies the schema for an object
-func (o Object) Map(key string, event mapstr.M, data map[string]interface{}) multierror.Errors {
+func (o Object) Map(key string, event mapstr.M, data map[string]interface{}) []error {
subEvent := mapstr.M{}
errs := applySchemaToEvent(subEvent, data, o)
event[key] = subEvent
@@ -90,7 +91,7 @@ func (o Object) HasKey(key string) bool {
// ApplyTo adds the fields extracted from data, converted using the schema, to the
// event map.
-func (s Schema) ApplyTo(event mapstr.M, data map[string]interface{}, opts ...ApplyOption) (mapstr.M, multierror.Errors) {
+func (s Schema) ApplyTo(event mapstr.M, data map[string]interface{}, opts ...ApplyOption) (mapstr.M, []error) {
if len(opts) == 0 {
opts = DefaultApplyOptions
}
@@ -103,8 +104,8 @@ func (s Schema) ApplyTo(event mapstr.M, data map[string]interface{}, opts ...App
// Apply converts the fields extracted from data, using the schema, into a new map and reports back the errors.
func (s Schema) Apply(data map[string]interface{}, opts ...ApplyOption) (mapstr.M, error) {
- event, errors := s.ApplyTo(mapstr.M{}, data, opts...)
- return event, errors.Err()
+ event, errs := s.ApplyTo(mapstr.M{}, data, opts...)
+ return event, errors.Join(errs...)
}
// HasKey checks if the key is part of the schema
@@ -121,11 +122,12 @@ func hasKey(key string, mappers map[string]Mapper) bool {
return false
}
-func applySchemaToEvent(event mapstr.M, data map[string]interface{}, conversions map[string]Mapper) multierror.Errors {
- var errs multierror.Errors
+func applySchemaToEvent(event mapstr.M, data map[string]interface{}, conversions map[string]Mapper) []error {
+ var errs []error
for key, mapper := range conversions {
- errors := mapper.Map(key, event, data)
- errs = append(errs, errors...)
+ if err := mapper.Map(key, event, data); err != nil {
+ errs = append(errs, err...)
+ }
}
return errs
}
diff --git a/libbeat/dashboards/kibana_loader.go b/libbeat/dashboards/kibana_loader.go
index 3320f996a2a..1062262c7f7 100644
--- a/libbeat/dashboards/kibana_loader.go
+++ b/libbeat/dashboards/kibana_loader.go
@@ -20,14 +20,13 @@ package dashboards
import (
"context"
"encoding/json"
+ "errors"
"fmt"
"net/url"
"os"
"path/filepath"
"time"
- "github.com/joeshaw/multierror"
-
beatversion "github.com/elastic/beats/v7/libbeat/version"
"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/kibana"
@@ -130,7 +129,7 @@ func (loader KibanaLoader) ImportIndex(pattern mapstr.M) error {
return fmt.Errorf("kibana version must be at least %s", minimumRequiredVersionSavedObjects.String())
}
- var errs multierror.Errors
+ var errs []error
params := url.Values{}
params.Set("overwrite", "true")
@@ -143,7 +142,7 @@ func (loader KibanaLoader) ImportIndex(pattern mapstr.M) error {
if err != nil {
errs = append(errs, fmt.Errorf("error loading index pattern: %w", err))
}
- return errs.Err()
+ return errors.Join(errs...)
}
// ImportDashboard imports the dashboard file
diff --git a/libbeat/mapping/field.go b/libbeat/mapping/field.go
index c1264db26d2..b4128cb926a 100644
--- a/libbeat/mapping/field.go
+++ b/libbeat/mapping/field.go
@@ -22,8 +22,6 @@ import (
"fmt"
"strings"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/elastic-agent-libs/mapstr"
"github.com/elastic/go-ucfg/yaml"
)
@@ -442,14 +440,14 @@ func ConcatFields(a, b Fields) (Fields, error) {
}
func (f Fields) conflicts(fields Fields) error {
- var errs multierror.Errors
+ var errs []error
for _, key := range fields.GetKeys() {
keys := strings.Split(key, ".")
if err := f.canConcat(key, keys); err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// canConcat checks if the given string can be concatenated to the existing fields f
diff --git a/libbeat/mapping/field_test.go b/libbeat/mapping/field_test.go
index 933a0f8444e..4769ee35a2c 100644
--- a/libbeat/mapping/field_test.go
+++ b/libbeat/mapping/field_test.go
@@ -454,7 +454,7 @@ func TestFieldConcat(t *testing.T) {
"duplicates fail": {
a: Fields{{Name: "a"}},
b: Fields{{Name: "a"}},
- err: "1 error: fields contain key ",
+ err: "fields contain key ",
},
"nested with common prefix": {
a: Fields{{
@@ -495,7 +495,7 @@ func TestFieldConcat(t *testing.T) {
Name: "a",
Fields: Fields{{Name: "c"}},
}},
- err: "1 error: fields contain key ",
+ err: "fields contain key ",
},
"a is prefix of b": {
a: Fields{{Name: "a"}},
@@ -503,7 +503,7 @@ func TestFieldConcat(t *testing.T) {
Name: "a",
Fields: Fields{{Name: "b"}},
}},
- err: "1 error: fields contain non object node conflicting with key ",
+ err: "fields contain non object node conflicting with key ",
},
"a is object and prefix of b": {
a: Fields{{Name: "a", Type: "object"}},
@@ -522,7 +522,7 @@ func TestFieldConcat(t *testing.T) {
Fields: Fields{{Name: "b"}},
}},
b: Fields{{Name: "a"}},
- err: "1 error: fields contain key ",
+ err: "fields contain key ",
},
"multiple errors": {
a: Fields{
@@ -536,7 +536,7 @@ func TestFieldConcat(t *testing.T) {
{Name: "foo", Fields: Fields{{Name: "b", Fields: Fields{{Name: "c"}}}}},
},
- err: "2 errors: fields contain key ; fields contain non object node conflicting with key ",
+ err: "fields contain key \nfields contain non object node conflicting with key ",
},
}
diff --git a/libbeat/processors/processor.go b/libbeat/processors/processor.go
index d1f84aee33e..05346f34cc5 100644
--- a/libbeat/processors/processor.go
+++ b/libbeat/processors/processor.go
@@ -18,11 +18,10 @@
package processors
import (
+ "errors"
"fmt"
"strings"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/elastic-agent-libs/logp"
@@ -148,14 +147,14 @@ func (procs *Processors) All() []beat.Processor {
}
func (procs *Processors) Close() error {
- var errs multierror.Errors
+ var errs []error
for _, p := range procs.List {
err := Close(p)
if err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// Run executes the all processors serially and returns the event and possibly
diff --git a/libbeat/processors/util/netinfo.go b/libbeat/processors/util/netinfo.go
index d4e694e5fa4..a472220f032 100644
--- a/libbeat/processors/util/netinfo.go
+++ b/libbeat/processors/util/netinfo.go
@@ -18,10 +18,9 @@
package util
import (
+ "errors"
"net"
"sort"
-
- "github.com/joeshaw/multierror"
)
// GetNetInfo returns lists of IPs and MACs for the machine it is executed on.
@@ -33,7 +32,7 @@ func GetNetInfo() (ipList []string, hwList []string, err error) {
}
// Keep track of all errors
- var errs multierror.Errors
+ var errs []error
for _, i := range ifaces {
// Skip loopback interfaces
@@ -62,7 +61,7 @@ func GetNetInfo() (ipList []string, hwList []string, err error) {
}
}
- return ipList, unique(hwList), errs.Err()
+ return ipList, unique(hwList), errors.Join(errs...)
}
// formatHardwareAddr formats hardware addresses according to the ECS spec.
diff --git a/libbeat/publisher/processing/processors.go b/libbeat/publisher/processing/processors.go
index a3fe42c88da..e5a33741a3f 100644
--- a/libbeat/publisher/processing/processors.go
+++ b/libbeat/publisher/processing/processors.go
@@ -18,13 +18,12 @@
package processing
import (
+ "errors"
"fmt"
"strings"
"sync"
"time"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/outputs/codec/json"
@@ -90,14 +89,14 @@ func (p *group) Close() error {
if p == nil {
return nil
}
- var errs multierror.Errors
+ var errs []error
for _, processor := range p.list {
err := processors.Close(processor)
if err != nil {
errs = append(errs, err)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func (p *group) String() string {
diff --git a/metricbeat/helper/socket/ptable.go b/metricbeat/helper/socket/ptable.go
index 67197d7f38a..158ff1fed0a 100644
--- a/metricbeat/helper/socket/ptable.go
+++ b/metricbeat/helper/socket/ptable.go
@@ -20,11 +20,11 @@
package socket
import (
+ "errors"
"os"
"strconv"
"strings"
- "github.com/joeshaw/multierror"
"github.com/prometheus/procfs"
)
@@ -86,7 +86,7 @@ func (t *ProcTable) Refresh() error {
return err
}
- var errs multierror.Errors
+ var errs []error
inodes := map[uint32]*Proc{}
cachedProcs := make(map[int]*Proc, len(procs))
for _, pi := range procs {
@@ -125,7 +125,7 @@ func (t *ProcTable) Refresh() error {
t.procs = cachedProcs
t.inodes = inodes
- return errs.Err()
+ return errors.Join(errs...)
}
func (t *ProcTable) accessibleProcs() ([]procfs.Proc, error) {
diff --git a/metricbeat/mb/builders.go b/metricbeat/mb/builders.go
index 4c55e3e3944..37256633851 100644
--- a/metricbeat/mb/builders.go
+++ b/metricbeat/mb/builders.go
@@ -23,7 +23,6 @@ import (
"strings"
"github.com/gofrs/uuid/v5"
- "github.com/joeshaw/multierror"
conf "github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
@@ -108,7 +107,7 @@ func createModule(r *Register, bm BaseModule) (Module, error) {
func initMetricSets(r *Register, m Module) ([]MetricSet, error) {
var (
- errs multierror.Errors
+ errs []error
)
bms, err := newBaseMetricSets(r, m)
@@ -151,7 +150,7 @@ func initMetricSets(r *Register, m Module) ([]MetricSet, error) {
metricsets = append(metricsets, metricSet)
}
- return metricsets, errs.Err()
+ return metricsets, errors.Join(errs...)
}
// newBaseMetricSets creates a new BaseMetricSet for all MetricSets defined
diff --git a/metricbeat/module/apache/status/data.go b/metricbeat/module/apache/status/data.go
index a1c8e0e6663..b2036785c7d 100644
--- a/metricbeat/module/apache/status/data.go
+++ b/metricbeat/module/apache/status/data.go
@@ -19,6 +19,7 @@ package status
import (
"bufio"
+ "errors"
"regexp"
"strings"
@@ -28,10 +29,10 @@ import (
)
var (
- scoreboardRegexp = regexp.MustCompile("(Scoreboard):\\s+((_|S|R|W|K|D|C|L|G|I|\\.)+)")
+ scoreboardRegexp = regexp.MustCompile(`(Scoreboard):\s+((_|S|R|W|K|D|C|L|G|I|\.)+)`)
// This should match: "CPUSystem: .01"
- matchNumber = regexp.MustCompile("(^[0-9a-zA-Z ]+):\\s+(\\d*\\.?\\d+)")
+ matchNumber = regexp.MustCompile(`(^[0-9a-zA-Z ]+):\s+(\d*\.?\d+)`)
schema = s.Schema{
"total_accesses": c.Int("Total Accesses"),
@@ -102,8 +103,8 @@ func applySchema(event mapstr.M, fullEvent map[string]interface{}) error {
if _, found := fullEvent["ServerUptimeSeconds"]; !found {
applicableSchema = schemaOld
}
- _, err := applicableSchema.ApplyTo(event, fullEvent)
- return err.Err()
+ _, errs := applicableSchema.ApplyTo(event, fullEvent)
+ return errors.Join(errs...)
}
// Map body to MapStr
diff --git a/metricbeat/module/elasticsearch/ccr/data.go b/metricbeat/module/elasticsearch/ccr/data.go
index 5301f6e217c..c4ab21d8713 100644
--- a/metricbeat/module/elasticsearch/ccr/data.go
+++ b/metricbeat/module/elasticsearch/ccr/data.go
@@ -19,13 +19,12 @@ package ccr
import (
"encoding/json"
+ "errors"
"fmt"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/elastic-agent-libs/mapstr"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -142,7 +141,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return fmt.Errorf("failure parsing Elasticsearch CCR Stats API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for _, followerIndex := range data.FollowStats.Indices {
for _, followerShard := range followerIndex.Shards {
event := mb.Event{}
@@ -169,5 +168,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/enrich/data.go b/metricbeat/module/elasticsearch/enrich/data.go
index e400160698c..4722ec83006 100644
--- a/metricbeat/module/elasticsearch/enrich/data.go
+++ b/metricbeat/module/elasticsearch/enrich/data.go
@@ -25,8 +25,6 @@ import (
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/elastic-agent-libs/mapstr"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -77,7 +75,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return fmt.Errorf("failure parsing Elasticsearch Enrich Stats API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for _, stat := range data.CoordinatorStats {
event := mb.Event{}
@@ -157,5 +155,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/index/data.go b/metricbeat/module/elasticsearch/index/data.go
index d8bec4939d6..d73126d3e25 100644
--- a/metricbeat/module/elasticsearch/index/data.go
+++ b/metricbeat/module/elasticsearch/index/data.go
@@ -19,10 +19,9 @@ package index
import (
"encoding/json"
+ "errors"
"fmt"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/metricbeat/helper"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -190,7 +189,7 @@ func eventsMapping(r mb.ReporterV2, httpClient *helper.HTTP, info elasticsearch.
return fmt.Errorf("failure parsing Indices Stats Elasticsearch API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for name := range indicesStats.Indices {
event := mb.Event{
ModuleFields: mapstr.M{},
@@ -234,7 +233,7 @@ func eventsMapping(r mb.ReporterV2, httpClient *helper.HTTP, info elasticsearch.
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
func parseAPIResponse(content []byte, indicesStats *stats) error {
@@ -308,8 +307,15 @@ func getIndexStatus(shards map[string]interface{}) (string, error) {
shard := mapstr.M(s)
- isPrimary := shard["primary"].(bool)
- state := shard["state"].(string)
+ isPrimary, ok := shard["primary"].(bool)
+ if !ok {
+ return "", fmt.Errorf("%v.shards[primary] is not a bool", indexName)
+ }
+
+ state, ok := shard["state"].(string)
+ if !ok {
+ return "", fmt.Errorf("%v.shards[state] is not a string", indexName)
+ }
if isPrimary {
areAllPrimariesStarted = areAllPrimariesStarted && (state == "STARTED")
@@ -357,8 +363,15 @@ func getIndexShardStats(shards mapstr.M) (*shardStats, error) {
shard := mapstr.M(s)
- isPrimary := shard["primary"].(bool)
- state := shard["state"].(string)
+ isPrimary, ok := shard["primary"].(bool)
+ if !ok {
+ return nil, fmt.Errorf("%v.shards[primary] is not a bool", indexName)
+ }
+
+ state, ok := shard["state"].(string)
+ if !ok {
+ return nil, fmt.Errorf("%v.shards[state] is not a string", indexName)
+ }
if isPrimary {
primaries++
diff --git a/metricbeat/module/elasticsearch/index_recovery/data.go b/metricbeat/module/elasticsearch/index_recovery/data.go
index c71b17e56e6..67bc2c90cc4 100644
--- a/metricbeat/module/elasticsearch/index_recovery/data.go
+++ b/metricbeat/module/elasticsearch/index_recovery/data.go
@@ -19,11 +19,10 @@ package index_recovery
import (
"encoding/json"
+ "errors"
"fmt"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
@@ -97,7 +96,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return fmt.Errorf("failure parsing Elasticsearch Recovery API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for indexName, d := range data {
shards, ok := d["shards"]
if !ok {
@@ -133,5 +132,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
r.Event(event)
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/ml_job/data.go b/metricbeat/module/elasticsearch/ml_job/data.go
index 7954d106b25..c70647dc7a2 100644
--- a/metricbeat/module/elasticsearch/ml_job/data.go
+++ b/metricbeat/module/elasticsearch/ml_job/data.go
@@ -19,10 +19,9 @@ package ml_job
import (
"encoding/json"
+ "errors"
"fmt"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -61,7 +60,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return fmt.Errorf("failure parsing Elasticsearch ML Job Stats API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for _, job := range jobsData.Jobs {
if err := elastic.FixTimestampField(job, "data_counts.earliest_record_timestamp"); err != nil {
@@ -83,7 +82,12 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
event.ModuleFields.Put("cluster.id", info.ClusterID)
if node, exists := job["node"]; exists {
- nodeHash := node.(map[string]interface{})
+ nodeHash, ok := node.(map[string]interface{})
+ if !ok {
+ errs = append(errs, errors.New("job[node] is not a map"))
+ continue
+ }
+
event.ModuleFields.Put("node.id", nodeHash["id"])
event.ModuleFields.Put("node.name", nodeHash["name"])
}
@@ -100,5 +104,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/node/data.go b/metricbeat/module/elasticsearch/node/data.go
index 4576cc4ac88..78fea5cfe43 100644
--- a/metricbeat/module/elasticsearch/node/data.go
+++ b/metricbeat/module/elasticsearch/node/data.go
@@ -19,13 +19,12 @@ package node
import (
"encoding/json"
+ "errors"
"fmt"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/elastic-agent-libs/mapstr"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -74,7 +73,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return fmt.Errorf("failure parsing Elasticsearch Node Stats API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for id, node := range nodesStruct.Nodes {
event := mb.Event{}
@@ -103,5 +102,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/node_stats/data.go b/metricbeat/module/elasticsearch/node_stats/data.go
index 2673baa3b06..95a462d077c 100644
--- a/metricbeat/module/elasticsearch/node_stats/data.go
+++ b/metricbeat/module/elasticsearch/node_stats/data.go
@@ -19,13 +19,12 @@ package node_stats
import (
"encoding/json"
+ "errors"
"fmt"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
"github.com/elastic/elastic-agent-libs/mapstr"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -375,7 +374,7 @@ func eventsMapping(r mb.ReporterV2, m elasticsearch.MetricSetAPI, info elasticse
return err
}
- var errs multierror.Errors
+ var errs []error
for nodeID, node := range nodeData.Nodes {
isMaster := nodeID == masterNodeID
@@ -452,5 +451,5 @@ func eventsMapping(r mb.ReporterV2, m elasticsearch.MetricSetAPI, info elasticse
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/pending_tasks/data.go b/metricbeat/module/elasticsearch/pending_tasks/data.go
index a75c2dea6b6..ba22f012302 100644
--- a/metricbeat/module/elasticsearch/pending_tasks/data.go
+++ b/metricbeat/module/elasticsearch/pending_tasks/data.go
@@ -19,10 +19,9 @@ package pending_tasks
import (
"encoding/json"
+ "errors"
"fmt"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
@@ -54,7 +53,7 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
return elastic.MakeErrorForMissingField("tasks", elastic.Elasticsearch)
}
- var errs multierror.Errors
+ var errs []error
for _, task := range tasksStruct.Tasks {
event := mb.Event{}
@@ -81,5 +80,5 @@ func eventsMapping(r mb.ReporterV2, info elasticsearch.Info, content []byte, isX
r.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/metricbeat/module/elasticsearch/shard/data.go b/metricbeat/module/elasticsearch/shard/data.go
index e2c211035fb..65b38b31277 100644
--- a/metricbeat/module/elasticsearch/shard/data.go
+++ b/metricbeat/module/elasticsearch/shard/data.go
@@ -19,6 +19,7 @@ package shard
import (
"encoding/json"
+ "errors"
"strconv"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
@@ -26,8 +27,6 @@ import (
"fmt"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/mb"
@@ -65,7 +64,7 @@ func eventsMapping(r mb.ReporterV2, content []byte, isXpack bool) error {
return fmt.Errorf("failure parsing Elasticsearch Cluster State API response: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for _, index := range stateData.RoutingTable.Indices {
for _, shards := range index.Shards {
for i, shard := range shards {
@@ -146,7 +145,7 @@ func eventsMapping(r mb.ReporterV2, content []byte, isXpack bool) error {
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func getSourceNode(nodeID string, stateData *stateStruct) (mapstr.M, error) {
diff --git a/metricbeat/module/jolokia/jmx/data.go b/metricbeat/module/jolokia/jmx/data.go
index 59498764cf9..accc2145d4d 100644
--- a/metricbeat/module/jolokia/jmx/data.go
+++ b/metricbeat/module/jolokia/jmx/data.go
@@ -18,11 +18,10 @@
package jmx
import (
+ "errors"
"fmt"
"strings"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -120,7 +119,7 @@ func eventMapping(entries []Entry, mapping AttributeMapping) ([]mapstr.M, error)
// Generate a different event for each wildcard mbean, and and additional one
// for non-wildcard requested mbeans, group them by event name if defined
mbeanEvents := make(map[eventKey]mapstr.M)
- var errs multierror.Errors
+ var errs []error
for _, v := range entries {
if v.Value == nil || v.Request.Attribute == nil {
@@ -136,11 +135,13 @@ func eventMapping(entries []Entry, mapping AttributeMapping) ([]mapstr.M, error)
errs = append(errs, err)
}
case map[string]interface{}:
- constructEvents(entryValues, v, mbeanEvents, mapping, errs)
+ errs = constructEvents(entryValues, v, mbeanEvents, mapping, errs)
}
case []interface{}:
- entryValues := v.Value.(map[string]interface{})
- constructEvents(entryValues, v, mbeanEvents, mapping, errs)
+ entryValues, ok := v.Value.(map[string]interface{})
+ if ok {
+ errs = constructEvents(entryValues, v, mbeanEvents, mapping, errs)
+ }
}
}
@@ -149,10 +150,10 @@ func eventMapping(entries []Entry, mapping AttributeMapping) ([]mapstr.M, error)
events = append(events, event)
}
- return events, errs.Err()
+ return events, errors.Join(errs...)
}
-func constructEvents(entryValues map[string]interface{}, v Entry, mbeanEvents map[eventKey]mapstr.M, mapping AttributeMapping, errs multierror.Errors) {
+func constructEvents(entryValues map[string]interface{}, v Entry, mbeanEvents map[eventKey]mapstr.M, mapping AttributeMapping, errs []error) []error {
hasWildcard := strings.Contains(v.Request.Mbean, "*")
for attribute, value := range entryValues {
if !hasWildcard {
@@ -180,6 +181,7 @@ func constructEvents(entryValues map[string]interface{}, v Entry, mbeanEvents ma
}
}
}
+ return errs
}
func selectEvent(events map[eventKey]mapstr.M, key eventKey) mapstr.M {
diff --git a/packetbeat/module/pipeline.go b/packetbeat/module/pipeline.go
index c90f0adda76..74bb7d36b45 100644
--- a/packetbeat/module/pipeline.go
+++ b/packetbeat/module/pipeline.go
@@ -26,7 +26,6 @@ import (
"path/filepath"
"strings"
- "github.com/joeshaw/multierror"
"gopkg.in/yaml.v2"
"github.com/elastic/beats/v7/filebeat/fileset"
@@ -141,14 +140,14 @@ func load(esClient *eslegclient.Connection, pipelines []pipeline, overwritePipel
}
if err != nil {
- errs := multierror.Errors{err}
+ errs := []error{err}
for _, id := range loaded {
err = fileset.DeletePipeline(esClient, id)
if err != nil {
errs = append(errs, err)
}
}
- return nil, errs.Err()
+ return nil, errors.Join(errs...)
}
return loaded, nil
}
@@ -182,6 +181,7 @@ func applyTemplates(prefix string, version string, filename string, original []b
if err != nil {
return nil, fmt.Errorf("failed to sanitize the YAML pipeline file: %s: %w", filename, err)
}
+ //nolint:errcheck // ignore
content = newContent.(map[string]interface{})
default:
return nil, fmt.Errorf("unsupported extension '%s' for pipeline file: %s", extension, filename)
diff --git a/winlogbeat/config/config.go b/winlogbeat/config/config.go
index 08ea6822a32..d5dced5efb4 100644
--- a/winlogbeat/config/config.go
+++ b/winlogbeat/config/config.go
@@ -19,11 +19,10 @@
package config
import (
+ "errors"
"fmt"
"time"
- "github.com/joeshaw/multierror"
-
conf "github.com/elastic/elastic-agent-libs/config"
)
@@ -49,12 +48,12 @@ type WinlogbeatConfig struct {
// Validate validates the WinlogbeatConfig data and returns an error describing
// all problems or nil if there are none.
func (ebc WinlogbeatConfig) Validate() error {
- var errs multierror.Errors
+ var errs []error
if len(ebc.EventLogs) == 0 {
errs = append(errs, fmt.Errorf("at least one event log must be "+
"configured as part of event_logs"))
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/winlogbeat/config/config_test.go b/winlogbeat/config/config_test.go
index 2efd501336c..2ca49808804 100644
--- a/winlogbeat/config/config_test.go
+++ b/winlogbeat/config/config_test.go
@@ -60,8 +60,7 @@ func TestConfigValidate(t *testing.T) {
},
{
WinlogbeatConfig{},
- "1 error: at least one event log must be configured as part of " +
- "event_logs",
+ "at least one event log must be configured as part of event_logs",
},
}
diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go
index 43654284218..4b6e9f7b50e 100644
--- a/winlogbeat/eventlog/wineventlog.go
+++ b/winlogbeat/eventlog/wineventlog.go
@@ -32,7 +32,6 @@ import (
"syscall"
"time"
- "github.com/joeshaw/multierror"
"github.com/rcrowley/go-metrics"
"golang.org/x/sys/windows"
@@ -142,7 +141,7 @@ var defaultWinEventLogConfig = winEventLogConfig{
// Validate validates the winEventLogConfig data and returns an error describing
// any problems or nil.
func (c *winEventLogConfig) Validate() error {
- var errs multierror.Errors
+ var errs []error
if c.XMLQuery != "" {
if c.ID == "" {
@@ -170,7 +169,7 @@ func (c *winEventLogConfig) Validate() error {
errs = append(errs, fmt.Errorf("event log is missing a 'name'"))
}
- return errs.Err()
+ return errors.Join(errs...)
}
// Validate that winEventLog implements the EventLog interface.
diff --git a/winlogbeat/module/pipeline.go b/winlogbeat/module/pipeline.go
index 3ddc4f10f11..8e36703c92e 100644
--- a/winlogbeat/module/pipeline.go
+++ b/winlogbeat/module/pipeline.go
@@ -27,7 +27,6 @@ import (
"path/filepath"
"strings"
- "github.com/joeshaw/multierror"
"gopkg.in/yaml.v2"
"github.com/elastic/beats/v7/filebeat/fileset"
@@ -167,14 +166,14 @@ func load(esClient *eslegclient.Connection, pipelines []pipeline, overwritePipel
}
if err != nil {
- errs := multierror.Errors{err}
+ errs := []error{err}
for _, id := range loaded {
err = fileset.DeletePipeline(esClient, id)
if err != nil {
errs = append(errs, err)
}
}
- return nil, errs.Err()
+ return nil, errors.Join(errs...)
}
return loaded, nil
}
@@ -208,6 +207,7 @@ func applyTemplates(prefix string, version string, filename string, original []b
if err != nil {
return nil, fmt.Errorf("failed to sanitize the YAML pipeline file: %s: %w", filename, err)
}
+ //nolint:errcheck // ignore
content = newContent.(map[string]interface{})
default:
return nil, fmt.Errorf("unsupported extension '%s' for pipeline file: %s", extension, filename)
diff --git a/winlogbeat/sys/wineventlog/query.go b/winlogbeat/sys/wineventlog/query.go
index c48208f38fa..13a51cb0ac6 100644
--- a/winlogbeat/sys/wineventlog/query.go
+++ b/winlogbeat/sys/wineventlog/query.go
@@ -19,14 +19,13 @@ package wineventlog
import (
"bytes"
+ "errors"
"fmt"
"regexp"
"strconv"
"strings"
"text/template"
"time"
-
- "github.com/joeshaw/multierror"
)
const (
@@ -73,7 +72,7 @@ type Query struct {
// Build builds a query from the given parameters. The query is returned as a
// XML string and can be used with Subscribe function.
func (q Query) Build() (string, error) {
- var errs multierror.Errors
+ var errs []error
if q.Log == "" {
errs = append(errs, fmt.Errorf("empty log name"))
}
@@ -91,7 +90,7 @@ func (q Query) Build() (string, error) {
}
}
if len(errs) > 0 {
- return "", errs.Err()
+ return "", errors.Join(errs...)
}
return executeTemplate(queryTemplate, qp)
}
diff --git a/x-pack/auditbeat/module/system/host/host.go b/x-pack/auditbeat/module/system/host/host.go
index 8ea3a899de2..e9edbf08cc5 100644
--- a/x-pack/auditbeat/module/system/host/host.go
+++ b/x-pack/auditbeat/module/system/host/host.go
@@ -8,6 +8,7 @@ import (
"bytes"
"encoding/binary"
"encoding/gob"
+ "errors"
"fmt"
"io"
"math"
@@ -16,7 +17,6 @@ import (
"time"
"github.com/cespare/xxhash/v2"
- "github.com/joeshaw/multierror"
"github.com/elastic/beats/v7/auditbeat/ab"
"github.com/elastic/beats/v7/auditbeat/datastore"
@@ -117,7 +117,6 @@ func (host *Host) changeDetectionHash() uint64 {
return h.Sum64()
}
-//nolint:errcheck // All checks are for mapstr.Put.
func (host *Host) toMapStr() mapstr.M {
mapstr := mapstr.M{
// https://github.com/elastic/ecs#-host-fields
@@ -289,7 +288,6 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
var events []mb.Event
// Report ID changes as a separate, special event.
- //nolint:errcheck // All checks are for mapstr.Put.
if ms.lastHost.Info.UniqueID != currentHost.Info.UniqueID {
/*
Issue two events - one for the host with the old ID, one for the new
@@ -510,7 +508,7 @@ func getNetInfo() ([]net.IP, []net.HardwareAddr, error) {
}
// Keep track of all errors
- var errs multierror.Errors
+ var errs []error
for _, i := range ifaces {
// Skip loopback interfaces
@@ -546,5 +544,5 @@ func getNetInfo() ([]net.IP, []net.HardwareAddr, error) {
}
}
- return append(ipv4List, ipv6List...), hwList, errs.Err()
+ return append(ipv4List, ipv6List...), hwList, errors.Join(errs...)
}
diff --git a/x-pack/auditbeat/module/system/package/package.go b/x-pack/auditbeat/module/system/package/package.go
index 14aaadfdc56..90c976f68a5 100644
--- a/x-pack/auditbeat/module/system/package/package.go
+++ b/x-pack/auditbeat/module/system/package/package.go
@@ -25,7 +25,6 @@ import (
"github.com/cespare/xxhash/v2"
"github.com/gofrs/uuid/v5"
- "github.com/joeshaw/multierror"
"go.etcd.io/bbolt"
"github.com/elastic/beats/v7/auditbeat/ab"
@@ -255,7 +254,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
// Close cleans up the MetricSet when it finishes.
func (ms *MetricSet) Close() error {
- var errs multierror.Errors
+ var errs []error
errs = append(errs, closeDataset())
@@ -263,7 +262,7 @@ func (ms *MetricSet) Close() error {
errs = append(errs, ms.bucket.Close())
}
- return errs.Err()
+ return errors.Join(errs...)
}
// Fetch collects data about the host. It is invoked periodically.
diff --git a/x-pack/auditbeat/module/system/socket/helper/loopback.go b/x-pack/auditbeat/module/system/socket/helper/loopback.go
index 79512c602bc..c723d27d6a3 100644
--- a/x-pack/auditbeat/module/system/socket/helper/loopback.go
+++ b/x-pack/auditbeat/module/system/socket/helper/loopback.go
@@ -7,14 +7,13 @@
package helper
import (
+ "crypto/rand"
"errors"
"fmt"
- "math/rand"
"net"
"time"
"unsafe"
- "github.com/joeshaw/multierror"
"golang.org/x/sys/unix"
)
@@ -81,7 +80,10 @@ func NewIPv6Loopback() (lo IPv6Loopback, err error) {
func (lo *IPv6Loopback) AddRandomAddress() (addr net.IP, err error) {
addr = make(net.IP, 16)
addr[0] = 0xFD
- rand.Read(addr[1:])
+ _, err = rand.Read(addr[1:])
+ if err != nil {
+ return nil, fmt.Errorf("rand.Read failed: %w", err)
+ }
var req in6Ifreq
copy(req.addr[:], addr)
req.ifindex = lo.ifreq.index
@@ -106,7 +108,7 @@ func (lo *IPv6Loopback) AddRandomAddress() (addr net.IP, err error) {
if err = unix.Bind(fd, &bindAddr); err == nil {
break
}
- if errno, ok := err.(unix.Errno); !ok || errno != unix.EADDRNOTAVAIL {
+ if !errors.Is(err, unix.EADDRNOTAVAIL) {
break
}
time.Sleep(time.Millisecond * time.Duration(i))
@@ -119,7 +121,7 @@ func (lo *IPv6Loopback) AddRandomAddress() (addr net.IP, err error) {
// Cleanup removes the addresses registered to this loopback.
func (lo *IPv6Loopback) Cleanup() error {
- var errs multierror.Errors
+ var errs []error
var req in6Ifreq
req.ifindex = lo.ifreq.index
req.prefix = 128
@@ -133,5 +135,5 @@ func (lo *IPv6Loopback) Cleanup() error {
if lo.fd != -1 {
unix.Close(lo.fd)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/x-pack/auditbeat/module/system/socket/kprobes.go b/x-pack/auditbeat/module/system/socket/kprobes.go
index a8781345991..d468cfa9599 100644
--- a/x-pack/auditbeat/module/system/socket/kprobes.go
+++ b/x-pack/auditbeat/module/system/socket/kprobes.go
@@ -12,8 +12,6 @@ import (
"strings"
"unsafe"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/auditbeat/tracing"
"github.com/elastic/beats/v7/x-pack/auditbeat/module/system/socket/helper"
"github.com/elastic/elastic-agent-libs/mapstr"
@@ -59,19 +57,19 @@ func (p *probeInstaller) Install(pdef helper.ProbeDef) (format tracing.ProbeForm
if decoder, err = pdef.Decoder(format); err != nil {
return format, decoder, fmt.Errorf("failed to create decoder: %w", err)
}
- return
+ return format, decoder, nil
}
// UninstallInstalled uninstalls the probes installed by Install.
func (p *probeInstaller) UninstallInstalled() error {
- var errs multierror.Errors
+ var errs []error
for _, probe := range p.installed {
if err := p.traceFS.RemoveKProbe(probe); err != nil {
errs = append(errs, err)
}
}
p.installed = nil
- return errs.Err()
+ return errors.Join(errs...)
}
// UninstallIf uninstalls all probes in the system that met the condition.
@@ -80,7 +78,7 @@ func (p *probeInstaller) UninstallIf(condition helper.ProbeCondition) error {
if err != nil {
return fmt.Errorf("failed to list installed kprobes: %w", err)
}
- var errs multierror.Errors
+ var errs []error
for _, probe := range kprobes {
if condition(probe) {
if err := p.traceFS.RemoveKProbe(probe); err != nil {
@@ -88,7 +86,7 @@ func (p *probeInstaller) UninstallIf(condition helper.ProbeCondition) error {
}
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// WithGroup sets a custom group to probes before they are installed.
diff --git a/x-pack/auditbeat/module/system/socket/state.go b/x-pack/auditbeat/module/system/socket/state.go
index 347c5385921..2db1f18c28e 100644
--- a/x-pack/auditbeat/module/system/socket/state.go
+++ b/x-pack/auditbeat/module/system/socket/state.go
@@ -17,7 +17,6 @@ import (
"sync/atomic"
"time"
- "github.com/joeshaw/multierror"
"golang.org/x/sys/unix"
"github.com/elastic/beats/v7/auditbeat/tracing"
@@ -974,7 +973,7 @@ func (f *flow) toEvent(final bool) (ev mb.Event, err error) {
"complete": f.complete,
},
}
- var errs multierror.Errors
+ var errs []error
rootPut := func(key string, value interface{}) {
if _, err := root.Put(key, value); err != nil {
errs = append(errs, err)
@@ -1042,7 +1041,7 @@ func (f *flow) toEvent(final bool) (ev mb.Event, err error) {
return mb.Event{
RootFields: root,
MetricSetFields: metricset,
- }, errs.Err()
+ }, errors.Join(errs...)
}
func (s *state) SyncClocks(kernelNanos, userNanos uint64) error {
diff --git a/x-pack/auditbeat/module/system/user/user.go b/x-pack/auditbeat/module/system/user/user.go
index f48019af572..f984d39310e 100644
--- a/x-pack/auditbeat/module/system/user/user.go
+++ b/x-pack/auditbeat/module/system/user/user.go
@@ -21,7 +21,6 @@ import (
"github.com/cespare/xxhash/v2"
"github.com/gofrs/uuid/v5"
- "github.com/joeshaw/multierror"
"github.com/elastic/beats/v7/auditbeat/ab"
"github.com/elastic/beats/v7/auditbeat/datastore"
@@ -326,7 +325,7 @@ func (ms *MetricSet) Fetch(report mb.ReporterV2) {
// reportState reports all existing users on the system.
func (ms *MetricSet) reportState(report mb.ReporterV2) error {
- var errs multierror.Errors
+ var errs []error
ms.lastState = time.Now()
users, err := GetUsers(ms.config.DetectPasswordChanges)
@@ -369,12 +368,12 @@ func (ms *MetricSet) reportState(report mb.ReporterV2) error {
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
// reportChanges detects and reports any changes to users on this system since the last call.
func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
- var errs multierror.Errors
+ var errs []error
currentTime := time.Now()
// If this is not the first call to Fetch/reportChanges,
@@ -403,10 +402,12 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
// Check for changes to users
missingUserMap := make(map[string](*User))
for _, missingUser := range missingFromCache {
+ //nolint:errcheck // ignore
missingUserMap[missingUser.(*User).UID] = missingUser.(*User)
}
for _, userFromCache := range newInCache {
+ //nolint:errcheck // ignore
newUser := userFromCache.(*User)
oldUser, found := missingUserMap[newUser.UID]
@@ -460,7 +461,7 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
}
}
- return errs.Err()
+ return errors.Join(errs...)
}
func (ms *MetricSet) userEvent(user *User, eventType string, action eventAction) mb.Event {
diff --git a/x-pack/auditbeat/module/system/user/users_linux.go b/x-pack/auditbeat/module/system/user/users_linux.go
index e104fc1333b..adaf14b49cd 100644
--- a/x-pack/auditbeat/module/system/user/users_linux.go
+++ b/x-pack/auditbeat/module/system/user/users_linux.go
@@ -18,6 +18,7 @@ import "C"
import (
"crypto/sha512"
+ "errors"
"fmt"
"os/user"
"runtime"
@@ -25,8 +26,6 @@ import (
"strings"
"syscall"
"time"
-
- "github.com/joeshaw/multierror"
)
var epoch = time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
@@ -34,7 +33,7 @@ var epoch = time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
// GetUsers retrieves a list of users using information from
// /etc/passwd, /etc/group, and - if configured - /etc/shadow.
func GetUsers(readPasswords bool) ([]*User, error) {
- var errs multierror.Errors
+ var errs []error
// We are using a number of thread sensitive C functions in
// this file, most importantly setpwent/getpwent/endpwent and
@@ -61,7 +60,7 @@ func GetUsers(readPasswords bool) ([]*User, error) {
}
}
- return users, errs.Err()
+ return users, errors.Join(errs...)
}
func readPasswdFile(readPasswords bool) ([]*User, error) {
@@ -80,7 +79,7 @@ func readPasswdFile(readPasswords bool) ([]*User, error) {
if passwd == nil {
// getpwent() can return ENOENT even when there is no error,
// see https://github.com/systemd/systemd/issues/9585.
- if err != nil && err != syscall.ENOENT {
+ if err != nil && !errors.Is(err, syscall.ENOENT) {
return users, fmt.Errorf("error getting user: %w", err)
}
diff --git a/x-pack/filebeat/input/o365audit/input.go b/x-pack/filebeat/input/o365audit/input.go
index b01ba98ac90..11e7c1222cc 100644
--- a/x-pack/filebeat/input/o365audit/input.go
+++ b/x-pack/filebeat/input/o365audit/input.go
@@ -7,11 +7,11 @@ package o365audit
import (
"context"
"encoding/json"
+ "errors"
"fmt"
"time"
"github.com/Azure/go-autorest/autorest"
- "github.com/joeshaw/multierror"
v2 "github.com/elastic/beats/v7/filebeat/input/v2"
cursor "github.com/elastic/beats/v7/filebeat/input/v2/input-cursor"
@@ -117,7 +117,8 @@ func (inp *o365input) Run(
if err == nil {
break
}
- if ctx.Cancelation.Err() != err && err != context.Canceled {
+ //nolint:errorlint // ignore
+ if ctx.Cancelation.Err() != err && !errors.Is(err, context.Canceled) {
msg := mapstr.M{}
msg.Put("error.message", err.Error())
msg.Put("event.kind", "pipeline_error")
@@ -125,9 +126,12 @@ func (inp *o365input) Run(
Timestamp: time.Now(),
Fields: msg,
}
- publisher.Publish(event, nil)
+ if err := publisher.Publish(event, nil); err != nil {
+ ctx.Logger.Errorf("publisher.Publish failed: %v", err)
+ }
ctx.Logger.Errorf("Input failed: %v", err)
ctx.Logger.Infof("Restarting in %v", inp.config.API.ErrorRetryInterval)
+ //nolint:errcheck // ignore
timed.Wait(ctx.Cancelation, inp.config.API.ErrorRetryInterval)
}
}
@@ -140,7 +144,10 @@ func (inp *o365input) runOnce(
cursor cursor.Cursor,
publisher cursor.Publisher,
) error {
- stream := src.(*stream)
+ stream, ok := src.(*stream)
+ if !ok {
+ return errors.New("unable to cast src to stream")
+ }
tenantID, contentType := stream.tenantID, stream.contentType
log := ctx.Logger.With("tenantID", tenantID, "contentType", contentType)
@@ -239,7 +246,7 @@ func (env apiEnvironment) ReportAPIError(err apiError) poll.Action {
}
func (env apiEnvironment) toBeatEvent(raw json.RawMessage, doc mapstr.M) beat.Event {
- var errs multierror.Errors
+ var errs []error
ts, err := getDateKey(doc, "CreationTime", apiDateFormats)
if err != nil {
ts = time.Now()
@@ -257,6 +264,7 @@ func (env apiEnvironment) toBeatEvent(raw json.RawMessage, doc mapstr.M) beat.Ev
}
}
if env.Config.PreserveOriginalEvent {
+ //nolint:errcheck // ignore
b.PutValue("event.original", string(raw))
}
if len(errs) > 0 {
@@ -264,6 +272,7 @@ func (env apiEnvironment) toBeatEvent(raw json.RawMessage, doc mapstr.M) beat.Ev
for idx, e := range errs {
msgs[idx] = e.Error()
}
+ //nolint:errcheck // ignore
b.PutValue("error.message", msgs)
}
return b
diff --git a/x-pack/functionbeat/function/core/coordinator.go b/x-pack/functionbeat/function/core/coordinator.go
index b7cf2e716be..50e771ba996 100644
--- a/x-pack/functionbeat/function/core/coordinator.go
+++ b/x-pack/functionbeat/function/core/coordinator.go
@@ -6,10 +6,9 @@ package core
import (
"context"
+ "errors"
"fmt"
- "github.com/joeshaw/multierror"
-
"github.com/elastic/beats/v7/x-pack/functionbeat/function/telemetry"
"github.com/elastic/elastic-agent-libs/logp"
)
@@ -68,14 +67,14 @@ func (r *Coordinator) Run(ctx context.Context, t telemetry.T) error {
// Wait for goroutine to complete and aggregate any errors from the goroutine and
// raise them back to the main program.
- var errors multierror.Errors
+ var errs []error
for range r.runners {
err := <-results
if err != nil {
- errors = append(errors, err)
+ errs = append(errs, err)
}
}
- return errors.Err()
+ return errors.Join(errs...)
}
func (r *Coordinator) runFunc(
diff --git a/x-pack/libbeat/management/managerV2.go b/x-pack/libbeat/management/managerV2.go
index e39b394bf2b..2ffa7f1c807 100644
--- a/x-pack/libbeat/management/managerV2.go
+++ b/x-pack/libbeat/management/managerV2.go
@@ -14,7 +14,6 @@ import (
"syscall"
"time"
- "github.com/joeshaw/multierror"
"go.uber.org/zap/zapcore"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
@@ -682,9 +681,14 @@ func (cm *BeatV2Manager) reload(units map[unitKey]*agentUnit) {
// in v2 only a single input type will be started per component, so we don't need to
// worry about getting multiple re-loaders (we just need the one for the type)
if err := cm.reloadInputs(inputUnits); err != nil {
- merror := &multierror.MultiError{}
- if errors.As(err, &merror) {
- for _, err := range merror.Errors {
+ // reloadInputs wraps the multierror so we have to call Unwrap
+ wr := errors.Unwrap(err)
+
+ //nolint:errorlint // ignore
+ if u, ok := wr.(interface {
+ Unwrap() []error
+ }); ok {
+ for _, err := range u.Unwrap() {
unitErr := cfgfile.UnitError{}
if errors.As(err, &unitErr) {
unitErrors[unitErr.UnitID] = append(unitErrors[unitErr.UnitID], unitErr.Err)
@@ -824,17 +828,17 @@ func (cm *BeatV2Manager) reloadInputs(inputUnits []*agentUnit) error {
}
if err := obj.Reload(inputBeatCfgs); err != nil {
- merror := &multierror.MultiError{}
- realErrors := multierror.Errors{}
+ var errs []error
// At the moment this logic is tightly bound to the current RunnerList
// implementation from libbeat/cfgfile/list.go and Input.loadStates from
// filebeat/input/log/input.go.
// If they change the way they report errors, this will break.
- // TODO (Tiago): update all layers to use the most recent features from
- // the standard library errors package.
- if errors.As(err, &merror) {
- for _, err := range merror.Errors {
+ //nolint:errorlint // ignore
+ if u, ok := err.(interface {
+ Unwrap() []error
+ }); ok {
+ for _, err := range u.Unwrap() {
causeErr := errors.Unwrap(err)
// A Log input is only marked as finished when all events it
// produced are acked by the acker so when we see this error,
@@ -850,12 +854,12 @@ func (cm *BeatV2Manager) reloadInputs(inputUnits []*agentUnit) error {
}
// This is an error that cannot be ignored, so we report it
- realErrors = append(realErrors, err)
+ errs = append(errs, err)
}
}
- if len(realErrors) != 0 {
- return fmt.Errorf("failed to reload inputs: %w", realErrors.Err())
+ if len(errs) != 0 {
+ return fmt.Errorf("failed to reload inputs: %w", errors.Join(errs...))
}
} else {
// If there was no error reloading input and forceReload was
diff --git a/x-pack/libbeat/management/managerV2_test.go b/x-pack/libbeat/management/managerV2_test.go
index f1b32b15d82..f76bda8e1ff 100644
--- a/x-pack/libbeat/management/managerV2_test.go
+++ b/x-pack/libbeat/management/managerV2_test.go
@@ -12,7 +12,6 @@ import (
"testing"
"time"
- "github.com/joeshaw/multierror"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
"google.golang.org/grpc"
@@ -411,14 +410,14 @@ func TestErrorPerUnit(t *testing.T) {
r.MustRegisterOutput(output)
inputs := &mockReloadable{
ReloadFn: func(configs []*reload.ConfigWithMeta) error {
- errs := multierror.Errors{}
+ var errs []error
for _, input := range configs {
errs = append(errs, cfgfile.UnitError{
UnitID: input.InputUnitID,
Err: errors.New(errorMessages[input.InputUnitID]),
})
}
- return errs.Err()
+ return errors.Join(errs...)
},
}
r.MustRegisterInput(inputs)
diff --git a/x-pack/metricbeat/module/enterprisesearch/health/data.go b/x-pack/metricbeat/module/enterprisesearch/health/data.go
index 318f9fa0598..24cc7b643fe 100644
--- a/x-pack/metricbeat/module/enterprisesearch/health/data.go
+++ b/x-pack/metricbeat/module/enterprisesearch/health/data.go
@@ -9,8 +9,6 @@ import (
"errors"
"fmt"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
@@ -81,7 +79,7 @@ func eventMapping(report mb.ReporterV2, input []byte, isXpack bool) error {
if err != nil {
return err
}
- var errs multierror.Errors
+ var errs []error
// All events need to have a cluster_uuid to work with Stack Monitoring
event := mb.Event{
@@ -131,5 +129,5 @@ func eventMapping(report mb.ReporterV2, input []byte, isXpack bool) error {
report.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}
diff --git a/x-pack/metricbeat/module/enterprisesearch/stats/data.go b/x-pack/metricbeat/module/enterprisesearch/stats/data.go
index cd1ebd13dc3..1de2934118b 100644
--- a/x-pack/metricbeat/module/enterprisesearch/stats/data.go
+++ b/x-pack/metricbeat/module/enterprisesearch/stats/data.go
@@ -9,8 +9,6 @@ import (
"errors"
"fmt"
- "github.com/joeshaw/multierror"
-
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
"github.com/elastic/beats/v7/metricbeat/helper/elastic"
@@ -163,7 +161,7 @@ func eventMapping(report mb.ReporterV2, input []byte, isXpack bool) error {
if err != nil {
return err
}
- var errs multierror.Errors
+ var errs []error
// All events need to have a cluster_uuid to work with Stack Monitoring
event := mb.Event{
@@ -201,5 +199,5 @@ func eventMapping(report mb.ReporterV2, input []byte, isXpack bool) error {
report.Event(event)
}
- return errs.Err()
+ return errors.Join(errs...)
}