| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | package nginximport (	"os"	"path/filepath"	"regexp"	"strings"	"github.com/uozi-tech/cosy/logger")// Regular expressions for parsing log directives from nginx -T outputconst (	// AccessLogRegexPattern matches access_log directive with unquoted path	// Matches: access_log /path/to/file	AccessLogRegexPattern = `(?m)^\s*access_log\s+([^\s;]+)`	// ErrorLogRegexPattern matches error_log directive with unquoted path	// Matches: error_log /path/to/file	ErrorLogRegexPattern = `(?m)^\s*error_log\s+([^\s;]+)`)var (	accessLogRegex *regexp.Regexp	errorLogRegex  *regexp.Regexp)func init() {	accessLogRegex = regexp.MustCompile(AccessLogRegexPattern)	errorLogRegex = regexp.MustCompile(ErrorLogRegexPattern)}// isValidRegularFile checks if the given path is a valid regular file// Returns true if the path exists and is a regular file (not a directory or special file)func isValidRegularFile(path string) bool {	if path == "" {		return false	}	fileInfo, err := os.Stat(path)	if err != nil {		logger.Debug("nginx.isValidRegularFile: failed to stat file", "path", path, "error", err)		return false	}	// Check if it's a regular file (not a directory or special file)	if !fileInfo.Mode().IsRegular() {		logger.Debug("nginx.isValidRegularFile: path is not a regular file", "path", path, "mode", fileInfo.Mode())		return false	}	return true}// isCommentedLine checks if a line is commented (starts with #)func isCommentedLine(line string) bool {	trimmed := strings.TrimSpace(line)	return strings.HasPrefix(trimmed, "#")}// getAccessLogPathFromNginxT extracts the first access_log path from nginx -T outputfunc getAccessLogPathFromNginxT() string {	output := getNginxT()	if output == "" {		logger.Error("nginx.getAccessLogPathFromNginxT: nginx -T output is empty")		return ""	}	lines := strings.Split(output, "\n")	for _, line := range lines {		// Skip commented lines		if isCommentedLine(line) {			continue		}		matches := accessLogRegex.FindStringSubmatch(line)		if len(matches) >= 2 {			logPath := matches[1]			// Skip 'off' directive			if logPath == "off" {				continue			}			// Handle relative paths			if !filepath.IsAbs(logPath) {				logPath = filepath.Join(GetPrefix(), logPath)			}			resolvedPath := resolvePath(logPath)			// Validate that the path is a regular file			if !isValidRegularFile(resolvedPath) {				logger.Warn("nginx.getAccessLogPathFromNginxT: path is not a valid regular file", "path", resolvedPath)				continue			}			return resolvedPath		}	}	logger.Error("nginx.getAccessLogPathFromNginxT: no valid access_log file found")	return ""}// getErrorLogPathFromNginxT extracts the first error_log path from nginx -T outputfunc getErrorLogPathFromNginxT() string {	output := getNginxT()	if output == "" {		logger.Error("nginx.getErrorLogPathFromNginxT: nginx -T output is empty")		return ""	}	lines := strings.Split(output, "\n")	for _, line := range lines {		// Skip commented lines		if isCommentedLine(line) {			continue		}		matches := errorLogRegex.FindStringSubmatch(line)		if len(matches) >= 2 {			logPath := matches[1]			// Handle relative paths			if !filepath.IsAbs(logPath) {				logPath = filepath.Join(GetPrefix(), logPath)			}			resolvedPath := resolvePath(logPath)			// Validate that the path is a regular file			if !isValidRegularFile(resolvedPath) {				logger.Warn("nginx.getErrorLogPathFromNginxT: path is not a valid regular file", "path", resolvedPath)				continue			}			return resolvedPath		}	}	logger.Error("nginx.getErrorLogPathFromNginxT: no valid error_log file found")	return ""}
 |