config_info.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package performance
  2. import (
  3. "os"
  4. "regexp"
  5. "runtime"
  6. "strconv"
  7. "github.com/0xJacky/Nginx-UI/internal/nginx"
  8. "github.com/pkg/errors"
  9. )
  10. type NginxConfigInfo struct {
  11. WorkerProcesses int `json:"worker_processes"`
  12. WorkerConnections int `json:"worker_connections"`
  13. ProcessMode string `json:"process_mode"`
  14. KeepaliveTimeout string `json:"keepalive_timeout"`
  15. Gzip string `json:"gzip"`
  16. GzipMinLength int `json:"gzip_min_length"`
  17. GzipCompLevel int `json:"gzip_comp_level"`
  18. ClientMaxBodySize string `json:"client_max_body_size"` // with unit
  19. ServerNamesHashBucketSize string `json:"server_names_hash_bucket_size"`
  20. ClientHeaderBufferSize string `json:"client_header_buffer_size"` // with unit
  21. ClientBodyBufferSize string `json:"client_body_buffer_size"` // with unit
  22. ProxyCache ProxyCacheConfig `json:"proxy_cache"`
  23. }
  24. // GetNginxWorkerConfigInfo Get Nginx config info of worker_processes and worker_connections
  25. func GetNginxWorkerConfigInfo() (*NginxConfigInfo, error) {
  26. result := &NginxConfigInfo{
  27. WorkerProcesses: 1,
  28. WorkerConnections: 1024,
  29. ProcessMode: "manual",
  30. KeepaliveTimeout: "65s",
  31. Gzip: "off",
  32. GzipMinLength: 1,
  33. GzipCompLevel: 1,
  34. ClientMaxBodySize: "1m",
  35. ServerNamesHashBucketSize: "32k",
  36. ClientHeaderBufferSize: "1k",
  37. ClientBodyBufferSize: "8k",
  38. ProxyCache: ProxyCacheConfig{
  39. Enabled: false,
  40. Path: "/var/cache/nginx/proxy_cache",
  41. Levels: "1:2",
  42. UseTempPath: "off",
  43. KeysZone: "proxy_cache:10m",
  44. Inactive: "60m",
  45. MaxSize: "1g",
  46. // Purger: "off",
  47. },
  48. }
  49. confPath := nginx.GetConfPath("nginx.conf")
  50. if confPath == "" {
  51. return nil, errors.New("failed to get nginx.conf path")
  52. }
  53. // Read the current configuration
  54. content, err := os.ReadFile(confPath)
  55. if err != nil {
  56. return nil, errors.Wrap(err, "failed to read nginx.conf")
  57. }
  58. outputStr := string(content)
  59. // Parse worker_processes
  60. wpRe := regexp.MustCompile(`worker_processes\s+(\d+|auto);`)
  61. if matches := wpRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  62. if matches[1] == "auto" {
  63. result.WorkerProcesses = runtime.NumCPU()
  64. result.ProcessMode = "auto"
  65. } else {
  66. result.WorkerProcesses, _ = strconv.Atoi(matches[1])
  67. result.ProcessMode = "manual"
  68. }
  69. }
  70. // Parse worker_connections
  71. wcRe := regexp.MustCompile(`worker_connections\s+(\d+);`)
  72. if matches := wcRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  73. result.WorkerConnections, _ = strconv.Atoi(matches[1])
  74. }
  75. // Parse keepalive_timeout
  76. ktRe := regexp.MustCompile(`keepalive_timeout\s+(\d+[smhdwMy]?);`)
  77. if matches := ktRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  78. result.KeepaliveTimeout = matches[1]
  79. }
  80. // Parse gzip
  81. gzipRe := regexp.MustCompile(`gzip\s+(on|off);`)
  82. if matches := gzipRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  83. result.Gzip = matches[1]
  84. }
  85. // Parse gzip_min_length
  86. gzipMinRe := regexp.MustCompile(`gzip_min_length\s+(\d+);`)
  87. if matches := gzipMinRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  88. result.GzipMinLength, _ = strconv.Atoi(matches[1])
  89. }
  90. // Parse gzip_comp_level
  91. gzipCompRe := regexp.MustCompile(`gzip_comp_level\s+(\d+);`)
  92. if matches := gzipCompRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  93. result.GzipCompLevel, _ = strconv.Atoi(matches[1])
  94. }
  95. // Parse client_max_body_size with any unit (k, m, g)
  96. cmaxRe := regexp.MustCompile(`client_max_body_size\s+(\d+[kmg]?);`)
  97. if matches := cmaxRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  98. result.ClientMaxBodySize = matches[1]
  99. }
  100. // Parse server_names_hash_bucket_size
  101. hashRe := regexp.MustCompile(`server_names_hash_bucket_size\s+(\d+[kmg]?);`)
  102. if matches := hashRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  103. result.ServerNamesHashBucketSize = matches[1]
  104. }
  105. // Parse client_header_buffer_size with any unit (k, m, g)
  106. headerRe := regexp.MustCompile(`client_header_buffer_size\s+(\d+[kmg]?);`)
  107. if matches := headerRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  108. result.ClientHeaderBufferSize = matches[1]
  109. }
  110. // Parse client_body_buffer_size with any unit (k, m, g)
  111. bodyRe := regexp.MustCompile(`client_body_buffer_size\s+(\d+[kmg]?);`)
  112. if matches := bodyRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  113. result.ClientBodyBufferSize = matches[1]
  114. }
  115. // Parse proxy_cache_path settings
  116. proxyCachePathRe := regexp.MustCompile(`proxy_cache_path\s+([^;]+);`)
  117. if matches := proxyCachePathRe.FindStringSubmatch(outputStr); len(matches) > 1 {
  118. result.ProxyCache.Enabled = true
  119. proxyCacheParams := matches[1]
  120. // Extract path (first parameter)
  121. pathRe := regexp.MustCompile(`^\s*([^\s]+)`)
  122. if pathMatches := pathRe.FindStringSubmatch(proxyCacheParams); len(pathMatches) > 1 {
  123. result.ProxyCache.Path = pathMatches[1]
  124. }
  125. // Extract levels parameter
  126. levelsRe := regexp.MustCompile(`levels=([^\s]+)`)
  127. if levelsMatches := levelsRe.FindStringSubmatch(proxyCacheParams); len(levelsMatches) > 1 {
  128. result.ProxyCache.Levels = levelsMatches[1]
  129. }
  130. // Extract use_temp_path parameter
  131. useTempPathRe := regexp.MustCompile(`use_temp_path=(on|off)`)
  132. if useTempPathMatches := useTempPathRe.FindStringSubmatch(proxyCacheParams); len(useTempPathMatches) > 1 {
  133. result.ProxyCache.UseTempPath = useTempPathMatches[1]
  134. }
  135. // Extract keys_zone parameter
  136. keysZoneRe := regexp.MustCompile(`keys_zone=([^\s]+)`)
  137. if keysZoneMatches := keysZoneRe.FindStringSubmatch(proxyCacheParams); len(keysZoneMatches) > 1 {
  138. result.ProxyCache.KeysZone = keysZoneMatches[1]
  139. }
  140. // Extract inactive parameter
  141. inactiveRe := regexp.MustCompile(`inactive=([^\s]+)`)
  142. if inactiveMatches := inactiveRe.FindStringSubmatch(proxyCacheParams); len(inactiveMatches) > 1 {
  143. result.ProxyCache.Inactive = inactiveMatches[1]
  144. }
  145. // Extract max_size parameter
  146. maxSizeRe := regexp.MustCompile(`max_size=([^\s]+)`)
  147. if maxSizeMatches := maxSizeRe.FindStringSubmatch(proxyCacheParams); len(maxSizeMatches) > 1 {
  148. result.ProxyCache.MaxSize = maxSizeMatches[1]
  149. }
  150. // Extract min_free parameter
  151. minFreeRe := regexp.MustCompile(`min_free=([^\s]+)`)
  152. if minFreeMatches := minFreeRe.FindStringSubmatch(proxyCacheParams); len(minFreeMatches) > 1 {
  153. result.ProxyCache.MinFree = minFreeMatches[1]
  154. }
  155. // Extract manager_files parameter
  156. managerFilesRe := regexp.MustCompile(`manager_files=([^\s]+)`)
  157. if managerFilesMatches := managerFilesRe.FindStringSubmatch(proxyCacheParams); len(managerFilesMatches) > 1 {
  158. result.ProxyCache.ManagerFiles = managerFilesMatches[1]
  159. }
  160. // Extract manager_sleep parameter
  161. managerSleepRe := regexp.MustCompile(`manager_sleep=([^\s]+)`)
  162. if managerSleepMatches := managerSleepRe.FindStringSubmatch(proxyCacheParams); len(managerSleepMatches) > 1 {
  163. result.ProxyCache.ManagerSleep = managerSleepMatches[1]
  164. }
  165. // Extract manager_threshold parameter
  166. managerThresholdRe := regexp.MustCompile(`manager_threshold=([^\s]+)`)
  167. if managerThresholdMatches := managerThresholdRe.FindStringSubmatch(proxyCacheParams); len(managerThresholdMatches) > 1 {
  168. result.ProxyCache.ManagerThreshold = managerThresholdMatches[1]
  169. }
  170. // Extract loader_files parameter
  171. loaderFilesRe := regexp.MustCompile(`loader_files=([^\s]+)`)
  172. if loaderFilesMatches := loaderFilesRe.FindStringSubmatch(proxyCacheParams); len(loaderFilesMatches) > 1 {
  173. result.ProxyCache.LoaderFiles = loaderFilesMatches[1]
  174. }
  175. // Extract loader_sleep parameter
  176. loaderSleepRe := regexp.MustCompile(`loader_sleep=([^\s]+)`)
  177. if loaderSleepMatches := loaderSleepRe.FindStringSubmatch(proxyCacheParams); len(loaderSleepMatches) > 1 {
  178. result.ProxyCache.LoaderSleep = loaderSleepMatches[1]
  179. }
  180. // Extract loader_threshold parameter
  181. loaderThresholdRe := regexp.MustCompile(`loader_threshold=([^\s]+)`)
  182. if loaderThresholdMatches := loaderThresholdRe.FindStringSubmatch(proxyCacheParams); len(loaderThresholdMatches) > 1 {
  183. result.ProxyCache.LoaderThreshold = loaderThresholdMatches[1]
  184. }
  185. // Extract purger parameter
  186. // purgerRe := regexp.MustCompile(`purger=(on|off)`)
  187. // if purgerMatches := purgerRe.FindStringSubmatch(proxyCacheParams); len(purgerMatches) > 1 {
  188. // result.ProxyCache.Purger = purgerMatches[1]
  189. // }
  190. // // Extract purger_files parameter
  191. // purgerFilesRe := regexp.MustCompile(`purger_files=([^\s]+)`)
  192. // if purgerFilesMatches := purgerFilesRe.FindStringSubmatch(proxyCacheParams); len(purgerFilesMatches) > 1 {
  193. // result.ProxyCache.PurgerFiles = purgerFilesMatches[1]
  194. // }
  195. // // Extract purger_sleep parameter
  196. // purgerSleepRe := regexp.MustCompile(`purger_sleep=([^\s]+)`)
  197. // if purgerSleepMatches := purgerSleepRe.FindStringSubmatch(proxyCacheParams); len(purgerSleepMatches) > 1 {
  198. // result.ProxyCache.PurgerSleep = purgerSleepMatches[1]
  199. // }
  200. // // Extract purger_threshold parameter
  201. // purgerThresholdRe := regexp.MustCompile(`purger_threshold=([^\s]+)`)
  202. // if purgerThresholdMatches := purgerThresholdRe.FindStringSubmatch(proxyCacheParams); len(purgerThresholdMatches) > 1 {
  203. // result.ProxyCache.PurgerThreshold = purgerThresholdMatches[1]
  204. // }
  205. } else {
  206. // No proxy_cache_path directive found, so disable it
  207. result.ProxyCache.Enabled = false
  208. }
  209. return result, nil
  210. }