From 69880a317a6d0079f9b9ba033da7483c9f4da265 Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:31:45 -0800 Subject: [PATCH] Add procs running (#33614) * start adding thread counts * finish adding thread metrics to process_summary * add changelog * fix test * fix CI * still fixing CI --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 24 +++++++++ metricbeat/module/system/fields.go | 2 +- .../system/process_summary/_meta/data.json | 10 ++-- .../system/process_summary/_meta/fields.yml | 11 ++++ .../process_summary/_meta/testdata/proc/stat | 20 ++++++++ .../system/process_summary/process_summary.go | 51 +++++++++++++++++-- .../process_summary/process_summary_test.go | 21 ++++++-- 8 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 metricbeat/module/system/process_summary/_meta/testdata/proc/stat diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 1f5127cda30..42685e384ec 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -172,6 +172,7 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff] - Add Data Granularity option to AWS module to allow for for fewer API calls of longer periods and keep small intervals. {issue}33133[33133] {pull}33166[33166] - Update README file on how to run Metricbeat on Kubernetes. {pull}33308[33308] +- Add per-thread metrics to system_summary {pull}33614[33614] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 6251287b33c..42151251891 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -63063,6 +63063,30 @@ type: long Number of processes for which the state couldn't be retrieved or is unknown. +type: long + +-- + +[float] +=== threads + +Counts of individual threads on a system. + + +*`system.process.summary.threads.running`*:: ++ +-- +Count of currently running threads. + +type: long + +-- + +*`system.process.summary.threads.blocked`*:: ++ +-- +Count of threads blocked by I/O. + type: long -- diff --git a/metricbeat/module/system/fields.go b/metricbeat/module/system/fields.go index 76225cbdb26..13bc793b2b3 100644 --- a/metricbeat/module/system/fields.go +++ b/metricbeat/module/system/fields.go @@ -32,5 +32,5 @@ func init() { // AssetSystem returns asset data. // This is the base64 encoded zlib format compressed contents of module/system. func AssetSystem() string { - return "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" + return "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" } diff --git a/metricbeat/module/system/process_summary/_meta/data.json b/metricbeat/module/system/process_summary/_meta/data.json index d1af140066f..1f076ab493c 100644 --- a/metricbeat/module/system/process_summary/_meta/data.json +++ b/metricbeat/module/system/process_summary/_meta/data.json @@ -15,10 +15,14 @@ "system": { "process": { "summary": { - "idle": 122, + "idle": 110, "running": 1, - "sleeping": 222, - "total": 345 + "sleeping": 138, + "threads": { + "blocked": 0, + "running": 2 + }, + "total": 249 } } } diff --git a/metricbeat/module/system/process_summary/_meta/fields.yml b/metricbeat/module/system/process_summary/_meta/fields.yml index 9f9fadf8c1b..f1361aff152 100644 --- a/metricbeat/module/system/process_summary/_meta/fields.yml +++ b/metricbeat/module/system/process_summary/_meta/fields.yml @@ -49,3 +49,14 @@ type: long description: > Number of processes for which the state couldn't be retrieved or is unknown. + - name: threads + title: Process Threads + type: group + description: Counts of individual threads on a system. + fields: + - name: running + type: long + description: Count of currently running threads. + - name: blocked + type: long + description: Count of threads blocked by I/O. \ No newline at end of file diff --git a/metricbeat/module/system/process_summary/_meta/testdata/proc/stat b/metricbeat/module/system/process_summary/_meta/testdata/proc/stat new file mode 100644 index 00000000000..03f19e5dd46 --- /dev/null +++ b/metricbeat/module/system/process_summary/_meta/testdata/proc/stat @@ -0,0 +1,20 @@ +cpu 1958638 6202 264378 107797637 610519 48962 29230 0 0 0 +cpu0 202944 915 25801 8936097 52700 4560 2877 0 0 0 +cpu1 177481 161 24227 8962725 51442 4397 2880 0 0 0 +cpu2 163745 223 22570 8981414 51892 3899 2866 0 0 0 +cpu3 166884 667 22302 8982047 49632 3841 1990 0 0 0 +cpu4 162061 1532 22361 8983333 51060 4063 2514 0 0 0 +cpu5 164845 1064 23137 8982450 47903 4178 2832 0 0 0 +cpu6 128551 121 16962 9024912 49464 3859 2271 0 0 0 +cpu7 152482 50 19820 8998298 49329 4045 2168 0 0 0 +cpu8 160705 494 21774 8988485 48981 4108 2170 0 0 0 +cpu9 163737 399 23160 8970031 62795 4192 2188 0 0 0 +cpu10 158907 233 20849 8991461 49155 3932 2074 0 0 0 +cpu11 156288 339 21410 8996378 46160 3882 2394 0 0 0 +intr 87587498 33 0 0 0 0 0 0 0 1 0 285 0 0 0 0 0 0 0 0 0 0 0 34 159 0 0 0 0 0 0 0 0 0 0 0 0 0 45137 0 226 134037 135047 117182 116322 117562 142962 104763 122559 114616 110349 105725 123676 0 0 0 0 0 163501 138328 95724 141345 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +ctxt 104885124 +btime 1667843900 +processes 319096 +procs_running 3 +procs_blocked 1 +softirq 58311163 7 11951252 388 1078388 45103 0 2624 20249646 917 24982838 diff --git a/metricbeat/module/system/process_summary/process_summary.go b/metricbeat/module/system/process_summary/process_summary.go index 76de5443d9f..2fdf850b530 100644 --- a/metricbeat/module/system/process_summary/process_summary.go +++ b/metricbeat/module/system/process_summary/process_summary.go @@ -21,7 +21,11 @@ package process_summary import ( - "github.com/pkg/errors" + "fmt" + "io/ioutil" + "runtime" + "strconv" + "strings" "github.com/elastic/beats/v7/libbeat/common/transform/typeconv" "github.com/elastic/beats/v7/metricbeat/mb" @@ -67,7 +71,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error { procList, err := process.ListStates(m.sys) if err != nil { - return errors.Wrap(err, "error fetching process list") + return fmt.Errorf("error fetching process list: %w", err) } procStates := map[string]int{} @@ -80,7 +84,17 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error { } outMap := mapstr.M{} - typeconv.Convert(&outMap, procStates) + err = typeconv.Convert(&outMap, procStates) + if err != nil { + return fmt.Errorf("error formatting process stats: %w", err) + } + if runtime.GOOS == "linux" { + threads, err := threadStats(m.sys) + if err != nil { + return fmt.Errorf("error fetching thread stats: %w", err) + } + outMap["threads"] = threads + } outMap["total"] = len(procList) r.Event(mb.Event{ // change the name space to use . instead of _ @@ -90,3 +104,34 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) error { return nil } + +// threadStats returns a map of state counts for running threads on a system +func threadStats(sys resolve.Resolver) (mapstr.M, error) { + statPath := sys.ResolveHostFS("/proc/stat") + procData, err := ioutil.ReadFile(statPath) + if err != nil { + return nil, fmt.Errorf("error reading procfs file %s: %w", statPath, err) + } + threadData := mapstr.M{} + for _, line := range strings.Split(string(procData), "\n") { + // look for format procs_[STATE] [COUNT] + fields := strings.Fields(line) + if len(fields) < 2 { + continue + } + if strings.Contains(fields[0], "procs_") { + keyFields := strings.Split(fields[0], "_") + // the field isn't what we're expecting, continue + if len(keyFields) < 2 { + continue + } + procsInt, err := strconv.ParseInt(fields[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing value %s from %s: %w", fields[0], statPath, err) + } + + threadData[keyFields[1]] = procsInt + } + } + return threadData, nil +} diff --git a/metricbeat/module/system/process_summary/process_summary_test.go b/metricbeat/module/system/process_summary/process_summary_test.go index eaf03413d2c..6d42704e196 100644 --- a/metricbeat/module/system/process_summary/process_summary_test.go +++ b/metricbeat/module/system/process_summary/process_summary_test.go @@ -31,6 +31,7 @@ import ( "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" ) func TestData(t *testing.T) { @@ -42,7 +43,8 @@ func TestData(t *testing.T) { } func TestFetch(t *testing.T) { - logp.DevelopmentSetup() + err := logp.DevelopmentSetup() + require.NoError(t, err) f := mbtest.NewReportingMetricSetV2Error(t, getConfig()) events, errs := mbtest.ReportingFetchV2Error(f) @@ -52,13 +54,14 @@ func TestFetch(t *testing.T) { t.Logf("%s/%s event: %+v", f.Module().Name(), f.Name(), event.StringToPrint()) - _, err := event.GetValue("system.process.summary") + _, err = event.GetValue("system.process.summary") require.NoError(t, err) } func TestStateNames(t *testing.T) { - logp.DevelopmentSetup() + err := logp.DevelopmentSetup() + require.NoError(t, err) f := mbtest.NewReportingMetricSetV2Error(t, getConfig()) events, errs := mbtest.ReportingFetchV2Error(f) @@ -81,6 +84,9 @@ func TestStateNames(t *testing.T) { if key == "total" { continue } + if _, ok := val.(int); !ok { + continue + } // Check to make sure the values we got actually exist exists := false for _, proc := range process.PidStates { @@ -97,6 +103,15 @@ func TestStateNames(t *testing.T) { } +func TestThreads(t *testing.T) { + root := resolve.NewTestResolver("_meta/testdata") + stats, err := threadStats(root) + require.NoError(t, err) + require.Equal(t, int64(1), stats["blocked"]) + require.Equal(t, int64(3), stats["running"]) + t.Logf("metrics: %#v", stats) +} + func getConfig() map[string]interface{} { return map[string]interface{}{ "module": "system",