| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | package performanceimport (	"os"	"regexp"	"runtime"	"strconv"	"github.com/0xJacky/Nginx-UI/internal/nginx"	"github.com/pkg/errors")type NginxConfigInfo struct {	WorkerProcesses           int              `json:"worker_processes"`	WorkerConnections         int              `json:"worker_connections"`	ProcessMode               string           `json:"process_mode"`	KeepaliveTimeout          string           `json:"keepalive_timeout"`	Gzip                      string           `json:"gzip"`	GzipMinLength             int              `json:"gzip_min_length"`	GzipCompLevel             int              `json:"gzip_comp_level"`	ClientMaxBodySize         string           `json:"client_max_body_size"` // with unit	ServerNamesHashBucketSize string           `json:"server_names_hash_bucket_size"`	ClientHeaderBufferSize    string           `json:"client_header_buffer_size"` // with unit	ClientBodyBufferSize      string           `json:"client_body_buffer_size"`   // with unit	ProxyCache                ProxyCacheConfig `json:"proxy_cache"`}// GetNginxWorkerConfigInfo Get Nginx config info of worker_processes and worker_connectionsfunc GetNginxWorkerConfigInfo() (*NginxConfigInfo, error) {	result := &NginxConfigInfo{		WorkerProcesses:           1,		WorkerConnections:         1024,		ProcessMode:               "manual",		KeepaliveTimeout:          "65s",		Gzip:                      "off",		GzipMinLength:             1,		GzipCompLevel:             1,		ClientMaxBodySize:         "1m",		ServerNamesHashBucketSize: "32k",		ClientHeaderBufferSize:    "1k",		ClientBodyBufferSize:      "8k",		ProxyCache: ProxyCacheConfig{			Enabled:     false,			Path:        "/var/cache/nginx/proxy_cache",			Levels:      "1:2",			UseTempPath: "off",			KeysZone:    "proxy_cache:10m",			Inactive:    "60m",			MaxSize:     "1g",			// Purger:      "off",		},	}	confPath := nginx.GetConfEntryPath()	if confPath == "" {		return nil, errors.New("failed to get nginx.conf path")	}	// Read the current configuration	content, err := os.ReadFile(confPath)	if err != nil {		return nil, errors.Wrap(err, "failed to read nginx.conf")	}	outputStr := string(content)	// Parse worker_processes	wpRe := regexp.MustCompile(`worker_processes\s+(\d+|auto);`)	if matches := wpRe.FindStringSubmatch(outputStr); len(matches) > 1 {		if matches[1] == "auto" {			result.WorkerProcesses = runtime.NumCPU()			result.ProcessMode = "auto"		} else {			result.WorkerProcesses, _ = strconv.Atoi(matches[1])			result.ProcessMode = "manual"		}	}	// Parse worker_connections	wcRe := regexp.MustCompile(`worker_connections\s+(\d+);`)	if matches := wcRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.WorkerConnections, _ = strconv.Atoi(matches[1])	}	// Parse keepalive_timeout	ktRe := regexp.MustCompile(`keepalive_timeout\s+(\d+[smhdwMy]?);`)	if matches := ktRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.KeepaliveTimeout = matches[1]	}	// Parse gzip	gzipRe := regexp.MustCompile(`gzip\s+(on|off);`)	if matches := gzipRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.Gzip = matches[1]	}	// Parse gzip_min_length	gzipMinRe := regexp.MustCompile(`gzip_min_length\s+(\d+);`)	if matches := gzipMinRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.GzipMinLength, _ = strconv.Atoi(matches[1])	}	// Parse gzip_comp_level	gzipCompRe := regexp.MustCompile(`gzip_comp_level\s+(\d+);`)	if matches := gzipCompRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.GzipCompLevel, _ = strconv.Atoi(matches[1])	}	// Parse client_max_body_size with any unit (k, m, g)	cmaxRe := regexp.MustCompile(`client_max_body_size\s+(\d+[kmg]?);`)	if matches := cmaxRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.ClientMaxBodySize = matches[1]	}	// Parse server_names_hash_bucket_size	hashRe := regexp.MustCompile(`server_names_hash_bucket_size\s+(\d+[kmg]?);`)	if matches := hashRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.ServerNamesHashBucketSize = matches[1]	}	// Parse client_header_buffer_size with any unit (k, m, g)	headerRe := regexp.MustCompile(`client_header_buffer_size\s+(\d+[kmg]?);`)	if matches := headerRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.ClientHeaderBufferSize = matches[1]	}	// Parse client_body_buffer_size with any unit (k, m, g)	bodyRe := regexp.MustCompile(`client_body_buffer_size\s+(\d+[kmg]?);`)	if matches := bodyRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.ClientBodyBufferSize = matches[1]	}	// Parse proxy_cache_path settings	proxyCachePathRe := regexp.MustCompile(`proxy_cache_path\s+([^;]+);`)	if matches := proxyCachePathRe.FindStringSubmatch(outputStr); len(matches) > 1 {		result.ProxyCache.Enabled = true		proxyCacheParams := matches[1]		// Extract path (first parameter)		pathRe := regexp.MustCompile(`^\s*([^\s]+)`)		if pathMatches := pathRe.FindStringSubmatch(proxyCacheParams); len(pathMatches) > 1 {			result.ProxyCache.Path = pathMatches[1]		}		// Extract levels parameter		levelsRe := regexp.MustCompile(`levels=([^\s]+)`)		if levelsMatches := levelsRe.FindStringSubmatch(proxyCacheParams); len(levelsMatches) > 1 {			result.ProxyCache.Levels = levelsMatches[1]		}		// Extract use_temp_path parameter		useTempPathRe := regexp.MustCompile(`use_temp_path=(on|off)`)		if useTempPathMatches := useTempPathRe.FindStringSubmatch(proxyCacheParams); len(useTempPathMatches) > 1 {			result.ProxyCache.UseTempPath = useTempPathMatches[1]		}		// Extract keys_zone parameter		keysZoneRe := regexp.MustCompile(`keys_zone=([^\s]+)`)		if keysZoneMatches := keysZoneRe.FindStringSubmatch(proxyCacheParams); len(keysZoneMatches) > 1 {			result.ProxyCache.KeysZone = keysZoneMatches[1]		}		// Extract inactive parameter		inactiveRe := regexp.MustCompile(`inactive=([^\s]+)`)		if inactiveMatches := inactiveRe.FindStringSubmatch(proxyCacheParams); len(inactiveMatches) > 1 {			result.ProxyCache.Inactive = inactiveMatches[1]		}		// Extract max_size parameter		maxSizeRe := regexp.MustCompile(`max_size=([^\s]+)`)		if maxSizeMatches := maxSizeRe.FindStringSubmatch(proxyCacheParams); len(maxSizeMatches) > 1 {			result.ProxyCache.MaxSize = maxSizeMatches[1]		}		// Extract min_free parameter		minFreeRe := regexp.MustCompile(`min_free=([^\s]+)`)		if minFreeMatches := minFreeRe.FindStringSubmatch(proxyCacheParams); len(minFreeMatches) > 1 {			result.ProxyCache.MinFree = minFreeMatches[1]		}		// Extract manager_files parameter		managerFilesRe := regexp.MustCompile(`manager_files=([^\s]+)`)		if managerFilesMatches := managerFilesRe.FindStringSubmatch(proxyCacheParams); len(managerFilesMatches) > 1 {			result.ProxyCache.ManagerFiles = managerFilesMatches[1]		}		// Extract manager_sleep parameter		managerSleepRe := regexp.MustCompile(`manager_sleep=([^\s]+)`)		if managerSleepMatches := managerSleepRe.FindStringSubmatch(proxyCacheParams); len(managerSleepMatches) > 1 {			result.ProxyCache.ManagerSleep = managerSleepMatches[1]		}		// Extract manager_threshold parameter		managerThresholdRe := regexp.MustCompile(`manager_threshold=([^\s]+)`)		if managerThresholdMatches := managerThresholdRe.FindStringSubmatch(proxyCacheParams); len(managerThresholdMatches) > 1 {			result.ProxyCache.ManagerThreshold = managerThresholdMatches[1]		}		// Extract loader_files parameter		loaderFilesRe := regexp.MustCompile(`loader_files=([^\s]+)`)		if loaderFilesMatches := loaderFilesRe.FindStringSubmatch(proxyCacheParams); len(loaderFilesMatches) > 1 {			result.ProxyCache.LoaderFiles = loaderFilesMatches[1]		}		// Extract loader_sleep parameter		loaderSleepRe := regexp.MustCompile(`loader_sleep=([^\s]+)`)		if loaderSleepMatches := loaderSleepRe.FindStringSubmatch(proxyCacheParams); len(loaderSleepMatches) > 1 {			result.ProxyCache.LoaderSleep = loaderSleepMatches[1]		}		// Extract loader_threshold parameter		loaderThresholdRe := regexp.MustCompile(`loader_threshold=([^\s]+)`)		if loaderThresholdMatches := loaderThresholdRe.FindStringSubmatch(proxyCacheParams); len(loaderThresholdMatches) > 1 {			result.ProxyCache.LoaderThreshold = loaderThresholdMatches[1]		}		// Extract purger parameter		// purgerRe := regexp.MustCompile(`purger=(on|off)`)		// if purgerMatches := purgerRe.FindStringSubmatch(proxyCacheParams); len(purgerMatches) > 1 {		// 	result.ProxyCache.Purger = purgerMatches[1]		// }		// // Extract purger_files parameter		// purgerFilesRe := regexp.MustCompile(`purger_files=([^\s]+)`)		// if purgerFilesMatches := purgerFilesRe.FindStringSubmatch(proxyCacheParams); len(purgerFilesMatches) > 1 {		// 	result.ProxyCache.PurgerFiles = purgerFilesMatches[1]		// }		// // Extract purger_sleep parameter		// purgerSleepRe := regexp.MustCompile(`purger_sleep=([^\s]+)`)		// if purgerSleepMatches := purgerSleepRe.FindStringSubmatch(proxyCacheParams); len(purgerSleepMatches) > 1 {		// 	result.ProxyCache.PurgerSleep = purgerSleepMatches[1]		// }		// // Extract purger_threshold parameter		// purgerThresholdRe := regexp.MustCompile(`purger_threshold=([^\s]+)`)		// if purgerThresholdMatches := purgerThresholdRe.FindStringSubmatch(proxyCacheParams); len(purgerThresholdMatches) > 1 {		// 	result.ProxyCache.PurgerThreshold = purgerThresholdMatches[1]		// }	} else {		// No proxy_cache_path directive found, so disable it		result.ProxyCache.Enabled = false	}	return result, nil}
 |