package lib import ( "fmt" "math" "net/http" "os" "path/filepath" "strings" "time" ) var metrics = PerformanceMetrics{ MinLatency: time.Duration(math.MaxInt64), ResponseCounters: make(map[int]int32), } func UpdateMetrics(duration time.Duration, resp *http.Response, second int) { metrics.Mu.Lock() defer metrics.Mu.Unlock() fmt.Printf("Updating metrics - Duration: %v, Status: %d\n", duration, resp.StatusCode) // Debug log metrics.TotalRequests++ metrics.TotalLatency += duration if duration > metrics.MaxLatency { metrics.MaxLatency = duration } if duration < metrics.MinLatency { metrics.MinLatency = duration } if resp.StatusCode == http.StatusOK { metrics.TotalResponses++ metrics.ResponseCounters[second]++ } // Debug log fmt.Printf("Current metrics - Total Requests: %d, Total Responses: %d\n", metrics.TotalRequests, metrics.TotalResponses) } func CalculateAndPrintMetrics(startTime time.Time, requestsPerSecond float64, endpoint string, patterns []RequestPattern) { time.Sleep(100 * time.Millisecond) metrics.Mu.Lock() defer metrics.Mu.Unlock() averageLatency := time.Duration(0) if metrics.TotalRequests > 0 { averageLatency = metrics.TotalLatency / time.Duration(metrics.TotalRequests) } totalDuration := time.Since(startTime).Seconds() totalResponses := int32(0) for _, count := range metrics.ResponseCounters { totalResponses += count } if metrics.MinLatency == time.Duration(math.MaxInt64) { metrics.MinLatency = 0 } results := fmt.Sprintf("Load Test Report\n") results += fmt.Sprintf("=============\n\n") results += fmt.Sprintf("Endpoint: %s\n", endpoint) results += fmt.Sprintf("Pattern: ") for i, p := range patterns { if i > 0 { results += " → " } results += fmt.Sprintf("%d%s", p.Sequence, strings.ToLower(p.Verb[:1])) } results += "\n\n" results += fmt.Sprintf("Performance Metrics\n") results += fmt.Sprintf("-----------------\n") results += fmt.Sprintf("Total Requests Sent: %d\n", metrics.TotalRequests) results += fmt.Sprintf("Total Responses Received: %d\n", totalResponses) results += fmt.Sprintf("Average Latency: %s\n", averageLatency) results += fmt.Sprintf("Max Latency: %s\n", metrics.MaxLatency) results += fmt.Sprintf("Min Latency: %s\n", metrics.MinLatency) results += fmt.Sprintf("Requests/sec (Target): %.2f\n", requestsPerSecond) results += fmt.Sprintf("Requests/sec (Actual): %.2f\n", float64(metrics.TotalRequests)/totalDuration) results += fmt.Sprintf("Responses/sec: %.2f\n", float64(totalResponses)/totalDuration) fmt.Println(results) saveReport(results) } func saveReport(results string) { resultsDir := ".reports" os.MkdirAll(resultsDir, os.ModePerm) resultsFile := filepath.Join(resultsDir, fmt.Sprintf("%d.txt", time.Now().Unix())) if err := os.WriteFile(resultsFile, []byte(results), 0644); err != nil { fmt.Println("Error saving report:", err) return } fmt.Println("Report saved:", resultsFile) }