This commit is contained in:
2025-05-23 15:11:03 +04:00
parent c86165f88c
commit 92b9c356b8
83 changed files with 450 additions and 810 deletions

View File

@@ -5,7 +5,7 @@ import (
"fmt"
"os"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/hetznerinstall"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/hetznerinstall"
)
func main() {

View File

@@ -6,10 +6,10 @@ import (
"os/exec"
"path/filepath"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql/dependencies"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql/gosp"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql/postgres"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql/verification"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql/dependencies"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql/gosp"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql/postgres"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql/verification"
)
// Constants for PostgreSQL installation

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"os"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql"
)
func main() {

View File

@@ -6,7 +6,7 @@ import (
"os/exec"
"path/filepath"
"github.com/freeflowuniverse/heroagent/pkg/system/builders/postgresql/postgres"
"git.ourworld.tf/herocode/heroagent/pkg/system/builders/postgresql/postgres"
)
// Constants for Go stored procedure
@@ -46,10 +46,10 @@ func (b *GoSPBuilder) run(cmd string, args ...string) error {
fmt.Println("Running:", cmd, args)
c := exec.Command(cmd, args...)
// Set environment variables
c.Env = append(os.Environ(),
c.Env = append(os.Environ(),
"GOROOT=/usr/local/go",
"GOPATH=/root/go",
"PATH=/usr/local/go/bin:" + os.Getenv("PATH"))
"GOPATH=/root/go",
"PATH=/usr/local/go/bin:"+os.Getenv("PATH"))
c.Stdout = os.Stdout
c.Stderr = os.Stderr
return c.Run()
@@ -58,7 +58,7 @@ func (b *GoSPBuilder) run(cmd string, args ...string) error {
// Build builds a Go stored procedure
func (b *GoSPBuilder) Build() error {
fmt.Println("Building Go stored procedure...")
// Use the explicitly provided Go path if available
var goExePath string
if b.GoPath != "" {
@@ -74,7 +74,7 @@ func (b *GoSPBuilder) Build() error {
}
fmt.Printf("Using detected Go executable from: %s\n", goExePath)
}
if err := os.MkdirAll(b.GoSharedLibDir, 0755); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
@@ -98,27 +98,27 @@ func main() {}
// Use the full path to Go rather than relying on PATH
fmt.Println("Running Go build with full path:", goExePath)
// Show debug information
fmt.Println("Environment variables that will be set:")
fmt.Println(" GOROOT=/usr/local/go")
fmt.Println(" GOPATH=/root/go")
fmt.Println(" PATH=/usr/local/go/bin:" + os.Getenv("PATH"))
// Verify that the Go executable exists before using it
if _, err := os.Stat(goExePath); err != nil {
return fmt.Errorf("Go executable not found at %s: %w", goExePath, err)
}
// Create the output directory if it doesn't exist
outputDir := filepath.Join(b.InstallPrefix, "lib")
if err := os.MkdirAll(outputDir, 0755); err != nil {
return fmt.Errorf("failed to create output directory %s: %w", outputDir, err)
}
// Prepare output path
outputPath := filepath.Join(outputDir, "libgosp.so")
// Instead of relying on environment variables, create a wrapper shell script
// that sets all required environment variables and then calls the Go executable
tempDir, err := os.MkdirTemp("", "go-build-")
@@ -126,7 +126,7 @@ func main() {}
return fmt.Errorf("failed to create temp directory: %w", err)
}
defer os.RemoveAll(tempDir) // Clean up when done
goRoot := filepath.Dir(filepath.Dir(goExePath)) // /usr/local/go
wrapperScript := filepath.Join(tempDir, "go-wrapper.sh")
wrapperContent := fmt.Sprintf(`#!/bin/sh
@@ -143,25 +143,25 @@ echo "PATH=$PATH"
echo "=== Running Go command ==="
echo "%s $@"
exec %s "$@"
`,
goRoot,
`,
goRoot,
filepath.Dir(goExePath),
goExePath,
goExePath)
// Write the wrapper script
if err := os.WriteFile(wrapperScript, []byte(wrapperContent), 0755); err != nil {
return fmt.Errorf("failed to write wrapper script: %w", err)
}
fmt.Printf("Created wrapper script at %s\n", wrapperScript)
// Use the wrapper script to build the Go shared library
cmd := exec.Command(wrapperScript, "build", "-buildmode=c-shared", "-o", outputPath, libPath)
cmd.Dir = filepath.Dir(libPath) // Set working directory to where the source file is
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Printf("Executing Go build via wrapper script\n")
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to build Go stored procedure: %w", err)

View File

@@ -8,7 +8,7 @@ import (
"runtime"
"strings"
"github.com/mholt/archiver/v3"
"github.com/mholt/archiver/v4"
)
const (
@@ -51,14 +51,14 @@ func (g *GoInstaller) GetGoVersion() (string, error) {
if err != nil {
return "", fmt.Errorf("failed to get Go version: %w", err)
}
// Parse go version output (format: "go version go1.x.x ...")
version := strings.TrimSpace(string(output))
parts := strings.Split(version, " ")
if len(parts) < 3 {
return "", fmt.Errorf("unexpected go version output format: %s", version)
}
// Return just the version number without the "go" prefix
return strings.TrimPrefix(parts[2], "go"), nil
}
@@ -77,7 +77,7 @@ func (g *GoInstaller) InstallGo() (string, error) {
// Default Go installation location
var installDir string = "/usr/local"
var goExePath string = filepath.Join(installDir, "go", "bin", "go")
// Check if Go is already installed by checking the binary directly
if _, err := os.Stat(goExePath); err == nil {
version, err := g.GetGoVersion()
@@ -86,7 +86,7 @@ func (g *GoInstaller) InstallGo() (string, error) {
return goExePath, nil
}
}
// Also check if Go is available in PATH as a fallback
if g.IsGoInstalled() {
path, err := exec.LookPath("go")
@@ -98,31 +98,31 @@ func (g *GoInstaller) InstallGo() (string, error) {
}
}
}
fmt.Printf("Installing Go version %s...\n", g.Version)
// Determine architecture and OS
goOS := runtime.GOOS
goArch := runtime.GOARCH
// Construct download URL
downloadURL := fmt.Sprintf("https://golang.org/dl/go%s.%s-%s.tar.gz", g.Version, goOS, goArch)
// Create a temporary directory for download
tempDir, err := os.MkdirTemp("", "go-install-")
if err != nil {
return "", fmt.Errorf("failed to create temporary directory: %w", err)
}
defer os.RemoveAll(tempDir)
// Download Go tarball
tarballPath := filepath.Join(tempDir, "go.tar.gz")
if err := downloadFile(downloadURL, tarballPath); err != nil {
return "", fmt.Errorf("failed to download Go: %w", err)
}
// Install directory - typically /usr/local for Linux/macOS
// Check if existing Go installation exists and remove it
existingGoDir := filepath.Join(installDir, "go")
if _, err := os.Stat(existingGoDir); err == nil {
@@ -131,34 +131,34 @@ func (g *GoInstaller) InstallGo() (string, error) {
return "", fmt.Errorf("failed to remove existing Go installation: %w", err)
}
}
// Extract tarball to install directory
fmt.Printf("Extracting Go to %s\n", installDir)
err = extractTarGz(tarballPath, installDir)
if err != nil {
return "", fmt.Errorf("failed to extract Go tarball: %w", err)
}
// Verify installation
var goExePathVerify = filepath.Join(installDir, "go", "bin", "go") // Use = instead of := to avoid variable shadowing
// Check if the Go binary exists
var statErr error
_, statErr = os.Stat(goExePathVerify)
if statErr != nil {
return "", fmt.Errorf("Go installation failed - go executable not found at %s", goExePathVerify)
}
// Set up environment variables
fmt.Println("Setting up Go environment variables...")
// Update PATH in /etc/profile
profilePath := "/etc/profile"
profileContent, err := os.ReadFile(profilePath)
if err != nil {
return "", fmt.Errorf("failed to read profile: %w", err)
}
// Add Go bin to PATH if not already there
goBinPath := filepath.Join(installDir, "go", "bin")
if !strings.Contains(string(profileContent), goBinPath) {
@@ -167,7 +167,7 @@ func (g *GoInstaller) InstallGo() (string, error) {
return "", fmt.Errorf("failed to update profile: %w", err)
}
}
fmt.Printf("✅ Go %s installed successfully!\n", g.Version)
return goExePath, nil
}

View File

@@ -8,7 +8,7 @@ import (
"syscall"
"time"
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
"git.ourworld.tf/herocode/heroagent/pkg/system/stats"
)
func main() {
@@ -18,11 +18,11 @@ func main() {
// Create a new stats manager with Redis connection
// Create a custom configuration
config := &stats.Config{
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
DefaultTimeout: 5 * time.Second,
ExpirationTimes: map[string]time.Duration{
"system": 60 * time.Second, // System info expires after 60 seconds
@@ -32,7 +32,7 @@ func main() {
"hardware": 120 * time.Second, // Hardware stats expire after 2 minutes
},
}
manager, err := stats.NewStatsManager(config)
if err != nil {
fmt.Printf("Error creating stats manager: %v\n", err)
@@ -61,12 +61,12 @@ func main() {
fmt.Printf(" Cores: %d\n", sysInfo.CPU.Cores)
fmt.Printf(" Model: %s\n", sysInfo.CPU.ModelName)
fmt.Printf(" Usage: %.1f%%\n", sysInfo.CPU.UsagePercent)
fmt.Println("\nMemory Information:")
fmt.Printf(" Total: %.1f GB\n", sysInfo.Memory.Total)
fmt.Printf(" Used: %.1f GB (%.1f%%)\n", sysInfo.Memory.Used, sysInfo.Memory.UsedPercent)
fmt.Printf(" Free: %.1f GB\n", sysInfo.Memory.Free)
fmt.Println("\nNetwork Information:")
fmt.Printf(" Upload Speed: %s\n", sysInfo.Network.UploadSpeed)
fmt.Printf(" Download Speed: %s\n", sysInfo.Network.DownloadSpeed)
@@ -81,7 +81,7 @@ func main() {
} else {
fmt.Printf("Found %d disks:\n", len(diskStats.Disks))
for _, disk := range diskStats.Disks {
fmt.Printf(" %s: %.1f GB total, %.1f GB free (%.1f%% used)\n",
fmt.Printf(" %s: %.1f GB total, %.1f GB free (%.1f%% used)\n",
disk.Path, disk.Total, disk.Free, disk.UsedPercent)
}
}
@@ -93,12 +93,12 @@ func main() {
if err != nil {
fmt.Printf("Error getting process stats: %v\n", err)
} else {
fmt.Printf("Total processes: %d (showing top %d)\n",
fmt.Printf("Total processes: %d (showing top %d)\n",
processStats.Total, len(processStats.Processes))
fmt.Println("\nTop Processes by CPU Usage:")
for i, proc := range processStats.Processes {
fmt.Printf(" %d. PID %d: %s (CPU: %.1f%%, Memory: %.1f MB)\n",
fmt.Printf(" %d. PID %d: %s (CPU: %.1f%%, Memory: %.1f MB)\n",
i+1, proc.PID, proc.Name, proc.CPUPercent, proc.MemoryMB)
}
}
@@ -107,10 +107,10 @@ func main() {
fmt.Println("\n4. CACHING DEMONSTRATION")
fmt.Println("----------------------")
fmt.Println("Getting network speed multiple times (should use cache):")
for i := 0; i < 3; i++ {
netSpeed := manager.GetNetworkSpeedResult()
fmt.Printf(" Request %d: Upload: %s, Download: %s\n",
fmt.Printf(" Request %d: Upload: %s, Download: %s\n",
i+1, netSpeed.UploadSpeed, netSpeed.DownloadSpeed)
time.Sleep(500 * time.Millisecond)
}
@@ -127,17 +127,17 @@ func main() {
fmt.Println("--------------------------")
fmt.Println("Enabling debug mode (direct fetching without cache)...")
manager.Debug = true
fmt.Println("Getting system info in debug mode:")
debugSysInfo, err := manager.GetSystemInfo()
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf(" CPU Usage: %.1f%%\n", debugSysInfo.CPU.UsagePercent)
fmt.Printf(" Memory Used: %.1f GB (%.1f%%)\n",
fmt.Printf(" Memory Used: %.1f GB (%.1f%%)\n",
debugSysInfo.Memory.Used, debugSysInfo.Memory.UsedPercent)
}
// Reset debug mode
manager.Debug = false
@@ -148,17 +148,17 @@ func main() {
for statsType, duration := range manager.Expiration {
fmt.Printf(" %s: %v\n", statsType, duration)
}
fmt.Println("\nChanging system stats expiration to 10 seconds...")
manager.Expiration["system"] = 10 * time.Second
fmt.Println("Updated expiration times:")
for statsType, duration := range manager.Expiration {
fmt.Printf(" %s: %v\n", statsType, duration)
}
fmt.Println("\nDemo complete. Press Ctrl+C to exit.")
// Keep the program running
select {}
}

View File

@@ -11,27 +11,27 @@ import (
"syscall"
"time"
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
"git.ourworld.tf/herocode/heroagent/pkg/system/stats"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/process"
)
// TestResult stores the results of a single test run
type TestResult struct {
StartTime time.Time
EndTime time.Time
SystemInfoTime time.Duration
DiskStatsTime time.Duration
ProcessTime time.Duration
NetworkTime time.Duration
HardwareTime time.Duration
TotalTime time.Duration
UserCPU float64
SystemCPU float64
TotalCPU float64
OverallCPU float64
MemoryUsageMB float32
NumGoroutines int
StartTime time.Time
EndTime time.Time
SystemInfoTime time.Duration
DiskStatsTime time.Duration
ProcessTime time.Duration
NetworkTime time.Duration
HardwareTime time.Duration
TotalTime time.Duration
UserCPU float64
SystemCPU float64
TotalCPU float64
OverallCPU float64
MemoryUsageMB float32
NumGoroutines int
}
func main() {
@@ -66,11 +66,11 @@ func main() {
// Create a new stats manager with Redis connection
config := &stats.Config{
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
DefaultTimeout: 5 * time.Second,
ExpirationTimes: map[string]time.Duration{
"system": 60 * time.Second, // System info expires after 60 seconds
@@ -80,7 +80,7 @@ func main() {
"hardware": 120 * time.Second, // Hardware stats expire after 2 minutes
},
}
manager, err := stats.NewStatsManager(config)
if err != nil {
fmt.Printf("Error creating stats manager: %v\n", err)
@@ -101,11 +101,11 @@ func main() {
// Set up signal handling for graceful shutdown
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// Create a ticker for running tests at the specified interval
ticker := time.NewTicker(time.Duration(*intervalPtr) * time.Second)
defer ticker.Stop()
// Store the sleep duration between operations
sleepDuration := time.Duration(*sleepPtr) * time.Millisecond
@@ -118,7 +118,7 @@ func main() {
// Store test results
var results []TestResult
// Print header
fmt.Printf("%-20s %-20s %-12s %-12s %-12s %-12s %-12s %-12s %-12s %-12s %-12s %-12s %-12s\n",
"Start Time", "End Time", "System(ms)", "Disk(ms)", "Process(ms)", "Network(ms)", "Hardware(ms)", "Total(ms)", "UserCPU(%)", "SysCPU(%)", "TotalCPU(%)", "Memory(MB)", "Goroutines")
@@ -131,7 +131,7 @@ func main() {
// Run a test and record the results
result := runTest(manager, currentProcess, sleepDuration)
results = append(results, result)
// Print the result
fmt.Printf("%-20s %-20s %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f %-12d\n",
result.StartTime.Format("15:04:05.000000"),
@@ -147,16 +147,16 @@ func main() {
result.TotalCPU,
result.MemoryUsageMB,
result.NumGoroutines)
case <-sigChan:
// Calculate and print summary statistics
fmt.Println("\nTest Summary:")
fmt.Println(strings.Repeat("-", 50))
var totalSystemTime, totalDiskTime, totalProcessTime, totalNetworkTime, totalHardwareTime, totalTime time.Duration
var totalUserCPU, totalSystemCPU, totalCombinedCPU, totalOverallCPU float64
var totalMemory float32
for _, r := range results {
totalSystemTime += r.SystemInfoTime
totalDiskTime += r.DiskStatsTime
@@ -170,7 +170,7 @@ func main() {
totalOverallCPU += r.OverallCPU
totalMemory += r.MemoryUsageMB
}
count := float64(len(results))
if count > 0 {
fmt.Printf("Average System Info Time: %.2f ms\n", float64(totalSystemTime.Microseconds())/(count*1000))
@@ -185,7 +185,7 @@ func main() {
fmt.Printf("Average Overall CPU: %.2f%%\n", totalOverallCPU/count)
fmt.Printf("Average Memory Usage: %.2f MB\n", float64(totalMemory)/count)
}
fmt.Println("\nTest completed. Exiting...")
return
}
@@ -196,90 +196,90 @@ func main() {
func runTest(manager *stats.StatsManager, proc *process.Process, sleepBetweenOps time.Duration) TestResult {
// Get initial CPU times for the process
initialTimes, _ := proc.Times()
// Get initial overall CPU usage
_, _ = cpu.Percent(0, false) // Discard initial reading, we'll only use the final reading
result := TestResult{
StartTime: time.Now(),
}
// Measure total time
totalStart := time.Now()
// Measure system info time
start := time.Now()
_, _ = manager.GetSystemInfo()
result.SystemInfoTime = time.Since(start)
// Sleep between operations if configured
if sleepBetweenOps > 0 {
time.Sleep(sleepBetweenOps)
}
// Measure disk stats time
start = time.Now()
_, _ = manager.GetDiskStats()
result.DiskStatsTime = time.Since(start)
// Sleep between operations if configured
if sleepBetweenOps > 0 {
time.Sleep(sleepBetweenOps)
}
// Measure process stats time
start = time.Now()
_, _ = manager.GetProcessStats(10)
result.ProcessTime = time.Since(start)
// Sleep between operations if configured
if sleepBetweenOps > 0 {
time.Sleep(sleepBetweenOps)
}
// Measure network speed time
start = time.Now()
_ = manager.GetNetworkSpeedResult()
result.NetworkTime = time.Since(start)
// Sleep between operations if configured
if sleepBetweenOps > 0 {
time.Sleep(sleepBetweenOps)
}
// Measure hardware stats time
start = time.Now()
_ = manager.GetHardwareStatsJSON()
result.HardwareTime = time.Since(start)
// Record total time
result.TotalTime = time.Since(totalStart)
result.EndTime = time.Now()
// Get final CPU times for the process
finalTimes, _ := proc.Times()
// Calculate CPU usage for this specific operation
if initialTimes != nil && finalTimes != nil {
result.UserCPU = (finalTimes.User - initialTimes.User) * 100
result.SystemCPU = (finalTimes.System - initialTimes.System) * 100
result.TotalCPU = result.UserCPU + result.SystemCPU
}
// Get overall CPU usage
finalOverallCPU, _ := cpu.Percent(0, false)
if len(finalOverallCPU) > 0 {
result.OverallCPU = finalOverallCPU[0]
}
// Measure memory usage
memInfo, _ := proc.MemoryInfo()
if memInfo != nil {
result.MemoryUsageMB = float32(memInfo.RSS) / (1024 * 1024)
}
// Record number of goroutines
result.NumGoroutines = runtime.NumGoroutine()
return result
}

View File

@@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
"git.ourworld.tf/herocode/heroagent/pkg/system/stats"
"github.com/redis/go-redis/v9"
)

View File

@@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
"git.ourworld.tf/herocode/heroagent/pkg/system/stats"
)
func main() {
@@ -15,21 +15,21 @@ func main() {
// Create a new stats manager with Redis connection
config := &stats.Config{
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
RedisAddr: "localhost:6379",
RedisPassword: "",
RedisDB: 0,
Debug: false,
QueueSize: 100,
DefaultTimeout: 5 * time.Second,
ExpirationTimes: map[string]time.Duration{
"system": 30 * time.Second, // System info expires after 30 seconds
"disk": 60 * time.Second, // Disk info expires after 1 minute
"process": 15 * time.Second, // Process info expires after 15 seconds
"network": 20 * time.Second, // Network info expires after 20 seconds
"hardware": 60 * time.Second, // Hardware stats expire after 1 minute
"system": 30 * time.Second, // System info expires after 30 seconds
"disk": 60 * time.Second, // Disk info expires after 1 minute
"process": 15 * time.Second, // Process info expires after 15 seconds
"network": 20 * time.Second, // Network info expires after 20 seconds
"hardware": 60 * time.Second, // Hardware stats expire after 1 minute
},
}
manager, err := stats.NewStatsManager(config)
if err != nil {
fmt.Printf("Error creating stats manager: %v\n", err)
@@ -40,7 +40,7 @@ func main() {
// DISK INFORMATION
fmt.Println("\n1. DISK INFORMATION")
fmt.Println("------------------")
// Get all disk stats using the manager
diskStats, err := manager.GetDiskStats()
if err != nil {
@@ -48,7 +48,7 @@ func main() {
} else {
fmt.Printf("Found %d disks:\n", len(diskStats.Disks))
for _, disk := range diskStats.Disks {
fmt.Printf(" %s: %.1f GB total, %.1f GB free (%.1f%% used)\n",
fmt.Printf(" %s: %.1f GB total, %.1f GB free (%.1f%% used)\n",
disk.Path, disk.Total, disk.Free, disk.UsedPercent)
}
}
@@ -58,7 +58,7 @@ func main() {
if err != nil {
fmt.Printf("Error getting root disk info: %v\n", err)
} else {
fmt.Printf("\nRoot Disk: %.1f GB total, %.1f GB free (%.1f%% used)\n",
fmt.Printf("\nRoot Disk: %.1f GB total, %.1f GB free (%.1f%% used)\n",
rootDisk.Total, rootDisk.Free, rootDisk.UsedPercent)
}
@@ -68,7 +68,7 @@ func main() {
// SYSTEM INFORMATION
fmt.Println("\n2. SYSTEM INFORMATION")
fmt.Println("--------------------")
// Get system info using the manager
sysInfo, err := manager.GetSystemInfo()
if err != nil {
@@ -78,12 +78,12 @@ func main() {
fmt.Printf(" Cores: %d\n", sysInfo.CPU.Cores)
fmt.Printf(" Model: %s\n", sysInfo.CPU.ModelName)
fmt.Printf(" Usage: %.1f%%\n", sysInfo.CPU.UsagePercent)
fmt.Println("\nMemory Information:")
fmt.Printf(" Total: %.1f GB\n", sysInfo.Memory.Total)
fmt.Printf(" Used: %.1f GB (%.1f%%)\n", sysInfo.Memory.Used, sysInfo.Memory.UsedPercent)
fmt.Printf(" Free: %.1f GB\n", sysInfo.Memory.Free)
fmt.Println("\nNetwork Information:")
fmt.Printf(" Upload Speed: %s\n", sysInfo.Network.UploadSpeed)
fmt.Printf(" Download Speed: %s\n", sysInfo.Network.DownloadSpeed)
@@ -98,18 +98,18 @@ func main() {
// PROCESS INFORMATION
fmt.Println("\n3. PROCESS INFORMATION")
fmt.Println("---------------------")
// Get process stats using the manager
processStats, err := manager.GetProcessStats(5) // Get top 5 processes
if err != nil {
fmt.Printf("Error getting process stats: %v\n", err)
} else {
fmt.Printf("Total processes: %d (showing top %d)\n",
fmt.Printf("Total processes: %d (showing top %d)\n",
processStats.Total, len(processStats.Processes))
fmt.Println("\nTop Processes by CPU Usage:")
for i, proc := range processStats.Processes {
fmt.Printf(" %d. PID %d: %s (CPU: %.1f%%, Memory: %.1f MB)\n",
fmt.Printf(" %d. PID %d: %s (CPU: %.1f%%, Memory: %.1f MB)\n",
i+1, proc.PID, proc.Name, proc.CPUPercent, proc.MemoryMB)
}
}
@@ -128,7 +128,7 @@ func main() {
// COMBINED STATS
fmt.Println("\n4. COMBINED STATS FUNCTIONS")
fmt.Println("--------------------------")
// Hardware stats using the manager
fmt.Println("\nHardware Stats:")
hardwareStats := manager.GetHardwareStats()
@@ -151,17 +151,17 @@ func main() {
// Wait and measure network speed again
fmt.Println("\nWaiting 2 seconds for another network speed measurement...")
time.Sleep(2 * time.Second)
// Get updated network speed using the manager
updatedNetSpeed := manager.GetNetworkSpeedResult()
fmt.Println("\nUpdated Network Speed:")
fmt.Printf(" Upload: %s\n", updatedNetSpeed.UploadSpeed)
fmt.Printf(" Download: %s\n", updatedNetSpeed.DownloadSpeed)
// CACHE MANAGEMENT
fmt.Println("\n5. CACHE MANAGEMENT")
fmt.Println("------------------")
// Force update of system stats
fmt.Println("\nForcing update of system stats...")
err = manager.ForceUpdate("system")
@@ -170,7 +170,7 @@ func main() {
} else {
fmt.Println("System stats updated successfully")
}
// Get updated system info
updatedSysInfo, err := manager.GetSystemInfo()
if err != nil {
@@ -178,7 +178,7 @@ func main() {
} else {
fmt.Println("\nUpdated CPU Usage: " + fmt.Sprintf("%.1f%%", updatedSysInfo.CPU.UsagePercent))
}
// Clear cache for disk stats
fmt.Println("\nClearing cache for disk stats...")
err = manager.ClearCache("disk")
@@ -187,7 +187,7 @@ func main() {
} else {
fmt.Println("Disk stats cache cleared successfully")
}
// Toggle debug mode
fmt.Println("\nToggling debug mode (direct fetching without cache)...")
manager.Debug = !manager.Debug