Skip to content

[cgv2] Add CPU CFS quota, period, and weight metrics#281

Merged
orestisfl merged 8 commits intoelastic:mainfrom
orestisfl:cgv2-cfs-metrics
Feb 26, 2026
Merged

[cgv2] Add CPU CFS quota, period, and weight metrics#281
orestisfl merged 8 commits intoelastic:mainfrom
orestisfl:cgv2-cfs-metrics

Conversation

@orestisfl
Copy link
Contributor

What does this PR do?

Add support for collecting CPU bandwidth control settings from cgroupv2:

  • cpu.max (quota and period in microseconds)
  • cpu.weight (relative weight, replaces shares from v1)

Why is it important?

This brings cgroupv2 to feature parity with cgroupv1 for CPU limit metrics.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have added an entry in CHANGELOG.md

Related issues

Add support for collecting CPU bandwidth control settings from cgroupv2:
- cpu.max (quota and period in microseconds)
- cpu.weight (relative weight, replaces shares from v1)

This brings cgroupv2 to feature parity with cgroupv1 for CPU limit metrics.
@orestisfl orestisfl self-assigned this Feb 10, 2026
@orestisfl orestisfl requested a review from a team as a code owner February 10, 2026 19:28
@orestisfl orestisfl requested review from AndersonQ and VihasMakwana and removed request for a team February 10, 2026 19:28
@orestisfl orestisfl added enhancement New feature or request Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team labels Feb 10, 2026
VihasMakwana
VihasMakwana previously approved these changes Feb 17, 2026
# Conflicts:
#	metric/system/cgroup/cgv2/v2_test.go
Replace opt.Us with a new UsOpt wrapper (analogous to opt.BytesOpt)
so that missing cpu.max files produce omitted fields rather than
misleading zeros. This distinguishes "file absent" (field omitted)
from "unlimited quota" (quota.us: 0).

Add TestCFSSerialization to verify the structform output for all cases.
orestisfl added a commit that referenced this pull request Feb 26, 2026
## What does this PR do?
encoding/json's omitempty is silently ignored on struct fields —
zero-valued structs are always serialized regardless of the tag. Go
1.24's omitzero fixes this by checking IsZero() or the zero value.

## Why is it important?

No downstream production code is affected (consumers use struct tags via
go-structform, not json tags), but this corrects a latent bug if these
types are ever json.Marshal'd directly.

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added tests that prove my fix is effective or that my
feature works

## Related issues

- Blocks
#281
The CFS, UsOpt, and opt.Uint fields added on this branch used
omitempty, which is silently ignored for structs by encoding/json.
Switch to omitzero (Go 1.24) consistent with the fix in elastic#288.

Refactor omitzero_test.go to table-driven style with exact key
equality via assert.Equal instead of Contains/NotContains.
@orestisfl orestisfl requested a review from AndersonQ February 26, 2026 09:11
@orestisfl
Copy link
Contributor Author

Applied changes from #288

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds support for collecting CPU bandwidth control settings from cgroupv2, achieving feature parity with cgroupv1 for CPU limit metrics. The changes introduce three new metrics from cgroup v2:

  • cpu.max - provides quota and period in microseconds
  • cpu.weight - provides relative CPU weight (replacing cpu.shares from v1)

Changes:

  • Added CFS (Completely Fair Scheduler) struct and UsOpt wrapper type to cgv2 package for CPU bandwidth control metrics
  • Implemented parsing logic for cpu.max (handling both limited quotas and unlimited/"max" values) and cpu.weight
  • Added comprehensive unit tests for parsing, serialization, and integration scenarios
  • Updated test data with cgroupv2 examples

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
metric/system/cgroup/cgv2/cpu.go Core implementation adding CFS struct, UsOpt wrapper, and parsing functions for cpu.max/cpu.weight
metric/system/cgroup/cgv2/v2_test.go Unit tests for parseCPUMax, getCFS, and serialization behavior
metric/system/cgroup/cgv2/omitzero_test.go Tests for JSON serialization with omitzero tags, refactored to table-driven format
metric/system/cgroup/reader_test.go Integration test verifying CFS metrics from testdata
metric/system/cgroup/testdata/docker.zip Binary test data containing cgroupv2 filesystem with cpu.max and cpu.weight files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@orestisfl orestisfl merged commit 69b8af0 into elastic:main Feb 26, 2026
9 checks passed
@orestisfl orestisfl deleted the cgv2-cfs-metrics branch February 26, 2026 15:11
orestisfl added a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```
mergify bot pushed a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)

# Conflicts:
#	metricbeat/module/system/fields.go
mergify bot pushed a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)
mergify bot pushed a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)
orestisfl added a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098) (#49399)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)

Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
orestisfl added a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098) (#49400)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)

Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
orestisfl added a commit to elastic/beats that referenced this pull request Mar 11, 2026
…s for zswap and cgroups v2 CPU CFS data (#49398)

* [Metricbeat] Bump elastic-agent-system-metrics for zswap and cgroups v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```

(cherry picked from commit eeabffa)

# Conflicts:
#	metricbeat/module/system/fields.go

* Resolve cherry-pick conflict by regenerating fields.go

The auto-generated metricbeat/module/system/fields.go had merge
conflict markers from the backport cherry-pick. Regenerated using
`mage fields` based on the successfully merged _meta/fields.yml files.

---------

Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
strawgate pushed a commit to elastic/beats that referenced this pull request Mar 11, 2026
…v2 CPU CFS data (#49098)

Bumps the elastic-agent-system-metrics dependency to [v0.14.3](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.3), [v0.14.2](https://github.com/elastic/elastic-agent-system-metrics/releases/tag/v0.14.2) also included.

### What's Changed
* Add Zswap Metrics by @orestisfl in elastic/elastic-agent-system-metrics#279
* PULL_REQUEST_TEMPLATE: Remove reference to non-existant CHANGELOG.md by @orestisfl in elastic/elastic-agent-system-metrics#286
* fix: remove shared context timeout from matrix tests by @orestisfl in elastic/elastic-agent-system-metrics#285
* Enable modernize linter and apply suggestions by @orestisfl in elastic/elastic-agent-system-metrics#287
* Use json omitzero for struct-typed fields in cgroup structs by @orestisfl in elastic/elastic-agent-system-metrics#288
* [cgv2] Add CPU CFS quota, period, and weight metrics by @orestisfl in elastic/elastic-agent-system-metrics#281
* Add missing zswap debug metrics by @orestisfl in elastic/elastic-agent-system-metrics#289

## Disruptive User Impact

None. New features.

## How to test this PR locally

1. Build metricbeat from the branch:

```bash
cd metricbeat
mage build
```

2. Create a test config file `metricbeat.test.yml`:

```yaml
metricbeat.modules:
  - module: system
    period: 5s
    metricsets:
      - memory
      - process
    process.include_top_n:
      by_cpu: 5
      by_memory: 5

output.console:
  pretty: true

logging.level: debug
```

3. Run metricbeat:

```bash
./metricbeat -e -c metricbeat.test.yml
```

4. Verify zswap memory metrics appear in the output (requires Linux with zswap enabled -- check with `cat /sys/module/zswap/parameters/enabled`):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "memory") | .system.memory.zswap'
```

Expected output (values will vary):

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976
}
```

5. To also verify the `zswap.debug.*` fields (requires debugfs access), grant the binary the `cap_dac_read_search` capability:

```bash
sudo setcap cap_dac_read_search=+ep metricbeat
```

Then re-run. Expected output with debug fields:

```json
{
  "compressed": 950353920,
  "uncompressed": 3813502976,
  "debug": {
    "decompress_fail": 0,
    "pool_limit_hit": 0,
    "pool_total_size": 950353920,
    "reject_alloc_fail": 0,
    "reject_compress_fail": 0,
    "reject_compress_poor": 0,
    "reject_kmemcache_fail": 0,
    "reject_reclaim_fail": 0,
    "stored_incompressible_pages": 16779,
    "stored_pages": 931031,
    "written_back_pages": 29111
  }
}
```

6. Verify `cfs.weight` appears in process cgroup metrics (requires cgroupsv2):

```bash
./metricbeat -e -c metricbeat.test.yml 2>/dev/null | jq 'select(.metricset.name == "process") | .system.process.cgroup.cpu.cfs.weight // empty'
```

7. Run unit tests:

```bash
cd metricbeat
go test ./module/system/...
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants