Skip to content

Add Zswap Metrics#279

Merged
orestisfl merged 14 commits intoelastic:mainfrom
orestisfl:zswap-metrics
Feb 16, 2026
Merged

Add Zswap Metrics#279
orestisfl merged 14 commits intoelastic:mainfrom
orestisfl:zswap-metrics

Conversation

@orestisfl
Copy link
Copy Markdown
Contributor

@orestisfl orestisfl commented Jan 26, 2026

What does this PR do?

Adds support for zswap tracking:

  1. From /proc/vmstat
  2. From /proc/meminfo
  3. From /sys/kernel/debug/zswap/
  4. From /sys/fs/cgroup/<cgroup name>/memory.stat

The testing here is not trivial because:

  1. zswap might be completely disabled at compile time: https://github.com/torvalds/linux/blob/1f97d9dcf53649c41c33227b345a36902cbb08ad/mm/memcontrol.c#L1346-L1348
  2. debugfs (/sys/kernel/debug/) might not be mounted at all
  3. Access to /sys/kernel/debug/ requires root

To deal with this situation, metric/memory/memory_integration_test.go decides on the expected result based on BUILDKITE_STEP_KEY. This makes it slightly harder to add new images to our pipeline (the ciExpectations map needs to be updated) but ensures we are actually reading zswap debug metrics somewhere in our tests.

Reviewer note: Please check my nesting of the debug metrics, it could be that we prefer them at the same level.

Why is it important?

Adds important kernel metrics of the zswap compressed swap backend. See elastic/beats#47605 for more info.

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

Testing Instructions

1. Local integration tests

All tests should run and succeed locally by default, if you want to check for actual access of all metrics, use:

$ go test -c ./metric/memory -o memory.test
$ sudo BUILDKITE_STEP_KEY=manual PRIVILEGED=1 ./memory.test -test.run TestMemoryFromContainer -test.v
=== RUN   TestMemoryFromContainer
    memory_integration_test.go:64: Total: 33323646976, Free: 4660809728, Used: 28662837248
    memory_integration_test.go:70: Zswap exists: true, Debug exists: true (BUILDKITE_STEP_KEY="manual")
    memory_integration_test.go:72: Zswap: Compressed=557056 bytes, Uncompressed=217088 bytes
    memory_integration_test.go:72: Zswap debug: StoredPages=53, PoolTotalSize=557056
--- PASS: TestMemoryFromContainer (0.00s)
PASS
$ sudo setcap cap_dac_read_search=+ep memory.test
$ BUILDKITE_STEP_KEY=manual PRIVILEGED=1 ./memory.test -test.run TestMemoryFromContainer -test.v
=== RUN   TestMemoryFromContainer
    memory_integration_test.go:67: Total: 33323646976, Free: 19951370240, Used: 13372276736
    memory_integration_test.go:73: Zswap exists: true, Debug exists: true (BUILDKITE_STEP_KEY="manual")
    memory_integration_test.go:75: Zswap: Compressed=430080 bytes, Uncompressed=106496 bytes
    memory_integration_test.go:75: Zswap debug: StoredPages=26, PoolTotalSize=430080
--- PASS: TestMemoryFromContainer (0.00s)
PASS

2. Metricbeat -- memory metricset

metricbeat.modules:
  - module: system
    period: 1s
    metricsets:
      - memory

output.console:
  pretty: true

Test this config:

  • With old elastic-agent-system-metrics
  • Without any extra permissions
  • With sudo
  • With sudo setcap cap_dac_read_search=+ep ./metricbeat
  • After sudo umount debugfs -> debug stats disabled
Before
{
  "@metadata": {
    "beat": "metricbeat",
    "type": "_doc",
    "version": "9.4.0"
  },
  "@timestamp": "2026-01-28T09:43:47.196Z",
  "agent": {
    "ephemeral_id": "1242f8a9-2768-4582-82e2-f1a605d4f182",
    "id": "8b35a267-5085-44a8-a82e-e43a4af9af11",
    "name": "laptop",
    "type": "metricbeat",
    "version": "9.4.0"
  },
  "ecs": {
    "version": "8.0.0"
  },
  "event": {
    "dataset": "system.memory",
    "duration": 127644,
    "module": "system"
  },
  "host": {
    "name": "laptop"
  },
  "metricset": {
    "name": "memory",
    "period": 1000
  },
  "service": {
    "type": "system"
  },
  "system": {
    "memory": {
      "actual": {
        "free": 18093944832,
        "used": {
          "bytes": 15229702144,
          "pct": 0.457
        }
      },
      "cached": 14415081472,
      "free": 6065573888,
      "swap": {
        "free": 20558376960,
        "total": 21474832384,
        "used": {
          "bytes": 916455424,
          "pct": 0.0427
        }
      },
      "total": 33323646976,
      "used": {
        "bytes": 27258073088,
        "pct": 0.818
      }
    }
  }
}
Unprivileged output
{
  "@metadata": {
    "beat": "metricbeat",
    "type": "_doc",
    "version": "9.4.0"
  },
  "@timestamp": "2026-01-28T09:41:08.897Z",
  "agent": {
    "ephemeral_id": "9aa025fc-2b19-4e40-82d5-7603b3da8b99",
    "id": "8b35a267-5085-44a8-a82e-e43a4af9af11",
    "name": "laptop",
    "type": "metricbeat",
    "version": "9.4.0"
  },
  "ecs": {
    "version": "8.0.0"
  },
  "event": {
    "dataset": "system.memory",
    "duration": 127572,
    "module": "system"
  },
  "host": {
    "name": "laptop"
  },
  "metricset": {
    "name": "memory",
    "period": 1000
  },
  "service": {
    "type": "system"
  },
  "system": {
    "memory": {
      "actual": {
        "free": 17940357120,
        "used": {
          "bytes": 15383289856,
          "pct": 0.4616
        }
      },
      "cached": 15113895936,
      "free": 5096550400,
      "swap": {
        "free": 20952903680,
        "total": 21474832384,
        "used": {
          "bytes": 521928704,
          "pct": 0.0243
        }
      },
      "total": 33323646976,
      "used": {
        "bytes": 28227096576,
        "pct": 0.8471
      },
      "zswap": {
        "compressed": 112336896,
        "uncompressed": 464326656
      }
    }
  }
}
Privileged output
{
  "@metadata": {
    "beat": "metricbeat",
    "type": "_doc",
    "version": "9.4.0"
  },
  "@timestamp": "2026-01-28T09:48:09.372Z",
  "agent": {
    "ephemeral_id": "55e06c15-f7e0-44bf-b361-28e69015ec34",
    "id": "8b35a267-5085-44a8-a82e-e43a4af9af11",
    "name": "laptop",
    "type": "metricbeat",
    "version": "9.4.0"
  },
  "ecs": {
    "version": "8.0.0"
  },
  "event": {
    "dataset": "system.memory",
    "duration": 181346,
    "module": "system"
  },
  "host": {
    "name": "laptop"
  },
  "metricset": {
    "name": "memory",
    "period": 1000
  },
  "service": {
    "type": "system"
  },
  "system": {
    "memory": {
      "actual": {
        "free": 18898096128,
        "used": {
          "bytes": 14425550848,
          "pct": 0.4329
        }
      },
      "cached": 13020823552,
      "free": 7782682624,
      "swap": {
        "free": 20104949760,
        "total": 21474832384,
        "used": {
          "bytes": 1369882624,
          "pct": 0.0638
        }
      },
      "total": 33323646976,
      "used": {
        "bytes": 25540964352,
        "pct": 0.7665
      },
      "zswap": {
        "compressed": 312053760,
        "debug": {
          "pool_limit_hit": 0,
          "pool_total_size": 312053760,
          "reject_alloc_fail": 0,
          "reject_compress_fail": 8665,
          "reject_compress_poor": 0,
          "reject_kmemcache_fail": 0,
          "reject_reclaim_fail": 0,
          "stored_pages": 304752,
          "written_back_pages": 0
        },
        "uncompressed": 1248264192
      }
    }
  }
}

3. Metricbeat -- processes metricset

Add:

      - process
    processes: ['.*']
    process.cgroups.enabled: true

to get zswap stats for the process metricset, check output with:

$ ./metricbeat -c metricbeat.yaml | jq '(.system.process.cgroup.memory.stats // {}) | with_entries(select(.key | IN("zswap","zswapped","zswpin","zswpout","zswpwb"))) | select(length > 0)' 
...
{
  "zswpout": 412,
  "zswpwb": 0,
  "zswapped": {
    "bytes": 1249280
  },
  "zswap": {
    "bytes": 283113
  },
  "zswpin": 107
}
...

Related issues

@orestisfl orestisfl self-assigned this Jan 26, 2026
@orestisfl orestisfl added enhancement New feature or request Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team labels Jan 26, 2026
@orestisfl orestisfl marked this pull request as ready for review January 28, 2026 12:48
@orestisfl orestisfl requested a review from a team as a code owner January 28, 2026 12:48
@orestisfl orestisfl requested review from khushijain21 and leehinman and removed request for a team January 28, 2026 12:48
@pierrehilbert pierrehilbert requested a review from rdner January 29, 2026 08:05
Copy link
Copy Markdown
Member

@rdner rdner left a comment

Choose a reason for hiding this comment

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

The code changes look good to me. Only a few questions.

@orestisfl orestisfl merged commit 7613049 into elastic:main Feb 16, 2026
5 checks passed
@orestisfl orestisfl deleted the zswap-metrics branch February 16, 2026 19:28
orestisfl added a commit that referenced this pull request Mar 3, 2026
## What does this PR do?
Adds decompress_fail and stored_incompressible_pages that were missed

## 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

- Follow-up of
#279
- Relates elastic/beats#47605
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/...
```
belimawr pushed a commit to belimawr/beats that referenced this pull request Mar 12, 2026
…v2 CPU CFS data (elastic#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/...
```
belimawr pushed a commit to belimawr/beats that referenced this pull request Mar 12, 2026
…v2 CPU CFS data (elastic#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.

3 participants