From 1c90d3fcd185a7895680e8b16ef672bd36700d69 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Thu, 26 Dec 2024 20:01:31 +0530
Subject: [PATCH 1/9] chore: initial commit

---
 metricbeat/module/system/process/process.go   | 21 ++++++++++++-------
 .../system/process_summary/process_summary.go | 12 +++++++++--
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/metricbeat/module/system/process/process.go b/metricbeat/module/system/process/process.go
index f84c0b6027a0..c3fb72d0e51c 100644
--- a/metricbeat/module/system/process/process.go
+++ b/metricbeat/module/system/process/process.go
@@ -45,9 +45,10 @@ func init() {
 // MetricSet that fetches process metrics.
 type MetricSet struct {
 	mb.BaseMetricSet
-	stats  *process.Stats
-	perCPU bool
-	setpid int
+	stats            *process.Stats
+	perCPU           bool
+	setpid           int
+	degradeOnPartial bool
 }
 
 // New creates and returns a new MetricSet.
@@ -72,7 +73,12 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
 	if config.Pid != 0 && config.Procs[0] != ".*" {
 		logp.L().Warnf("`process.pid` set to %d, but `processes` is set to a non-default value. Metricset will only report metrics for pid %d", config.Pid, config.Pid)
 	}
-
+	degradedConf := struct {
+		DegradeOnPartial bool `config:"degrade_on_partial"`
+	}{}
+	if err := base.Module().UnpackConfig(&degradedConf); err != nil {
+		logp.L().Warnf("Failed to unpack config; degraded mode will be disabled for partial metrics: %v", err)
+	}
 	m := &MetricSet{
 		BaseMetricSet: base,
 		stats: &process.Stats{
@@ -88,7 +94,8 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
 				IgnoreRootCgroups: true,
 			},
 		},
-		perCPU: config.IncludePerCPU,
+		perCPU:           config.IncludePerCPU,
+		degradeOnPartial: degradedConf.DegradeOnPartial,
 	}
 
 	m.setpid = config.Pid
@@ -118,7 +125,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 		if err != nil && !errors.Is(err, process.NonFatalErr{}) {
 			// return only if the error is fatal in nature
 			return fmt.Errorf("process stats: %w", err)
-		} else if (err != nil && errors.Is(err, process.NonFatalErr{})) {
+		} else if (err != nil && errors.Is(err, process.NonFatalErr{}) && !m.degradeOnPartial) {
 			err = mb.PartialMetricsError{Err: err}
 		}
 
@@ -137,7 +144,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 		if err != nil && !errors.Is(err, process.NonFatalErr{}) {
 			// return only if the error is fatal in nature
 			return fmt.Errorf("error fetching pid %d: %w", m.setpid, err)
-		} else if (err != nil && errors.Is(err, process.NonFatalErr{})) {
+		} else if (err != nil && errors.Is(err, process.NonFatalErr{}) && !m.degradeOnPartial) {
 			err = mb.PartialMetricsError{Err: err}
 		}
 		// if error is non-fatal, emit partial metrics.
diff --git a/metricbeat/module/system/process_summary/process_summary.go b/metricbeat/module/system/process_summary/process_summary.go
index cc8d5e385525..b49f9b30d6ee 100644
--- a/metricbeat/module/system/process_summary/process_summary.go
+++ b/metricbeat/module/system/process_summary/process_summary.go
@@ -30,6 +30,7 @@ import (
 	"github.com/elastic/beats/v7/libbeat/common/transform/typeconv"
 	"github.com/elastic/beats/v7/metricbeat/mb"
 	"github.com/elastic/beats/v7/metricbeat/mb/parse"
+	"github.com/elastic/elastic-agent-libs/logp"
 	"github.com/elastic/elastic-agent-libs/mapstr"
 	"github.com/elastic/elastic-agent-system-metrics/metric/system/process"
 	"github.com/elastic/elastic-agent-system-metrics/metric/system/resolve"
@@ -50,7 +51,8 @@ func init() {
 // multiple fetch calls.
 type MetricSet struct {
 	mb.BaseMetricSet
-	sys resolve.Resolver
+	sys              resolve.Resolver
+	degradeOnPartial bool
 }
 
 // New create a new instance of the MetricSet
@@ -58,6 +60,12 @@ type MetricSet struct {
 // configuration entries if needed.
 func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
 	sys := base.Module().(resolve.Resolver)
+	degradedConf := struct {
+		DegradeOnPartial bool `config:"degrade_on_partial"`
+	}{}
+	if err := base.Module().UnpackConfig(&degradedConf); err != nil {
+		logp.L().Warnf("Failed to unpack config; degraded mode will be disabled for partial metrics: %v", err)
+	}
 	return &MetricSet{
 		BaseMetricSet: base,
 		sys:           sys,
@@ -73,7 +81,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 	if degradeErr != nil && !errors.Is(degradeErr, process.NonFatalErr{}) {
 		// return only if the error is fatal in nature
 		return fmt.Errorf("error fetching process list: %w", degradeErr)
-	} else if (degradeErr != nil && errors.Is(degradeErr, process.NonFatalErr{})) {
+	} else if (degradeErr != nil && errors.Is(degradeErr, process.NonFatalErr{}) && !m.degradeOnPartial) {
 		degradeErr = mb.PartialMetricsError{Err: degradeErr}
 	}
 

From f9e773929c3b411bff371263f92cee8d0f6abfe6 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Tue, 31 Dec 2024 18:25:50 +0530
Subject: [PATCH 2/9] doc and test cases

---
 metricbeat/docs/modules/system.asciidoc       |  3 ++
 metricbeat/mb/event.go                        |  8 +++++
 metricbeat/metricbeat.reference.yml           |  3 ++
 .../module/system/_meta/config.reference.yml  |  3 ++
 metricbeat/module/system/_meta/config.yml     |  1 +
 metricbeat/module/system/process/process.go   | 10 +++++--
 .../module/system/process/process_test.go     | 29 +++++++++++++++++++
 .../system/process_summary/process_summary.go | 15 +++++++---
 .../process_summary/process_summary_test.go   | 22 ++++++++++++++
 metricbeat/modules.d/system.yml               |  1 +
 x-pack/metricbeat/metricbeat.reference.yml    |  3 ++
 11 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc
index 93975cdeb6ad..e71015f0e2a1 100644
--- a/metricbeat/docs/modules/system.asciidoc
+++ b/metricbeat/docs/modules/system.asciidoc
@@ -270,6 +270,9 @@ metricbeat.modules:
   # Only effective for Windows.
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
+
+  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  #degrade_on_partial: false
 ----
 
 [float]
diff --git a/metricbeat/mb/event.go b/metricbeat/mb/event.go
index fb6907b6396f..7bcedf352698 100644
--- a/metricbeat/mb/event.go
+++ b/metricbeat/mb/event.go
@@ -223,9 +223,17 @@ type PartialMetricsError struct {
 }
 
 func (p PartialMetricsError) Error() string {
+	if p.Err == nil {
+		return "Partial metrics error"
+	}
 	return p.Err.Error()
 }
 
+func (p PartialMetricsError) Is(other error) bool {
+	_, is := other.(PartialMetricsError)
+	return is
+}
+
 func (p PartialMetricsError) Unwrap() error {
 	return p.Err
 }
diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml
index 7c36aa15743b..a342d73258d3 100644
--- a/metricbeat/metricbeat.reference.yml
+++ b/metricbeat/metricbeat.reference.yml
@@ -147,6 +147,9 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
+  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  #degrade_on_partial: false
+
 #------------------------------ Aerospike Module ------------------------------
 - module: aerospike
   metricsets: ["namespace"]
diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml
index bd8b64f10fe8..41ec3634da81 100644
--- a/metricbeat/module/system/_meta/config.reference.yml
+++ b/metricbeat/module/system/_meta/config.reference.yml
@@ -86,3 +86,6 @@
   # Only effective for Windows.
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
+
+  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  #degrade_on_partial: false
diff --git a/metricbeat/module/system/_meta/config.yml b/metricbeat/module/system/_meta/config.yml
index 4f3a66dcfa90..f48f318182e7 100644
--- a/metricbeat/module/system/_meta/config.yml
+++ b/metricbeat/module/system/_meta/config.yml
@@ -17,6 +17,7 @@
   process.include_top_n:
     by_cpu: 5      # include top 5 processes by CPU
     by_memory: 5   # include top 5 processes by memory
+  degrade_on_partial: false # mark metricset as degraded if partial metrics are emitted 
 # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container
 # hostfs: "/hostfs"
 
diff --git a/metricbeat/module/system/process/process.go b/metricbeat/module/system/process/process.go
index c3fb72d0e51c..c00e60f6bfd6 100644
--- a/metricbeat/module/system/process/process.go
+++ b/metricbeat/module/system/process/process.go
@@ -125,7 +125,10 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 		if err != nil && !errors.Is(err, process.NonFatalErr{}) {
 			// return only if the error is fatal in nature
 			return fmt.Errorf("process stats: %w", err)
-		} else if (err != nil && errors.Is(err, process.NonFatalErr{}) && !m.degradeOnPartial) {
+		} else if (err != nil && errors.Is(err, process.NonFatalErr{})) {
+			if m.degradeOnPartial {
+				return fmt.Errorf("error fetching process list: %w", err)
+			}
 			err = mb.PartialMetricsError{Err: err}
 		}
 
@@ -144,7 +147,10 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 		if err != nil && !errors.Is(err, process.NonFatalErr{}) {
 			// return only if the error is fatal in nature
 			return fmt.Errorf("error fetching pid %d: %w", m.setpid, err)
-		} else if (err != nil && errors.Is(err, process.NonFatalErr{}) && !m.degradeOnPartial) {
+		} else if (err != nil && errors.Is(err, process.NonFatalErr{})) {
+			if m.degradeOnPartial {
+				return fmt.Errorf("error fetching process list: %w", err)
+			}
 			err = mb.PartialMetricsError{Err: err}
 		}
 		// if error is non-fatal, emit partial metrics.
diff --git a/metricbeat/module/system/process/process_test.go b/metricbeat/module/system/process/process_test.go
index 18841b68c09e..2cea940fcc30 100644
--- a/metricbeat/module/system/process/process_test.go
+++ b/metricbeat/module/system/process/process_test.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 
+	"github.com/elastic/beats/v7/metricbeat/mb"
 	mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"
 	_ "github.com/elastic/beats/v7/metricbeat/module/system"
 	"github.com/elastic/elastic-agent-libs/logp"
@@ -55,6 +56,34 @@ func TestFetch(t *testing.T) {
 		events[0].BeatEvent("system", "process").Fields.StringToPrint())
 }
 
+func TestFetchDegradeOnPartial(t *testing.T) {
+	logp.DevelopmentSetup()
+	config := getConfig()
+	config["degrade_on_partial"] = true
+
+	f := mbtest.NewReportingMetricSetV2Error(t, config)
+	events, errs := mbtest.ReportingFetchV2Error(f)
+	if len(errs) > 0 {
+		for _, err := range errs {
+			assert.NotErrorIsf(t, err, mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
+		}
+	} else {
+		assert.NotEmpty(t, events)
+
+		time.Sleep(2 * time.Second)
+
+		events, errs = mbtest.ReportingFetchV2Error(f)
+		for _, err := range errs {
+			assert.ErrorIsf(t, err, process.NonFatalErr{}, "Expected non-fatal error, got %v", err)
+		}
+		assert.NotEmpty(t, events)
+
+		t.Logf("fetched %d events, showing events[0]:", len(events))
+		t.Logf("%s/%s event: %+v", f.Module().Name(), f.Name(),
+			events[0].BeatEvent("system", "process").Fields.StringToPrint())
+	}
+}
+
 func TestFetchSinglePid(t *testing.T) {
 	logp.DevelopmentSetup()
 
diff --git a/metricbeat/module/system/process_summary/process_summary.go b/metricbeat/module/system/process_summary/process_summary.go
index b49f9b30d6ee..69c08c957e74 100644
--- a/metricbeat/module/system/process_summary/process_summary.go
+++ b/metricbeat/module/system/process_summary/process_summary.go
@@ -59,7 +59,10 @@ type MetricSet struct {
 // Part of new is also setting up the configuration by processing additional
 // configuration entries if needed.
 func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
-	sys := base.Module().(resolve.Resolver)
+	sys, ok := base.Module().(resolve.Resolver)
+	if !ok {
+		return nil, fmt.Errorf("resolver cannot be cast from the module")
+	}
 	degradedConf := struct {
 		DegradeOnPartial bool `config:"degrade_on_partial"`
 	}{}
@@ -67,8 +70,9 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
 		logp.L().Warnf("Failed to unpack config; degraded mode will be disabled for partial metrics: %v", err)
 	}
 	return &MetricSet{
-		BaseMetricSet: base,
-		sys:           sys,
+		BaseMetricSet:    base,
+		sys:              sys,
+		degradeOnPartial: degradedConf.DegradeOnPartial,
 	}, nil
 }
 
@@ -81,7 +85,10 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error {
 	if degradeErr != nil && !errors.Is(degradeErr, process.NonFatalErr{}) {
 		// return only if the error is fatal in nature
 		return fmt.Errorf("error fetching process list: %w", degradeErr)
-	} else if (degradeErr != nil && errors.Is(degradeErr, process.NonFatalErr{}) && !m.degradeOnPartial) {
+	} else if (degradeErr != nil && errors.Is(degradeErr, process.NonFatalErr{})) {
+		if m.degradeOnPartial {
+			return fmt.Errorf("error fetching process list: %w", degradeErr)
+		}
 		degradeErr = mb.PartialMetricsError{Err: degradeErr}
 	}
 
diff --git a/metricbeat/module/system/process_summary/process_summary_test.go b/metricbeat/module/system/process_summary/process_summary_test.go
index 042148f37133..9261ee2ebfdb 100644
--- a/metricbeat/module/system/process_summary/process_summary_test.go
+++ b/metricbeat/module/system/process_summary/process_summary_test.go
@@ -25,6 +25,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
+	"github.com/elastic/beats/v7/metricbeat/mb"
 	mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"
 	_ "github.com/elastic/beats/v7/metricbeat/module/system"
 	"github.com/elastic/elastic-agent-libs/logp"
@@ -58,6 +59,27 @@ func TestFetch(t *testing.T) {
 	require.NoError(t, err)
 
 }
+func TestFetchDegradeOnPartial(t *testing.T) {
+	logp.DevelopmentSetup()
+	config := getConfig()
+	config["degrade_on_partial"] = true
+
+	f := mbtest.NewReportingMetricSetV2Error(t, config)
+	events, errs := mbtest.ReportingFetchV2Error(f)
+	if len(errs) > 0 {
+		for _, err := range errs {
+			assert.NotErrorIsf(t, err, mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
+		}
+	} else {
+		require.NotEmpty(t, events)
+		event := events[0].BeatEvent("system", "process_summary").Fields
+		t.Logf("%s/%s event: %+v", f.Module().Name(), f.Name(),
+			event.StringToPrint())
+
+		_, err := event.GetValue("system.process.summary")
+		require.NoError(t, err)
+	}
+}
 
 func TestStateNames(t *testing.T) {
 	logp.DevelopmentSetup()
diff --git a/metricbeat/modules.d/system.yml b/metricbeat/modules.d/system.yml
index 4123ea00f332..20cd4564033a 100644
--- a/metricbeat/modules.d/system.yml
+++ b/metricbeat/modules.d/system.yml
@@ -20,6 +20,7 @@
   process.include_top_n:
     by_cpu: 5      # include top 5 processes by CPU
     by_memory: 5   # include top 5 processes by memory
+  degrade_on_partial: false # mark metricset as degraded if partial metrics are emitted 
 # Configure the mount point of the host’s filesystem for use in monitoring a host from within a container
 # hostfs: "/hostfs"
 
diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml
index dd246a629417..64a85168dc49 100644
--- a/x-pack/metricbeat/metricbeat.reference.yml
+++ b/x-pack/metricbeat/metricbeat.reference.yml
@@ -147,6 +147,9 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
+  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  #degrade_on_partial: false
+
 #------------------------------- ActiveMQ Module -------------------------------
 - module: activemq
   metricsets: ['broker', 'queue', 'topic']

From d88dc3ebaa83acda5ba03007e04a53e1dec501e8 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Tue, 31 Dec 2024 18:40:06 +0530
Subject: [PATCH 3/9] lint

---
 .../module/system/process_summary/process_summary_test.go      | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/metricbeat/module/system/process_summary/process_summary_test.go b/metricbeat/module/system/process_summary/process_summary_test.go
index 9261ee2ebfdb..7c8a0c6b4502 100644
--- a/metricbeat/module/system/process_summary/process_summary_test.go
+++ b/metricbeat/module/system/process_summary/process_summary_test.go
@@ -102,7 +102,8 @@ func TestStateNames(t *testing.T) {
 	assert.NotZero(t, event["total"])
 
 	var sum int
-	total := event["total"].(int)
+	total, ok := event["total"].(int)
+	require.Truef(t, ok, "Expected int got %T", event["total"])
 	for key, val := range event {
 		if key == "total" {
 			continue

From 1a4461d9f1178f462c3a7065069e6555a194d2a6 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Thu, 2 Jan 2025 17:12:54 +0530
Subject: [PATCH 4/9] remove errors.Is

---
 metricbeat/mb/event.go                                       | 5 -----
 metricbeat/module/system/process/process_test.go             | 2 +-
 .../module/system/process_summary/process_summary_test.go    | 2 +-
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/metricbeat/mb/event.go b/metricbeat/mb/event.go
index 7bcedf352698..8f8aca9edf03 100644
--- a/metricbeat/mb/event.go
+++ b/metricbeat/mb/event.go
@@ -229,11 +229,6 @@ func (p PartialMetricsError) Error() string {
 	return p.Err.Error()
 }
 
-func (p PartialMetricsError) Is(other error) bool {
-	_, is := other.(PartialMetricsError)
-	return is
-}
-
 func (p PartialMetricsError) Unwrap() error {
 	return p.Err
 }
diff --git a/metricbeat/module/system/process/process_test.go b/metricbeat/module/system/process/process_test.go
index 2cea940fcc30..d8b8461973ca 100644
--- a/metricbeat/module/system/process/process_test.go
+++ b/metricbeat/module/system/process/process_test.go
@@ -65,7 +65,7 @@ func TestFetchDegradeOnPartial(t *testing.T) {
 	events, errs := mbtest.ReportingFetchV2Error(f)
 	if len(errs) > 0 {
 		for _, err := range errs {
-			assert.NotErrorIsf(t, err, mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
+			assert.NotErrorIsf(t, err, &mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
 		}
 	} else {
 		assert.NotEmpty(t, events)
diff --git a/metricbeat/module/system/process_summary/process_summary_test.go b/metricbeat/module/system/process_summary/process_summary_test.go
index 7c8a0c6b4502..48dbf09cfe3e 100644
--- a/metricbeat/module/system/process_summary/process_summary_test.go
+++ b/metricbeat/module/system/process_summary/process_summary_test.go
@@ -68,7 +68,7 @@ func TestFetchDegradeOnPartial(t *testing.T) {
 	events, errs := mbtest.ReportingFetchV2Error(f)
 	if len(errs) > 0 {
 		for _, err := range errs {
-			assert.NotErrorIsf(t, err, mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
+			assert.NotErrorIsf(t, err, &mb.PartialMetricsError{}, "Expected non-fatal error, got %v", err)
 		}
 	} else {
 		require.NotEmpty(t, events)

From 3bcf204d3b075b1aa8f79148c0214abdbbb71e9c Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Thu, 2 Jan 2025 18:13:53 +0530
Subject: [PATCH 5/9] chore: notice

---
 NOTICE.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NOTICE.txt b/NOTICE.txt
index 4b244c27a5ec..702bc9e7d49d 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Elastic Beats
-Copyright 2014-2024 Elasticsearch BV
+Copyright 2014-2025 Elasticsearch BV
 
 This product includes software developed by The Apache Software 
 Foundation (http://www.apache.org/).

From 09879672f68a823db2f483b2ea9ab9cbbbf522f2 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Thu, 16 Jan 2025 14:28:32 +0530
Subject: [PATCH 6/9] update docs

---
 metricbeat/docs/modules/system.asciidoc             | 11 ++++++++++-
 metricbeat/metricbeat.reference.yml                 | 11 ++++++++++-
 metricbeat/module/system/_meta/config.reference.yml | 11 ++++++++++-
 x-pack/metricbeat/metricbeat.reference.yml          | 11 ++++++++++-
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc
index e71015f0e2a1..a25ddf81eeb4 100644
--- a/metricbeat/docs/modules/system.asciidoc
+++ b/metricbeat/docs/modules/system.asciidoc
@@ -271,7 +271,16 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  # While running in unprivileged mode, process/process_summary metricsets can emit
+  # partial metrics. Some metrics that require privileged access can be missing.
+  # On Windows, non-administrator users may not be able to access protected processes, leading 
+  # to missing details like command line and arguments. On Unix, non-root users can't access 
+  # procfs without the right permissions. 
+  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
+  # Enabling the config below will mark the metricset as degraded when this occurs.
+  # You may want to enable it to identify potential permission-related issues.
+  # If you're unable to provide the necessary access, you can disable this config to keep
+  # metricsets healthy.
   #degrade_on_partial: false
 ----
 
diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml
index a342d73258d3..cb40d76ffea8 100644
--- a/metricbeat/metricbeat.reference.yml
+++ b/metricbeat/metricbeat.reference.yml
@@ -147,7 +147,16 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  # While running in unprivileged mode, process/process_summary metricsets can emit
+  # partial metrics. Some metrics that require privileged access can be missing.
+  # On Windows, non-administrator users may not be able to access protected processes, leading 
+  # to missing details like command line and arguments. On Unix, non-root users can't access 
+  # procfs without the right permissions. 
+  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
+  # Enabling the config below will mark the metricset as degraded when this occurs.
+  # You may want to enable it to identify potential permission-related issues.
+  # If you're unable to provide the necessary access, you can disable this config to keep
+  # metricsets healthy.
   #degrade_on_partial: false
 
 #------------------------------ Aerospike Module ------------------------------
diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml
index 41ec3634da81..fd9159d8ff1d 100644
--- a/metricbeat/module/system/_meta/config.reference.yml
+++ b/metricbeat/module/system/_meta/config.reference.yml
@@ -87,5 +87,14 @@
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  # While running in unprivileged mode, process/process_summary metricsets can emit
+  # partial metrics. Some metrics that require privileged access can be missing.
+  # On Windows, non-administrator users may not be able to access protected processes, leading 
+  # to missing details like command line and arguments. On Unix, non-root users can't access 
+  # procfs without the right permissions. 
+  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
+  # Enabling the config below will mark the metricset as degraded when this occurs.
+  # You may want to enable it to identify potential permission-related issues.
+  # If you're unable to provide the necessary access, you can disable this config to keep
+  # metricsets healthy.
   #degrade_on_partial: false
diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml
index 64a85168dc49..2c3b3bb86ea4 100644
--- a/x-pack/metricbeat/metricbeat.reference.yml
+++ b/x-pack/metricbeat/metricbeat.reference.yml
@@ -147,7 +147,16 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # Enable below config to mark metricset as degraded if partial metrics are emitted 
+  # While running in unprivileged mode, process/process_summary metricsets can emit
+  # partial metrics. Some metrics that require privileged access can be missing.
+  # On Windows, non-administrator users may not be able to access protected processes, leading 
+  # to missing details like command line and arguments. On Unix, non-root users can't access 
+  # procfs without the right permissions. 
+  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
+  # Enabling the config below will mark the metricset as degraded when this occurs.
+  # You may want to enable it to identify potential permission-related issues.
+  # If you're unable to provide the necessary access, you can disable this config to keep
+  # metricsets healthy.
   #degrade_on_partial: false
 
 #------------------------------- ActiveMQ Module -------------------------------

From b70c4119e77a42c32f7c8d5d3ee8e4361513b682 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <121151420+VihasMakwana@users.noreply.github.com>
Date: Thu, 16 Jan 2025 21:24:36 +0530
Subject: [PATCH 7/9] Update metricbeat/mb/event.go

Co-authored-by: Craig MacKenzie <craig.mackenzie@elastic.co>
---
 metricbeat/mb/event.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/metricbeat/mb/event.go b/metricbeat/mb/event.go
index 8f8aca9edf03..ebd0af668e94 100644
--- a/metricbeat/mb/event.go
+++ b/metricbeat/mb/event.go
@@ -224,7 +224,7 @@ type PartialMetricsError struct {
 
 func (p PartialMetricsError) Error() string {
 	if p.Err == nil {
-		return "Partial metrics error"
+		return ""
 	}
 	return p.Err.Error()
 }

From d83ebc902c35358aa84fbbc7f8d8c3a5a9b3fac9 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Thu, 16 Jan 2025 21:46:06 +0530
Subject: [PATCH 8/9] remove references

---
 metricbeat/docs/modules/system.asciidoc             | 12 ------------
 metricbeat/metricbeat.reference.yml                 | 12 ------------
 metricbeat/module/system/_meta/config.reference.yml | 12 ------------
 x-pack/metricbeat/metricbeat.reference.yml          | 12 ------------
 4 files changed, 48 deletions(-)

diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc
index a25ddf81eeb4..93975cdeb6ad 100644
--- a/metricbeat/docs/modules/system.asciidoc
+++ b/metricbeat/docs/modules/system.asciidoc
@@ -270,18 +270,6 @@ metricbeat.modules:
   # Only effective for Windows.
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
-
-  # While running in unprivileged mode, process/process_summary metricsets can emit
-  # partial metrics. Some metrics that require privileged access can be missing.
-  # On Windows, non-administrator users may not be able to access protected processes, leading 
-  # to missing details like command line and arguments. On Unix, non-root users can't access 
-  # procfs without the right permissions. 
-  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
-  # Enabling the config below will mark the metricset as degraded when this occurs.
-  # You may want to enable it to identify potential permission-related issues.
-  # If you're unable to provide the necessary access, you can disable this config to keep
-  # metricsets healthy.
-  #degrade_on_partial: false
 ----
 
 [float]
diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml
index cb40d76ffea8..7c36aa15743b 100644
--- a/metricbeat/metricbeat.reference.yml
+++ b/metricbeat/metricbeat.reference.yml
@@ -147,18 +147,6 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # While running in unprivileged mode, process/process_summary metricsets can emit
-  # partial metrics. Some metrics that require privileged access can be missing.
-  # On Windows, non-administrator users may not be able to access protected processes, leading 
-  # to missing details like command line and arguments. On Unix, non-root users can't access 
-  # procfs without the right permissions. 
-  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
-  # Enabling the config below will mark the metricset as degraded when this occurs.
-  # You may want to enable it to identify potential permission-related issues.
-  # If you're unable to provide the necessary access, you can disable this config to keep
-  # metricsets healthy.
-  #degrade_on_partial: false
-
 #------------------------------ Aerospike Module ------------------------------
 - module: aerospike
   metricsets: ["namespace"]
diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml
index fd9159d8ff1d..bd8b64f10fe8 100644
--- a/metricbeat/module/system/_meta/config.reference.yml
+++ b/metricbeat/module/system/_meta/config.reference.yml
@@ -86,15 +86,3 @@
   # Only effective for Windows.
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
-
-  # While running in unprivileged mode, process/process_summary metricsets can emit
-  # partial metrics. Some metrics that require privileged access can be missing.
-  # On Windows, non-administrator users may not be able to access protected processes, leading 
-  # to missing details like command line and arguments. On Unix, non-root users can't access 
-  # procfs without the right permissions. 
-  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
-  # Enabling the config below will mark the metricset as degraded when this occurs.
-  # You may want to enable it to identify potential permission-related issues.
-  # If you're unable to provide the necessary access, you can disable this config to keep
-  # metricsets healthy.
-  #degrade_on_partial: false
diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml
index 2c3b3bb86ea4..dd246a629417 100644
--- a/x-pack/metricbeat/metricbeat.reference.yml
+++ b/x-pack/metricbeat/metricbeat.reference.yml
@@ -147,18 +147,6 @@ metricbeat.modules:
   # You should use this option if running beats on machins with more than 64 cores.
   #use_performance_counters: false
 
-  # While running in unprivileged mode, process/process_summary metricsets can emit
-  # partial metrics. Some metrics that require privileged access can be missing.
-  # On Windows, non-administrator users may not be able to access protected processes, leading 
-  # to missing details like command line and arguments. On Unix, non-root users can't access 
-  # procfs without the right permissions. 
-  # Errors like ERROR_ACCESS_DENIED, EPERM, and EACCESS may result in partial metrics. 
-  # Enabling the config below will mark the metricset as degraded when this occurs.
-  # You may want to enable it to identify potential permission-related issues.
-  # If you're unable to provide the necessary access, you can disable this config to keep
-  # metricsets healthy.
-  #degrade_on_partial: false
-
 #------------------------------- ActiveMQ Module -------------------------------
 - module: activemq
   metricsets: ['broker', 'queue', 'topic']

From 89f38510db6fe0d0ab1d4e0a4895227092c5e179 Mon Sep 17 00:00:00 2001
From: Vihas Makwana <vihas.makwana@elastic.co>
Date: Fri, 17 Jan 2025 16:24:41 +0530
Subject: [PATCH 9/9] remove sleep

---
 metricbeat/module/system/process/process_test.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/metricbeat/module/system/process/process_test.go b/metricbeat/module/system/process/process_test.go
index d8b8461973ca..8920d0d0efef 100644
--- a/metricbeat/module/system/process/process_test.go
+++ b/metricbeat/module/system/process/process_test.go
@@ -70,8 +70,6 @@ func TestFetchDegradeOnPartial(t *testing.T) {
 	} else {
 		assert.NotEmpty(t, events)
 
-		time.Sleep(2 * time.Second)
-
 		events, errs = mbtest.ReportingFetchV2Error(f)
 		for _, err := range errs {
 			assert.ErrorIsf(t, err, process.NonFatalErr{}, "Expected non-fatal error, got %v", err)