From 90e0fd15577bf482b8c05ae37467f06c7d2b699c Mon Sep 17 00:00:00 2001 From: Paramadon Date: Wed, 24 Apr 2024 11:49:23 -0400 Subject: [PATCH] resolving all comment(cleaning up code) --- util/common/metrics.go | 27 ++-- validator/main.go | 2 - validator/validators/basic/basic_validator.go | 121 ++++++++++-------- 3 files changed, 85 insertions(+), 65 deletions(-) diff --git a/util/common/metrics.go b/util/common/metrics.go index 61bd3c852..f84a6e85d 100644 --- a/util/common/metrics.go +++ b/util/common/metrics.go @@ -26,8 +26,11 @@ import ( "github.com/prozz/aws-embedded-metrics-golang/emf" ) -const LastSendTimeFile = "last_send_time.txt" -const MinInterval = 60 // Minimum interval in seconds +const SleepDuration = 5 * time.Second + +const TracesPort = "4316/v1/traces" +const MetricPort = "4316/v1/metrics" + // StartSendingMetrics will generate metrics load based on the receiver (e.g 5000 statsd metrics per minute) func StartSendingMetrics(receiver string, duration, sendingInterval time.Duration, metricPerInterval int, metricLogGroup, metricNamespace string) (err error) { go func() { @@ -39,9 +42,9 @@ func StartSendingMetrics(receiver string, duration, sendingInterval time.Duratio case "emf": err = SendEMFMetrics(metricPerInterval, metricLogGroup, metricNamespace, sendingInterval, duration) case "app_signals": - err = SendAppSignalMetrics() //does app signals have dimension for metric? + err = SendAppSignalMetrics(duration) //does app signals have dimension for metric? case "traces": - err = SendAppTraceMetrics(duration) //does app signals have dimension for metric? + err = SendAppSignalsTraceMetrics(duration) //does app signals have dimension for metric? default: } @@ -50,7 +53,7 @@ func StartSendingMetrics(receiver string, duration, sendingInterval time.Duratio return err } -func SendAppTraceMetrics(duration time.Duration) error { +func SendAppSignalsTraceMetrics(duration time.Duration) error { baseDir := getBaseDir() for i := 0; i < int(duration/(5*time.Second)); i++ { @@ -94,7 +97,7 @@ func processTraceFile(filePath string, startTime int64, traceID string) error { modifiedData := strings.ReplaceAll(string(data), "START_TIME", fmt.Sprintf("%d", startTime)) modifiedData = strings.ReplaceAll(modifiedData, "TRACE_ID", traceID) - url := "http://127.0.0.1:4316/v1/traces" + url := "http://127.0.0.1:" + TracesPort _, err = http.Post(url, "application/json", bytes.NewBufferString(modifiedData)) if err != nil { return err @@ -210,7 +213,7 @@ func processFile(filePath string, startTime int64) error { modifiedData := strings.ReplaceAll(string(data), "START_TIME", fmt.Sprintf("%d", startTime)) //curl command - url := "http://127.0.0.1:4316/v1/metrics" + url := "http://127.0.0.1:" + MetricPort _, err = http.Post(url, "application/json", bytes.NewBufferString(modifiedData)) _, err = http.Post(url, "application/json", bytes.NewBufferString(modifiedData)) @@ -223,7 +226,7 @@ func processFile(filePath string, startTime int64) error { } -func SendAppSignalMetrics() error { +func SendAppSignalMetrics(duration time.Duration) error { // The bash script to be executed asynchronously. dir, err := os.Getwd() if err != nil { @@ -235,12 +238,14 @@ func SendAppSignalMetrics() error { // Determine the base directory for the files based on the OS var baseDir string if runtime.GOOS == "windows" { - baseDir = "C:\\Users\\Administrator\\amazon-cloudwatch-agent-test\\test\\app_signals\\resources\\metrics" + baseDir = filepath.Join("C:", "Users", "Administrator", "amazon-cloudwatch-agent-test", "test", "app_signals", "resources", "metrics") } else { // assuming macOS or Unix-like system - baseDir = "/Users/ec2-user/amazon-cloudwatch-agent-test/test/app_signals/resources/metrics" + baseDir = filepath.Join("/", "Users", "ec2-user", "amazon-cloudwatch-agent-test", "test", "app_signals", "resources", "metrics") } - for i := 0; i < 12; i++ { + fmt.Println("Base directory:", baseDir) + + for i := 0; i < int(duration/SleepDuration); i++ { if err != nil { return err } diff --git a/validator/main.go b/validator/main.go index 545a9bac5..7395e5dab 100644 --- a/validator/main.go +++ b/validator/main.go @@ -18,7 +18,6 @@ import ( "github.com/aws/amazon-cloudwatch-agent-test/util/common" "github.com/aws/amazon-cloudwatch-agent-test/validator/models" "github.com/aws/amazon-cloudwatch-agent-test/validator/validators" - "github.com/aws/amazon-cloudwatch-agent-test/validator/validators/basic" ) var ( @@ -80,7 +79,6 @@ func main() { func validate(vConfig models.ValidateConfig) error { var err error for i := 0; i < awsservice.StandardRetries; i++ { - basic.RetryCount = i + 1 err = validators.LaunchValidator(vConfig) if err == nil { diff --git a/validator/validators/basic/basic_validator.go b/validator/validators/basic/basic_validator.go index 5925b568c..67fad58cf 100644 --- a/validator/validators/basic/basic_validator.go +++ b/validator/validators/basic/basic_validator.go @@ -14,7 +14,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "go.uber.org/multierr" - apMetrics "github.com/aws/amazon-cloudwatch-agent-test/test/metric" + AppSignalMetrics "github.com/aws/amazon-cloudwatch-agent-test/test/metric" "github.com/aws/amazon-cloudwatch-agent-test/util/awsservice" "github.com/aws/amazon-cloudwatch-agent-test/util/common" "github.com/aws/amazon-cloudwatch-agent-test/util/common/traces" @@ -23,12 +23,12 @@ import ( ) const metricErrorBound = 0.1 +const AppSignalNamespace = "AppSignals" type BasicValidator struct { vConfig models.ValidateConfig } -var RetryCount = 1 var _ models.ValidatorFactory = (*BasicValidator)(nil) func NewBasicValidator(vConfig models.ValidateConfig) models.ValidatorFactory { @@ -39,7 +39,7 @@ func NewBasicValidator(vConfig models.ValidateConfig) models.ValidatorFactory { func (s *BasicValidator) GenerateLoad() error { var ( - metricSendingInterval = 10 * time.Second + metricSendingInterval = time.Minute logGroup = awsservice.GetInstanceId() metricNamespace = s.vConfig.GetMetricNamespace() dataRate = s.vConfig.GetDataRate() @@ -70,75 +70,46 @@ func (s *BasicValidator) CheckData(startTime, endTime time.Time) error { ) for _, metric := range validationMetric { - metricDimensions := []cwtypes.Dimension{ - { - Name: aws.String("InstanceId"), - Value: aws.String(ec2InstanceId), - }, + metricDimensions := []cwtypes.Dimension{} + //App Signal Metrics don't have instanceid dimension + if !isAppSignalMetric(metric) { + metricDimensions = []cwtypes.Dimension{ + { + Name: aws.String("InstanceId"), + Value: aws.String(ec2InstanceId), + }, + } } + for _, dimension := range metric.MetricDimension { metricDimensions = append(metricDimensions, cwtypes.Dimension{ Name: aws.String(dimension.Name), Value: aws.String(dimension.Value), }) } - environmentValue := "Generic" - operationValue := "operation" - serviceValue := "service-name" - - appSignalDimensions := []cwtypes.Dimension{ - { - Name: aws.String("HostedIn.Environment"), - Value: aws.String(environmentValue), - }, - { - Name: aws.String("Operation"), - Value: aws.String(operationValue), - }, - { - Name: aws.String("Service"), - Value: aws.String(serviceValue), - }, - } //App Signals metric testing (This is because we want to use a different checking method (same that was done for linux test)) if metric.MetricName == "Latency" || metric.MetricName == "Fault" || metric.MetricName == "Error" { - fetcher := apMetrics.MetricValueFetcher{} - values, err := fetcher.Fetch("AppSignals", metric.MetricName, appSignalDimensions, "Sum", 60) + err := s.ValidateAppSignalMetrics(metric, metricDimensions) if err != nil { multiErr = multierr.Append(multiErr, err) - } - if !apMetrics.IsAllValuesGreaterThanOrEqualToExpectedValue(metric.MetricName, values, 0) { - fmt.Printf("Error values are not the epected values%v", err) - multiErr = multierr.Append(multiErr, fmt.Errorf("Incorrect Metric values ")) + } else { + fmt.Println("App Signal Metrics are correct!") } } else { err := s.ValidateMetric(metric.MetricName, metricNamespace, metricDimensions, metric.MetricValue, metric.MetricSampleCount, startTime, endTime) if err != nil { - multiErr = multierr.Append(multiErr, err) - } - } - lookbackDuration := time.Duration(-5) * time.Minute - serviceName := "service-name" - serviceType := "AWS::EC2::Instance" - //filtering traces - filterExpression := fmt.Sprintf("(service(id(name: \"%s\", type: \"%s\")))", serviceName, serviceType) - timeNow := time.Now() - - traceIds, err := awsservice.GetTraceIDs(timeNow.Add(lookbackDuration), timeNow, filterExpression) - if err != nil { - fmt.Printf("error getting trace ids: %v", err) - multiErr = multierr.Append(multiErr, err) - } else { - fmt.Printf("Trace IDs: %v\n", traceIds) - if len(traceIds) > 0 { - fmt.Println("Trace IDs look good") - } else { - multiErr = multierr.Append(multiErr, fmt.Errorf("no trace IDs found")) + return err } } } + err := s.ValidateTracesMetrics() + if err != nil { + multiErr = multierr.Append(multiErr, err) + } else { + fmt.Println("Traces Metrics are correct!") + } for _, logValidation := range logValidations { err := s.ValidateLogs(logValidation.LogStream, logValidation.LogValue, logValidation.LogLevel, logValidation.LogSource, logValidation.LogLines, startTime, endTime) if err != nil { @@ -162,6 +133,52 @@ func (s *BasicValidator) Cleanup() error { return nil } +func isAppSignalMetric(metric models.MetricValidation) bool { + if metric.MetricName == "Latency" || metric.MetricName == "Fault" || metric.MetricName == "Error" { + return true + } + return false +} +func (s *BasicValidator) ValidateAppSignalMetrics(metric models.MetricValidation, metricDimensions []cwtypes.Dimension) error { + + if metric.MetricName == "Latency" || metric.MetricName == "Fault" || metric.MetricName == "Error" { + fetcher := AppSignalMetrics.MetricValueFetcher{} + values, err := fetcher.Fetch(AppSignalNamespace, metric.MetricName, metricDimensions, "Sum", 60) + if err != nil { + return err + } + if !AppSignalMetrics.IsAllValuesGreaterThanOrEqualToExpectedValue(metric.MetricName, values, 0) { + fmt.Printf("Error values are not the epected values%v", err) + return err + } + } + + return nil +} + +func (s *BasicValidator) ValidateTracesMetrics() error { + lookbackDuration := time.Duration(-5) * time.Minute + serviceName := "service-name" + serviceType := "AWS::EC2::Instance" + //filtering traces + filterExpression := fmt.Sprintf("(service(id(name: \"%s\", type: \"%s\")))", serviceName, serviceType) + timeNow := time.Now() + + traceIds, err := awsservice.GetTraceIDs(timeNow.Add(lookbackDuration), timeNow, filterExpression) + if err != nil { + fmt.Printf("error getting trace ids: %v", err) + return err + } else { + fmt.Printf("Trace IDs: %v\n", traceIds) + if len(traceIds) > 0 { + fmt.Println("Trace IDs look good") + } else { + return err + } + } + return nil +} + func (s *BasicValidator) ValidateLogs(logStream, logLine, logLevel, logSource string, expectedMinimumEventCount int, startTime, endTime time.Time) error { logGroup := awsservice.GetInstanceId() log.Printf("Start to validate that substring '%s' has at least %d log event(s) within log group %s, log stream %s, between %v and %v", logLine, expectedMinimumEventCount, logGroup, logStream, startTime, endTime)