Skip to content

Commit 7485d61

Browse files
authored
Merge branch 'aws-cwa-dev' into aws-cwa-dev
2 parents 62781da + 58011f4 commit 7485d61

6 files changed

Lines changed: 387 additions & 19 deletions

File tree

internal/aws/containerinsight/const.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ const (
146146
GpuRequest = "gpu_request"
147147
GpuReservedCapacity = "gpu_reserved_capacity"
148148

149+
NeuroncoreLimit = "neuroncore_limit"
150+
NeuroncoreUsageTotal = "neuroncore_usage_total"
151+
NeuroncoreRequest = "neuroncore_request"
152+
NeuroncoreReservedCapacity = "neuroncore_reserved_capacity"
153+
NeuroncoreUnreservedCapacity = "neuroncore_unreserved_capacity"
154+
NeuroncoreAvailableCapacity = "neuroncore_available_capacity"
155+
149156
HyperPodUnschedulablePendingReplacement = "unschedulable_pending_replacement"
150157
HyperPodUnschedulablePendingReboot = "unschedulable_pending_reboot"
151158
HyperPodSchedulable = "schedulable"
@@ -367,6 +374,13 @@ func init() {
367374
GpuRequest: UnitCount,
368375
GpuReservedCapacity: UnitPercent,
369376

377+
NeuroncoreLimit: UnitCount,
378+
NeuroncoreUsageTotal: UnitCount,
379+
NeuroncoreRequest: UnitCount,
380+
NeuroncoreReservedCapacity: UnitPercent,
381+
NeuroncoreUnreservedCapacity: UnitPercent,
382+
NeuroncoreAvailableCapacity: UnitCount,
383+
370384
HyperPodUnschedulablePendingReplacement: UnitCount,
371385
HyperPodUnschedulablePendingReboot: UnitCount,
372386
HyperPodSchedulable: UnitCount,

receiver/awscontainerinsightreceiver/internal/stores/nodeinfo.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import (
1515
)
1616

1717
type nodeStats struct {
18-
podCnt int
19-
containerCnt int
20-
cpuReq uint64
21-
memReq uint64
22-
gpuReq uint64
23-
gpuUsageTotal uint64
18+
podCnt int
19+
containerCnt int
20+
cpuReq uint64
21+
memReq uint64
22+
gpuReq uint64
23+
gpuUsageTotal uint64
24+
neuroncoreReq uint64
25+
neuroncoreUsageTotal uint64
2426
}
2527

2628
type nodeInfo struct {
@@ -118,6 +120,58 @@ func (n *nodeInfo) getNodeStatusCapacityGPUs() (uint64, bool) {
118120
return forceConvertToInt64(gpus, n.logger), true
119121
}
120122

123+
func (n *nodeInfo) getNeuronResourceCapacity(resourceKey v1.ResourceName) (uint64, bool) {
124+
capacityResources, ok := n.provider.NodeToCapacityMap()[n.nodeName]
125+
if !ok {
126+
return 0, false
127+
}
128+
value := capacityResources.Name(resourceKey, resource.DecimalExponent).Value()
129+
return forceConvertToInt64(value, n.logger), true
130+
}
131+
132+
func (n *nodeInfo) getNodeStatusCapacityNeuron() (uint64, bool) {
133+
return n.getNeuronResourceCapacity(resourceSpecNeuronKey)
134+
}
135+
136+
func (n *nodeInfo) getNodeStatusCapacityNeuroncore() (uint64, bool) {
137+
return n.getNeuronResourceCapacity(resourceSpecNeuroncoreKey)
138+
}
139+
140+
func (n *nodeInfo) getNodeStatusCapacityNeurondevice() (uint64, bool) {
141+
return n.getNeuronResourceCapacity(resourceSpecNeuronDeviceKey)
142+
}
143+
144+
func (n *nodeInfo) getNeuronCoresPerDevice() (int, bool) {
145+
devices, hasDevices := n.getNodeStatusCapacityNeuron()
146+
cores, hasCores := n.getNodeStatusCapacityNeuroncore()
147+
148+
if hasDevices && hasCores && devices > 0 && cores > 0 {
149+
return int(cores / devices), true
150+
}
151+
152+
return 0, false
153+
}
154+
155+
func (n *nodeInfo) getNodeStatusCapacityNeuronCores() (uint64, bool) {
156+
if cores, ok := n.getNodeStatusCapacityNeuroncore(); ok {
157+
return cores, true
158+
}
159+
160+
coresPerDevice, hasRatio := n.getNeuronCoresPerDevice()
161+
if !hasRatio {
162+
return 0, false
163+
}
164+
165+
if devices, ok := n.getNodeStatusCapacityNeuron(); ok {
166+
return devices * uint64(coresPerDevice), true
167+
}
168+
if devices, ok := n.getNodeStatusCapacityNeurondevice(); ok {
169+
return devices * uint64(coresPerDevice), true
170+
}
171+
172+
return 0, false
173+
}
174+
121175
func (n *nodeInfo) getNodeStatusCondition(conditionType v1.NodeConditionType) (uint64, bool) {
122176
if nodeConditions, ok := n.provider.NodeToConditionsMap()[n.nodeName]; ok {
123177
if conditionStatus, ok := nodeConditions[conditionType]; ok {

receiver/awscontainerinsightreceiver/internal/stores/podstore.go

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const (
2929
memoryKey = "memory"
3030
cpuKey = "cpu"
3131
gpuKey = "nvidia.com/gpu"
32+
neuronKey = "aws.amazon.com/neuron"
33+
neuroncoreKey = "aws.amazon.com/neuroncore"
34+
neuronDeviceKey = "aws.amazon.com/neurondevice"
3235
splitRegexStr = "\\.|-"
3336
kubeProxy = "kube-proxy"
3437
)
@@ -247,6 +250,7 @@ func (p *PodStore) Decorate(ctx context.Context, metric CIMetric, kubernetesBlob
247250
p.decorateCPU(metric, &entry.pod)
248251
p.decorateMem(metric, &entry.pod)
249252
p.decorateGPU(metric, &entry.pod)
253+
p.decorateNeuron(metric, &entry.pod)
250254
p.addStatus(metric, &entry.pod)
251255
addContainerCount(metric, &entry.pod)
252256
addContainerID(&entry.pod, metric, kubernetesBlob, p.logger)
@@ -298,6 +302,8 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
298302
var memRequest uint64
299303
var gpuRequest uint64
300304
var gpuUsageTotal uint64
305+
var neuroncoreRequest uint64
306+
var neuroncoreUsageTotal uint64
301307

302308
for i := range podList {
303309
pod := podList[i]
@@ -312,6 +318,12 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
312318
cpuRequest += tmpCPUReq
313319
tmpMemReq, _ := getResourceSettingForPod(&pod, p.nodeInfo.getMemCapacity(), memoryKey, getRequestForContainer)
314320
memRequest += tmpMemReq
321+
if coresLimit, coresReq, hasNeuron := p.getNeuronCoresFromPod(&pod); hasNeuron {
322+
neuroncoreRequest += coresReq
323+
if pod.Status.Phase == corev1.PodRunning {
324+
neuroncoreUsageTotal += coresLimit
325+
}
326+
}
315327
if tmpGpuLimit, ok := getResourceSettingForPod(&pod, 0, gpuKey, getLimitForContainer); ok {
316328
tmpGpuReq, _ := getResourceSettingForPod(&pod, 0, gpuKey, getRequestForContainer)
317329
gpuRequest += tmpGpuReq
@@ -337,12 +349,14 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
337349
}
338350

339351
p.nodeInfo.setNodeStats(nodeStats{
340-
podCnt: podCount,
341-
containerCnt: containerCount,
342-
memReq: memRequest,
343-
cpuReq: cpuRequest,
344-
gpuReq: gpuRequest,
345-
gpuUsageTotal: gpuUsageTotal,
352+
podCnt: podCount,
353+
containerCnt: containerCount,
354+
memReq: memRequest,
355+
cpuReq: cpuRequest,
356+
gpuReq: gpuRequest,
357+
gpuUsageTotal: gpuUsageTotal,
358+
neuroncoreReq: neuroncoreRequest,
359+
neuroncoreUsageTotal: neuroncoreUsageTotal,
346360
})
347361
}
348362

@@ -408,6 +422,17 @@ func (p *PodStore) decorateNode(metric CIMetric) {
408422
metric.AddField(ci.MetricName(ci.TypeNode, ci.GpuUsageTotal), nodeStats.gpuUsageTotal)
409423
metric.AddField(ci.MetricName(ci.TypeNode, ci.GpuReservedCapacity), float64(nodeStats.gpuReq)/float64(nodeStatusCapacityGPUs)*100)
410424
}
425+
426+
if nodeStatusCapacityNeuroncore, ok := p.nodeInfo.getNodeStatusCapacityNeuronCores(); ok && nodeStatusCapacityNeuroncore != 0 {
427+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreRequest), nodeStats.neuroncoreReq)
428+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreLimit), nodeStatusCapacityNeuroncore)
429+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreUsageTotal), nodeStats.neuroncoreUsageTotal)
430+
431+
reservedCapacity := float64(nodeStats.neuroncoreReq) / float64(nodeStatusCapacityNeuroncore) * 100
432+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreReservedCapacity), reservedCapacity)
433+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreUnreservedCapacity), 100.0-reservedCapacity)
434+
metric.AddField(ci.MetricName(ci.TypeNode, ci.NeuroncoreAvailableCapacity), nodeStatusCapacityNeuroncore-nodeStats.neuroncoreReq)
435+
}
411436
}
412437
}
413438
}
@@ -431,6 +456,56 @@ func (p *PodStore) decorateGPU(metric CIMetric, pod *corev1.Pod) {
431456
}
432457
}
433458

459+
func (p *PodStore) getCoresPerNeuronDevice() (int, bool) {
460+
return p.nodeInfo.getNeuronCoresPerDevice()
461+
}
462+
463+
func (p *PodStore) getNeuronCoresFromPod(pod *corev1.Pod) (limitCores, requestCores uint64, hasNeuron bool) {
464+
if coreLimit, ok := getResourceSettingForPod(pod, 0, neuroncoreKey, getLimitForContainer); ok {
465+
coreRequest, _ := getResourceSettingForPod(pod, 0, neuroncoreKey, getRequestForContainer)
466+
return coreLimit, coreRequest, true
467+
}
468+
469+
coresPerDevice, hasRatio := p.getCoresPerNeuronDevice()
470+
if !hasRatio {
471+
p.logger.Debug("Cannot determine neuron cores per device ratio, skipping device-based neuron metrics")
472+
return 0, 0, false
473+
}
474+
475+
deviceKeys := []corev1.ResourceName{neuronKey, neuronDeviceKey}
476+
for _, deviceKey := range deviceKeys {
477+
if deviceLimit, ok := getResourceSettingForPod(pod, 0, deviceKey, getLimitForContainer); ok {
478+
deviceRequest, _ := getResourceSettingForPod(pod, 0, deviceKey, getRequestForContainer)
479+
return deviceLimit * uint64(coresPerDevice), deviceRequest * uint64(coresPerDevice), true
480+
}
481+
}
482+
483+
return 0, 0, false
484+
}
485+
486+
func (p *PodStore) decorateNeuron(metric CIMetric, pod *corev1.Pod) {
487+
if p.includeEnhancedMetrics && p.enableAcceleratedComputeMetrics && metric.GetTag(ci.MetricType) == ci.TypePod &&
488+
pod.Status.Phase != corev1.PodSucceeded && pod.Status.Phase != corev1.PodFailed {
489+
coresLimit, coresRequest, hasNeuron := p.getNeuronCoresFromPod(pod)
490+
491+
if hasNeuron {
492+
metric.AddField(ci.MetricName(ci.TypePod, ci.NeuroncoreRequest), coresRequest)
493+
metric.AddField(ci.MetricName(ci.TypePod, ci.NeuroncoreLimit), coresLimit)
494+
495+
var podNeuroncoreUsageTotal uint64
496+
if pod.Status.Phase == corev1.PodRunning {
497+
podNeuroncoreUsageTotal = coresLimit
498+
}
499+
metric.AddField(ci.MetricName(ci.TypePod, ci.NeuroncoreUsageTotal), podNeuroncoreUsageTotal)
500+
501+
if nodeCapacityCores, ok := p.nodeInfo.getNodeStatusCapacityNeuronCores(); ok && nodeCapacityCores != 0 {
502+
reservedCapacity := float64(coresLimit) / float64(nodeCapacityCores) * 100
503+
metric.AddField(ci.MetricName(ci.TypePod, ci.NeuroncoreReservedCapacity), reservedCapacity)
504+
}
505+
}
506+
}
507+
}
508+
434509
func (p *PodStore) decorateCPU(metric CIMetric, pod *corev1.Pod) {
435510
if metric.GetTag(ci.MetricType) == ci.TypePod {
436511
// add cpu limit and request for pod cpu

0 commit comments

Comments
 (0)