system_services.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package services
  2. import (
  3. "bytes"
  4. "database/sql"
  5. "fmt"
  6. "os"
  7. "path/filepath"
  8. "sync"
  9. "time"
  10. "xg_dba/api"
  11. "xg_dba/internal/global"
  12. "xg_dba/internal/models"
  13. "xg_dba/module/remote"
  14. _ "xg_dba/pkg/xugu"
  15. "github.com/BurntSushi/toml"
  16. )
  17. func SetSystemInfo_service(connectInfo []api.ServerInfoRequest, saveFilePath string, progressID string) error {
  18. //ping服务器是否能连通
  19. //ssh连接服务器
  20. //执行命令
  21. //返回结果并存储到本地
  22. var wg sync.WaitGroup
  23. var mu sync.Mutex
  24. defer global.Progress.CloseProgress(progressID) // 处理完成后关闭进度 channel
  25. progressChan, ok := global.Progress.GetProgressChan(progressID)
  26. if !ok {
  27. return fmt.Errorf("Progress 队列错误")
  28. }
  29. commands := map[string]string{
  30. "OS Info": "cat /etc/os-release",
  31. "CPU Info": "lscpu",
  32. "Memory Info": "free -h",
  33. "Disk Info": "df -h",
  34. "Network Info": "ip addr",
  35. "Disk Speed": "dd if=/dev/zero of=/tmp/testfile bs=8K count=102400 oflag=direct; rm -f /tmp/testfile",
  36. "Network Speed": "ping -c 4 8.8.8.8",
  37. }
  38. //循环每一组集群去执行命令1
  39. for _, server := range connectInfo {
  40. wg.Add(1)
  41. //开启协程对每一组集群去执行命令
  42. go func(server api.ServerInfoRequest) {
  43. defer wg.Done()
  44. systemInfo := models.SystemMetaInfo{}
  45. var serverWg sync.WaitGroup
  46. for name, cmd := range commands {
  47. serverWg.Add(1)
  48. go func(name, cmd string, server api.ServerInfoRequest) {
  49. defer serverWg.Done()
  50. // 每次执行命令都新建一个 SSH 客户端
  51. sshClient, err := remote.NewSSHClient("1", server.Username, server.Password, server.Host, server.Port)
  52. if err != nil {
  53. global.Logger.Errorf("NewSSHClient failed for %s on server %s: %v", name, server.Host, err)
  54. progressChan <- fmt.Sprintf("%s on server %s: failed to connect", name, server.Host)
  55. return
  56. }
  57. defer sshClient.Close()
  58. output, err := sshClient.RunCommand(cmd)
  59. if err != nil {
  60. global.Logger.Errorf("%s command failed on server %s: %v", name, server.Host, err)
  61. progressChan <- fmt.Sprintf("%s on server %s: command failed", name, server.Host)
  62. return
  63. }
  64. mu.Lock()
  65. // 根据命令名称将输出赋值到结构体字段
  66. switch name {
  67. case "OS Info":
  68. systemInfo.Os = output
  69. case "CPU Info":
  70. systemInfo.Cpu = output
  71. case "Memory Info":
  72. systemInfo.Memory = output
  73. case "Disk Info":
  74. systemInfo.Disk = output
  75. case "Network Info":
  76. systemInfo.Network = output
  77. case "Disk Speed":
  78. systemInfo.DiskSpeed = output
  79. case "Network Speed":
  80. systemInfo.NetworkSpeed = output
  81. }
  82. mu.Unlock()
  83. progressChan <- fmt.Sprintf("%s on server %s: completed. data = %s", name, server.Host, output)
  84. fmt.Printf("--%s on server %s:\n%s\n", name, server.Host, output)
  85. }(name, cmd, server)
  86. }
  87. serverWg.Wait()
  88. if systemInfo.Cpu != "" {
  89. //progressChan <- fmt.Sprintf("Error: failed to get system meta info for server %s", server.Host)
  90. timestamp := time.Now().Format("20060102_150405")
  91. os.MkdirAll(filepath.Dir(saveFilePath), os.ModePerm)
  92. filePath := fmt.Sprintf("%s%s_os_info_%s.toml", saveFilePath, server.Host, timestamp)
  93. err := saveSystemMetaInfoToFile(systemInfo, filePath)
  94. if err != nil {
  95. progressChan <- fmt.Sprintf("Error: failed to save system meta info for server %s", server.Host)
  96. fmt.Printf("Error: %v\n", err)
  97. } else {
  98. progressChan <- fmt.Sprintf("System meta info saved successfully for server %s", server.Host)
  99. fmt.Println("System meta info saved successfully for server", server.Host)
  100. }
  101. return
  102. } else {
  103. return
  104. }
  105. }(server)
  106. }
  107. wg.Wait()
  108. //close(progressChan)
  109. return nil
  110. }
  111. // 保存系统环境信息到文件
  112. func saveSystemMetaInfoToFile(info models.SystemMetaInfo, filePath string) error {
  113. var buffer bytes.Buffer
  114. encoder := toml.NewEncoder(&buffer)
  115. if err := encoder.Encode(info); err != nil {
  116. return fmt.Errorf("failed to encode system meta info to TOML: %v", err)
  117. }
  118. err := os.WriteFile(filePath, buffer.Bytes(), 0644)
  119. if err != nil {
  120. return fmt.Errorf("failed to write to file: %v", err)
  121. }
  122. return nil
  123. }
  124. func GetDb() {
  125. // 连接数据库
  126. db, err := sql.Open("xugusql", "root:123456@tcp(127.0.0.1:3306)/test")
  127. if err != nil {
  128. panic(err.Error())
  129. }
  130. db.Close()
  131. }