Skip to content

Commit 430960e

Browse files
ItsLastDaycrobert-1
authored andcommitted
[receiver/hostmetrics] Add optional system.linux.memory.available metric (open-telemetry#27247)
Implement a new metric `system.linux.memory.available`, which I defined in open-telemetry/semantic-conventions#257. **Link to tracking Issue:** open-telemetry#7417 **Testing:** added a check to an existing unit test. I had to refactor the test a bit: it assumed that a certain metric will be at position 0, which is not true now. **Documentation:** Added note in `metadata.yaml` --------- Co-authored-by: Curtis Robert <[email protected]>
1 parent 3c33fc2 commit 430960e

File tree

13 files changed

+188
-23
lines changed

13 files changed

+188
-23
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: hostmetricsreceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add optional Linux-only metric `system.linux.memory.available`
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [7417]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
This is an alternative to `system.memory.usage` metric with `state=free`.
20+
Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values.
21+
This is supposed to be more accurate than just "free" memory.
22+
For reference, see the calculations [here](https://superuser.com/a/980821).
23+
See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html).
24+
25+
# If your change doesn't affect end users or the exported elements of any package,
26+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
27+
# Optional: The change log or logs in which this entry should be included.
28+
# e.g. '[user]' or '[user, api]'
29+
# Include 'user' if the change is relevant to end users.
30+
# Include 'api' if there is a change to a library API.
31+
# Default: '[user]'
32+
change_logs: [user]

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/documentation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ metrics:
3838
enabled: true
3939
```
4040
41+
### system.linux.memory.available
42+
43+
An estimate of how much memory is available for starting new applications, without swapping. This is a more accurate alternative than system.memory.usage with state=free. (Linux only)
44+
45+
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
46+
| ---- | ----------- | ---------- | ----------------------- | --------- |
47+
| By | Sum | Int | Cumulative | false |
48+
4149
### system.memory.utilization
4250
4351
Percentage of memory bytes in use.

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_config.go

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_config_test.go

Lines changed: 6 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics.go

Lines changed: 72 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics_test.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/testdata/config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
default:
22
all_set:
33
metrics:
4+
system.linux.memory.available:
5+
enabled: true
46
system.memory.usage:
57
enabled: true
68
system.memory.utilization:
79
enabled: true
810
none_set:
911
metrics:
12+
system.linux.memory.available:
13+
enabled: false
1014
system.memory.usage:
1115
enabled: false
1216
system.memory.utilization:

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
6969
memInfo.Total), metricsLen)
7070
}
7171
s.recordMemoryUtilizationMetric(now, memInfo)
72+
s.recordSystemSpecificMetrics(now, memInfo)
7273
}
7374

7475
return s.mb.Emit(), nil

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_linux.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,11 @@ func (s *scraper) recordMemoryUtilizationMetric(now pcommon.Timestamp, memInfo *
3030
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Sreclaimable)/float64(memInfo.Total), metadata.AttributeStateSlabReclaimable)
3131
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Sunreclaim)/float64(memInfo.Total), metadata.AttributeStateSlabUnreclaimable)
3232
}
33+
34+
func (s *scraper) recordLinuxMemoryAvailableMetric(now pcommon.Timestamp, memInfo *mem.VirtualMemoryStat) {
35+
s.mb.RecordSystemLinuxMemoryAvailableDataPoint(now, int64(memInfo.Available))
36+
}
37+
38+
func (s *scraper) recordSystemSpecificMetrics(now pcommon.Timestamp, memInfo *mem.VirtualMemoryStat) {
39+
s.recordLinuxMemoryAvailableMetric(now, memInfo)
40+
}

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_others.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ func (s *scraper) recordMemoryUtilizationMetric(now pcommon.Timestamp, memInfo *
2424
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Free)/float64(memInfo.Total), metadata.AttributeStateFree)
2525
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Inactive)/float64(memInfo.Total), metadata.AttributeStateInactive)
2626
}
27+
28+
func (s *scraper) recordSystemSpecificMetrics(now pcommon.Timestamp, memInfo *mem.VirtualMemoryStat) {
29+
}

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_test.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,18 @@ func TestScrape(t *testing.T) {
5252
SystemMemoryUsage: metadata.MetricConfig{
5353
Enabled: true,
5454
},
55+
SystemLinuxMemoryAvailable: metadata.MetricConfig{
56+
Enabled: true,
57+
},
5558
},
5659
},
5760
},
58-
expectedMetricCount: 2,
61+
expectedMetricCount: func() int {
62+
if runtime.GOOS == "linux" {
63+
return 3
64+
}
65+
return 2
66+
}(),
5967
},
6068
{
6169
name: "Error",
@@ -112,12 +120,19 @@ func TestScrape(t *testing.T) {
112120
assert.Equal(t, test.expectedMetricCount, md.MetricCount())
113121

114122
metrics := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics()
115-
assertMemoryUsageMetricValid(t, metrics.At(0), "system.memory.usage")
123+
memUsageIdx := -1
124+
for i := 0; i < md.MetricCount(); i++ {
125+
if metrics.At(i).Name() == "system.memory.usage" {
126+
memUsageIdx = i
127+
}
128+
}
129+
assert.NotEqual(t, memUsageIdx, -1)
130+
assertMemoryUsageMetricValid(t, metrics.At(memUsageIdx), "system.memory.usage")
116131

117132
if runtime.GOOS == "linux" {
118-
assertMemoryUsageMetricHasLinuxSpecificStateLabels(t, metrics.At(0))
133+
assertMemoryUsageMetricHasLinuxSpecificStateLabels(t, metrics.At(memUsageIdx))
119134
} else if runtime.GOOS != "windows" {
120-
internal.AssertSumMetricHasAttributeValue(t, metrics.At(0), 2, "state",
135+
internal.AssertSumMetricHasAttributeValue(t, metrics.At(memUsageIdx), 2, "state",
121136
pcommon.NewValueStr(metadata.AttributeStateInactive.String()))
122137
}
123138

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_windows.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ func (s *scraper) recordMemoryUtilizationMetric(now pcommon.Timestamp, memInfo *
2222
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Used)/float64(memInfo.Total), metadata.AttributeStateUsed)
2323
s.mb.RecordSystemMemoryUtilizationDataPoint(now, float64(memInfo.Free)/float64(memInfo.Total), metadata.AttributeStateFree)
2424
}
25+
26+
func (s *scraper) recordSystemSpecificMetrics(now pcommon.Timestamp, memInfo *mem.VirtualMemoryStat) {
27+
}

receiver/hostmetricsreceiver/internal/scraper/memoryscraper/metadata.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,12 @@ metrics:
2828
gauge:
2929
value_type: double
3030
attributes: [state]
31+
32+
system.linux.memory.available:
33+
enabled: false
34+
description: An estimate of how much memory is available for starting new applications, without swapping. This is a more accurate alternative than system.memory.usage with state=free. (Linux only)
35+
unit: By
36+
sum:
37+
value_type: int
38+
aggregation_temporality: cumulative
39+
monotonic: false

0 commit comments

Comments
 (0)