-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CPU extractors with unit tests (amazon-contributing#146)
* Add CPU extractors from kubelet summary API 1. Make cadvisor helper func's public to be used in k8swindows extractor 2. Add CPU extractor and add utilization fields 3. Add unit test for CPU extractor. 4. Add unit test data for kubelet summary API 5. Add helper func to convert Pod and Node summary stats to RawMetric * Refactor code 1. Changed cExtractor to cextractors 2. Add nil checks to avoid panic during pointer deferences * Refactored code 1. Added missing HasValue func in extractors 2. Replaced cextractor with cExtractor 3. Corrected extractorhelper name with missing characters
- Loading branch information
1 parent
4edef80
commit 1ad51be
Showing
16 changed files
with
706 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
receiver/awscontainerinsightreceiver/internal/k8swindows/extractors/cpu_extractor.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package extractors | ||
|
||
import ( | ||
ci "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/containerinsight" | ||
awsmetrics "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/metrics" | ||
cExtractor "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/cadvisor/extractors" | ||
|
||
"go.uber.org/zap" | ||
) | ||
|
||
const ( | ||
decimalToMillicores = 1000 | ||
) | ||
|
||
type CPUMetricExtractor struct { | ||
logger *zap.Logger | ||
rateCalculator awsmetrics.MetricCalculator | ||
} | ||
|
||
func (c *CPUMetricExtractor) HasValue(rawMetric *RawMetric) bool { | ||
if rawMetric.CPUStats != nil { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
func (c *CPUMetricExtractor) GetValue(rawMetric *RawMetric, mInfo cExtractor.CPUMemInfoProvider, containerType string) []*cExtractor.CAdvisorMetric { | ||
var metrics []*cExtractor.CAdvisorMetric | ||
|
||
metric := cExtractor.NewCadvisorMetric(containerType, c.logger) | ||
|
||
multiplier := float64(decimalToMillicores) | ||
identifier := rawMetric.Id | ||
cExtractor.AssignRateValueToField(&c.rateCalculator, metric.GetFields(), ci.MetricName(containerType, ci.CPUTotal), identifier, float64(*rawMetric.CPUStats.UsageCoreNanoSeconds), rawMetric.Time, multiplier) | ||
|
||
numCores := mInfo.GetNumCores() | ||
if metric.GetField(ci.MetricName(containerType, ci.CPUTotal)) != nil && numCores != 0 { | ||
metric.AddField(ci.MetricName(containerType, ci.CPUUtilization), metric.GetField(ci.MetricName(containerType, ci.CPUTotal)).(float64)/float64(numCores*decimalToMillicores)*100) | ||
} | ||
|
||
if containerType == ci.TypeNode { | ||
metric.AddField(ci.MetricName(containerType, ci.CPULimit), numCores*decimalToMillicores) | ||
} | ||
|
||
metrics = append(metrics, metric) | ||
return metrics | ||
} | ||
|
||
func (c *CPUMetricExtractor) Shutdown() error { | ||
return c.rateCalculator.Shutdown() | ||
} | ||
|
||
func NewCPUMetricExtractor(logger *zap.Logger) *CPUMetricExtractor { | ||
return &CPUMetricExtractor{ | ||
logger: logger, | ||
rateCalculator: cExtractor.NewFloat64RateCalculator(), | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
receiver/awscontainerinsightreceiver/internal/k8swindows/extractors/cpu_extractor_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package extractors | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/containerinsight" | ||
cExtractor "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/cadvisor/extractors" | ||
cTestUtils "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/cadvisor/testutils" | ||
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/k8swindows/testutils" | ||
|
||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func TestCPUStats(t *testing.T) { | ||
MockCPUMemInfo := cTestUtils.MockCPUMemInfo{} | ||
|
||
result := testutils.LoadKubeletSummary(t, "./testdata/PreSingleKubeletSummary.json") | ||
result2 := testutils.LoadKubeletSummary(t, "./testdata/CurSingleKubeletSummary.json") | ||
|
||
podRawMetric := ConvertPodToRaw(&result.Pods[0]) | ||
podRawMetric2 := ConvertPodToRaw(&result2.Pods[0]) | ||
|
||
// test container type | ||
containerType := containerinsight.TypePod | ||
extractor := NewCPUMetricExtractor(&zap.Logger{}) | ||
|
||
var cMetrics []*cExtractor.CAdvisorMetric | ||
cMetrics = extractor.GetValue(podRawMetric, MockCPUMemInfo, containerType) | ||
cMetrics = extractor.GetValue(podRawMetric2, MockCPUMemInfo, containerType) | ||
|
||
cExtractor.AssertContainsTaggedFloat(t, cMetrics[0], "pod_cpu_usage_total", 3.125000, 0) | ||
cExtractor.AssertContainsTaggedFloat(t, cMetrics[0], "pod_cpu_utilization", 0.156250, 0) | ||
require.NoError(t, extractor.Shutdown()) | ||
|
||
// test node type | ||
containerType = containerinsight.TypeNode | ||
extractor = NewCPUMetricExtractor(nil) | ||
|
||
nodeRawMetric := ConvertNodeToRaw(&result.Node) | ||
nodeRawMetric2 := ConvertNodeToRaw(&result2.Node) | ||
cMetrics = extractor.GetValue(nodeRawMetric, MockCPUMemInfo, containerType) | ||
cMetrics = extractor.GetValue(nodeRawMetric2, MockCPUMemInfo, containerType) | ||
|
||
cExtractor.AssertContainsTaggedFloat(t, cMetrics[0], "node_cpu_usage_total", 51.5, 0.5) | ||
cExtractor.AssertContainsTaggedFloat(t, cMetrics[0], "node_cpu_utilization", 2.5, 0.5) | ||
cExtractor.AssertContainsTaggedInt(t, cMetrics[0], "node_cpu_limit", 2000) | ||
|
||
require.NoError(t, extractor.Shutdown()) | ||
} |
25 changes: 25 additions & 0 deletions
25
receiver/awscontainerinsightreceiver/internal/k8swindows/extractors/extractor.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package extractors | ||
|
||
import ( | ||
"time" | ||
|
||
cExtractor "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/cadvisor/extractors" | ||
stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1" | ||
) | ||
|
||
// RawMetric Represent Container, Pod, Node Metric Extractors. | ||
// Kubelet summary and HNS stats will be converted to Raw Metric for parsing by Extractors. | ||
type RawMetric struct { | ||
Id string | ||
Name string | ||
Namespace string | ||
Time time.Time | ||
CPUStats *stats.CPUStats | ||
MemoryStats *stats.MemoryStats | ||
} | ||
|
||
type MetricExtractor interface { | ||
HasValue(summary *RawMetric) bool | ||
GetValue(summary *RawMetric, mInfo cExtractor.CPUMemInfoProvider, containerType string) []*cExtractor.CAdvisorMetric | ||
Shutdown() error | ||
} |
43 changes: 43 additions & 0 deletions
43
receiver/awscontainerinsightreceiver/internal/k8swindows/extractors/extractorhelpers.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package extractors | ||
|
||
import ( | ||
stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1" | ||
) | ||
|
||
// ConvertPodToRaw Converts Kubelet Pod stats to RawMetric. | ||
func ConvertPodToRaw(podStat *stats.PodStats) *RawMetric { | ||
var rawMetic *RawMetric | ||
rawMetic = &RawMetric{} | ||
rawMetic.Id = podStat.PodRef.UID | ||
rawMetic.Name = podStat.PodRef.Name | ||
rawMetic.Namespace = podStat.PodRef.Namespace | ||
|
||
if podStat.CPU != nil { | ||
rawMetic.Time = podStat.CPU.Time.Time | ||
rawMetic.CPUStats = podStat.CPU | ||
} | ||
|
||
if podStat.Memory != nil { | ||
rawMetic.MemoryStats = podStat.Memory | ||
} | ||
return rawMetic | ||
} | ||
|
||
// ConvertNodeToRaw Converts Kubelet Node stats to RawMetric. | ||
func ConvertNodeToRaw(nodeStat *stats.NodeStats) *RawMetric { | ||
var rawMetic *RawMetric | ||
rawMetic = &RawMetric{} | ||
rawMetic.Id = nodeStat.NodeName | ||
rawMetic.Name = nodeStat.NodeName | ||
|
||
if nodeStat.CPU != nil { | ||
rawMetic.Time = nodeStat.CPU.Time.Time | ||
rawMetic.CPUStats = nodeStat.CPU | ||
} | ||
|
||
if nodeStat.Memory != nil { | ||
rawMetic.MemoryStats = nodeStat.Memory | ||
} | ||
|
||
return rawMetic | ||
} |
40 changes: 40 additions & 0 deletions
40
receiver/awscontainerinsightreceiver/internal/k8swindows/extractors/extractorhelpers_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package extractors | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/k8swindows/testutils" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestConvertPodToRaw(t *testing.T) { | ||
|
||
result := testutils.LoadKubeletSummary(t, "./testdata/PreSingleKubeletSummary.json") | ||
|
||
podRawMetric := ConvertPodToRaw(&result.Pods[0]) | ||
|
||
assert.Equal(t, podRawMetric.Id, "01bfbe59-2925-4ad5-a8d3-a1b23e3ddd74") | ||
assert.Equal(t, podRawMetric.Name, "windows-server-iis-ltsc2019-58d94b5844-6v2pg") | ||
assert.Equal(t, podRawMetric.Namespace, "amazon-cloudwatch") | ||
parsedtime, _ := time.Parse(time.RFC3339, "2023-12-21T15:19:59Z") | ||
assert.Equal(t, podRawMetric.Time, parsedtime.Local()) | ||
assert.Equal(t, *podRawMetric.CPUStats.UsageCoreNanoSeconds, uint64(289625000000)) | ||
assert.Equal(t, *podRawMetric.CPUStats.UsageNanoCores, uint64(0)) | ||
} | ||
|
||
func TestConvertNodeToRaw(t *testing.T) { | ||
|
||
result := testutils.LoadKubeletSummary(t, "./testdata/PreSingleKubeletSummary.json") | ||
|
||
nodeRawMetric := ConvertNodeToRaw(&result.Node) | ||
|
||
assert.Equal(t, nodeRawMetric.Id, "ip-192-168-44-84.us-west-2.compute.internal") | ||
assert.Equal(t, nodeRawMetric.Name, "ip-192-168-44-84.us-west-2.compute.internal") | ||
assert.Equal(t, nodeRawMetric.Namespace, "") | ||
parsedtime, _ := time.Parse(time.RFC3339, "2023-12-21T15:19:58Z") | ||
assert.Equal(t, nodeRawMetric.Time, parsedtime.Local()) | ||
assert.Equal(t, *nodeRawMetric.CPUStats.UsageCoreNanoSeconds, uint64(38907680000000)) | ||
assert.Equal(t, *nodeRawMetric.CPUStats.UsageNanoCores, uint64(20000000)) | ||
} |
Oops, something went wrong.