fix: report container-scoped CPU and memory metrics - #27389
superezzdev wants to merge 1 commit into
Conversation
…ners Fixes Graylog2#27264 In containerized environments (e.g. Docker), the Cluster Configuration page displayed host-level CPU and memory figures rather than container-scoped usage and limits. In addition, Data Nodes could display a false warning about available memory exceeding heap size when direct cgroup filesystem reads failed. This change introduces container-aware metrics for both Graylog server and OpenSearch data nodes: - graylog2-server (CpuLoadGauge): Use OSHI's CgroupInfo to calculate container CPU usage deltas scaled by effective CPUs / CFS quota. Falls back to host CPU load ticks when not containerized. - data-node (NodeMetricsCollector): Inspect OpenSearch cgroup memory (limit_in_bytes, usage_in_bytes) and cpuacct stats to report container-scoped memory (total, used, free, used_percent) and CPU percent across ticks. - data-node (MetricsCollector): Retain NodeMetricsCollector instance across runs to track CPU usage deltas across consecutive samples. - data-node (OpensearchProcessImpl): Add OSHI CgroupInfo fallback to getContainerMemory() to accurately detect container limits and eliminate false-positive heap warning notifications. - Tests: Add unit tests for containerized CPU and memory reporting in both modules.
|
Hi @fpetersen-gl Thankyou |
moesterheld
left a comment
There was a problem hiding this comment.
Thank you very much for the contribution and the solid approach. I have one change request regarding the code and an additional request below.
If we use the existing metrics (and since this fixes wrong behavior, we should), this will definitely need an entry in UPGRADING.md. People will already use this for monitoring and alerting so this change might trigger alerts after updating.
Please add something along the lines of
### System CPU and Memory Metrics Now Reflect Container Limits When Containerized
When Graylog Server or Data Node runs in a container with cgroup CPU/memory limits configured (e.g. Docker `--memory`/`--cpus`, Kubernetes `resources.limits`), the `org.graylog2.system.cpu.percent` metric and the Data Node metrics `mem_total`, `mem_free`, `mem_total_used_bytes`, and `mem_total_used` now reflect the container's cgroup-scoped limits and usage instead of the underlying host's.
Previously, these metrics always reported host-level values, so a container with a memory limit well below the host's total RAM would show a low, misleadingly small "used" percentage. After upgrading, the same metrics scale to the container's actual limit, so used-percentage values can jump significantly even though nothing about the node's real memory or CPU pressure has changed. Review and, if necessary, adjust any dashboards or alert thresholds built against the old host-scaled values.
under ## Breaking changes
| } | ||
| try { | ||
| final CgroupInfo cgroup = cgroupInfo(); | ||
| if (cgroup != null && cgroup.isContainerized()) { |
There was a problem hiding this comment.
cgroupInfo() will construct an additional SystemInfo every 5 seconds only for making the cgroup detection (on bare-metal systems). We should cache the result of the detection on the first run to avoid the overhead cost of SystemInfo construction (see SystemInfo javadoc).
|
@superezzdev Thank you once more for your work. To include the changes in the upcoming 7.2 release, we have created a new pr (purely for procedural reasons) which includes your changes with your authorship intact and will address the found issues. superseded by #27425 |
Fixes #27264
Description
When Graylog Server and Data Nodes run in containers, the Cluster Configuration page can show the host's CPU and memory instead of the resources available to that container.
This PR makes the resource metrics cgroup-aware while keeping the existing behavior for non-containerized deployments.
What changed
Graylog Server:
CpuLoadGaugenow uses OSHI's cgroup information to calculate CPU usage for the container. When cgroup information isn't available, it falls back to the existing OSHI CPU tick calculation.Data Node:
NodeMetricsCollectornow uses the cgroup memory and CPU information returned by OpenSearch when a container has resource limits. This keeps memory total/used/free and CPU percentage scoped to the container instead of the host.CPU sampling:
MetricsCollectornow keeps the sameNodeMetricsCollectorinstance between runs so CPU usage can be calculated from consecutive samples.Heap warning:
OpensearchProcessImplnow also falls back to OSHI'sCgroupInfowhen the cgroup files can't be read directly. This avoids incorrect heap warnings in container environments where the direct/sys/fs/cgrouppaths aren't available.The existing host-level metrics remain the fallback when usable cgroup information isn't available.
Motivation
This was particularly noticeable when multiple Graylog/Data Node containers were running on the same host:
The goal is to make the values shown in Cluster Configuration match the resources of the actual container.
How Has This Been Tested?
Added tests covering the new cgroup-based behavior and the existing fallbacks.
graylog2-serverCpuLoadGaugeTest.reportsContainerCpuLoadAfterTwoSamplesCpuLoadGaugeTest.reportsContainerCpuLoadWithUnlimitedQuotadata-nodeNodeMetricsCollectorTest.getNodeMetricsWithCgroupMemoryNodeMetricsCollectorTest.getNodeMetricsWithUnlimitedCgroupMemoryNodeMetricsCollectorTest.getNodeMetricsWithCgroupCpuTests executed:
All relevant tests passed.
I also verified
forbiddenapisand clean compilation across the reactor modules.Types of changes
Checklist