Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/resources/dummy-neuron-monitor/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ RUN apt-get update \
&& rm -rf /tmp/tmp* \
&& apt-get clean

COPY neuron-monitor-output.json /opt/aws/neuron/bin/neuron-monitor-output.json
COPY dummy_neuron_monitor.py /opt/aws/neuron/bin/dummy_neuron_monitor.py
RUN chmod 755 /opt/aws/neuron/bin/dummy_neuron_monitor.py
RUN pip3 install prometheus_client boto3 requests
602 changes: 4 additions & 598 deletions docs/resources/dummy-neuron-monitor/dummy_neuron_monitor.py

Large diffs are not rendered by default.

28,166 changes: 28,166 additions & 0 deletions docs/resources/dummy-neuron-monitor/neuron-monitor-output.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion terraform/eks/daemon/awsneuron/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ resource "kubernetes_daemonset" "neuron_monitor" {
}
container {
name = "neuron-monitor-prometheus"
image = "506463145083.dkr.ecr.us-west-2.amazonaws.com/mocked-neuron-monitor:v2"
image = "506463145083.dkr.ecr.us-west-2.amazonaws.com/mocked-neuron-monitor:v4"
Comment thread
spanaik marked this conversation as resolved.
port {
container_port = 8000
}
Expand Down
1 change: 1 addition & 0 deletions test/awsneuron/neuron_metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (t *AwsNeuronTestRunner) Validate() status.TestGroupResult {
testResults = append(testResults, metric.ValidateMetrics(t.env, awsNeuronMetricIndicator, expectedDimsToMetrics)...)
testResults = append(testResults, metric.ValidateLogs(t.env))
testResults = append(testResults, metric.ValidateLogsFrequency(t.env))
testResults = append(testResults, metric.ValidateNeuronCoreUtilizationValuesLogs(t.env))
return status.TestGroupResult{
Name: t.GetTestName(),
TestResults: testResults,
Expand Down
62 changes: 62 additions & 0 deletions test/metric/container_insights_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import (
"errors"
"fmt"
"log"
"math"
"math/rand"
"sort"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -296,3 +298,63 @@ func ValidateLogsFrequency(env *environment.MetaData) status.TestResult {
testResult.Status = status.SUCCESSFUL
return testResult
}

func ValidateNeuronCoreUtilizationValuesLogs(env *environment.MetaData) status.TestResult {
const core = "core"
testResult := status.TestResult{
Name: "emf-logs-neuron-core-utilization",
Status: status.FAILED,
}
var testFailed = false

end := time.Now().Add(-2 * time.Minute).Truncate(time.Minute)
start := end.Add(-1 * time.Minute)
group := fmt.Sprintf("/aws/containerinsights/%s/performance", env.EKSClusterName)

// need to get the instances used for the EKS cluster
eKSInstances, err := awsservice.GetEKSInstances(env.EKSClusterName)
if err != nil {
log.Println("failed to get EKS instances", err)
return testResult
}

for _, instance := range eKSInstances {
stream := *instance.InstanceName
coreMap, err := awsservice.GetNeuronCoreUtilizationPerCore(group, stream, &start, &end)

if err != nil {
log.Printf("log validation (%s/%s) failed: %v, start time : %s, error is : %s", group, stream, err, start, err)
return testResult
}

// We expect 32 Cores from the current test, anything less or more is a bug
if len(coreMap) != 32 {
log.Printf("32 Cores not found")
var coreMapStr strings.Builder
for k, v := range coreMap {
coreMapStr.WriteString(fmt.Sprintf("%s: %f, ", k, v))
}
log.Printf("coreMap: %s", coreMapStr.String())
testFailed = true
}

// Check if coreMap has the expected core utilization values
for coreKey, actualValue := range coreMap {
if strings.HasPrefix(coreKey, core) {
coreNumStr := strings.TrimPrefix(coreKey, core)
expectedValue, err := strconv.Atoi(coreNumStr)
if err != nil || math.Round(actualValue) != float64(expectedValue) {
log.Printf("Core utilization validation failed: expected %s:%d, got %v",
coreKey, expectedValue, actualValue)
testFailed = true
}
}
}
}

testResult.Status = status.SUCCESSFUL
if testFailed {
Comment thread
spanaik marked this conversation as resolved.
testResult.Status = status.FAILED
}
return testResult
}
35 changes: 35 additions & 0 deletions util/awsservice/cloudwatchlogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,38 @@ func CountMetricsInEMFLogs(logGroupName string) (int, error) {

return totalMetrics, nil
}

func GetNeuronCoreUtilizationPerCore(logGroup, logStream string, since, until *time.Time) (map[string]float64, error) {
var coreUtilization = make(map[string]float64)
var data map[string]interface{}

events, err := GetLogsSince(logGroup, logStream, since, until)

// if there is an error, return the empty map
if err != nil {
return coreUtilization, err
}

for _, event := range events {
message := *event.Message

var eksClusterType EKSClusterType
innerErr := json.Unmarshal([]byte(message), &eksClusterType)
if innerErr != nil || !strings.Contains(eksClusterType.Type, "NodeAWSNeuronCore") {
continue
}

err := json.Unmarshal([]byte(message), &data)
if err != nil {
continue
}

if core, ok := data["NeuronCore"].(string); ok {
if util, ok := data["node_neuroncore_utilization"].(float64); ok {
coreUtilization[core] = util
}
}
}

return coreUtilization, nil
}