Skip to content

Commit d0f9f1c

Browse files
committed
feat: add functions to retrieve nginx paths and enhance log cache management
1 parent 62d5b15 commit d0f9f1c

File tree

4 files changed

+448
-14
lines changed

4 files changed

+448
-14
lines changed

internal/nginx/config_args.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ func resolvePath(path string) string {
7474
return path
7575
}
7676

77+
// GetPrefix returns the prefix of the nginx executable
78+
func GetPrefix() string {
79+
out := getNginxV()
80+
r, _ := regexp.Compile(`--prefix=(\S+)`)
81+
match := r.FindStringSubmatch(out)
82+
if len(match) < 1 {
83+
logger.Error("nginx.GetPrefix len(match) < 1")
84+
return "/usr/local/nginx"
85+
}
86+
return resolvePath(match[1])
87+
}
88+
89+
// GetConfPath returns the path to the nginx configuration file
7790
func GetConfPath(dir ...string) (confPath string) {
7891
if settings.NginxSettings.ConfigDir == "" {
7992
out := getNginxV()
@@ -97,6 +110,7 @@ func GetConfPath(dir ...string) (confPath string) {
97110
return joined
98111
}
99112

113+
// GetConfEntryPath returns the path to the nginx configuration file
100114
func GetConfEntryPath() (path string) {
101115
if settings.NginxSettings.ConfigPath == "" {
102116
out := getNginxV()
@@ -114,6 +128,7 @@ func GetConfEntryPath() (path string) {
114128
return resolvePath(path)
115129
}
116130

131+
// GetPIDPath returns the path to the nginx PID file
117132
func GetPIDPath() (path string) {
118133
if settings.NginxSettings.PIDPath == "" {
119134
out := getNginxV()
@@ -131,9 +146,10 @@ func GetPIDPath() (path string) {
131146
return resolvePath(path)
132147
}
133148

149+
// GetSbinPath returns the path to the nginx executable
134150
func GetSbinPath() (path string) {
135151
out := getNginxV()
136-
r, _ := regexp.Compile("--sbin-path=(\\S+)")
152+
r, _ := regexp.Compile(`--sbin-path=(\S+)`)
137153
match := r.FindStringSubmatch(out)
138154
if len(match) < 1 {
139155
logger.Error("nginx.GetPIDPath len(match) < 1")
@@ -144,10 +160,11 @@ func GetSbinPath() (path string) {
144160
return resolvePath(path)
145161
}
146162

163+
// GetAccessLogPath returns the path to the nginx access log file
147164
func GetAccessLogPath() (path string) {
148165
if settings.NginxSettings.AccessLogPath == "" {
149166
out := getNginxV()
150-
r, _ := regexp.Compile("--http-log-path=(\\S+)")
167+
r, _ := regexp.Compile(`--http-log-path=(\S+)`)
151168
match := r.FindStringSubmatch(out)
152169
if len(match) < 1 {
153170
logger.Error("nginx.GetAccessLogPath len(match) < 1")
@@ -161,10 +178,11 @@ func GetAccessLogPath() (path string) {
161178
return resolvePath(path)
162179
}
163180

181+
// GetErrorLogPath returns the path to the nginx error log file
164182
func GetErrorLogPath() string {
165183
if settings.NginxSettings.ErrorLogPath == "" {
166184
out := getNginxV()
167-
r, _ := regexp.Compile("--error-log-path=(\\S+)")
185+
r, _ := regexp.Compile(`--error-log-path=(\S+)`)
168186
match := r.FindStringSubmatch(out)
169187
if len(match) < 1 {
170188
logger.Error("nginx.GetErrorLogPath len(match) < 1")

internal/nginx_log/log_cache.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66

77
// NginxLogCache represents a cached log entry from nginx configuration
88
type NginxLogCache struct {
9-
Path string `json:"path"` // Path to the log file
10-
Type string `json:"type"` // Type of log: "access" or "error"
11-
Name string `json:"name"` // Name of the log file
9+
Path string `json:"path"` // Path to the log file
10+
Type string `json:"type"` // Type of log: "access" or "error"
11+
Name string `json:"name"` // Name of the log file
12+
ConfigFile string `json:"config_file"` // Path to the configuration file that contains this log directive
1213
}
1314

1415
var (
@@ -17,15 +18,28 @@ var (
1718
cacheMutex sync.RWMutex
1819
)
1920

20-
// AddLogPath adds a log path to the log cache
21-
func AddLogPath(path, logType, name string) {
21+
// AddLogPath adds a log path to the log cache with the source config file
22+
func AddLogPath(path, logType, name, configFile string) {
2223
cacheMutex.Lock()
2324
defer cacheMutex.Unlock()
2425

2526
logCache[path] = &NginxLogCache{
26-
Path: path,
27-
Type: logType,
28-
Name: name,
27+
Path: path,
28+
Type: logType,
29+
Name: name,
30+
ConfigFile: configFile,
31+
}
32+
}
33+
34+
// RemoveLogPathsFromConfig removes all log paths that come from a specific config file
35+
func RemoveLogPathsFromConfig(configFile string) {
36+
cacheMutex.Lock()
37+
defer cacheMutex.Unlock()
38+
39+
for path, cache := range logCache {
40+
if cache.ConfigFile == configFile {
41+
delete(logCache, path)
42+
}
2943
}
3044
}
3145

internal/nginx_log/nginx_log.go

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"path/filepath"
77
"regexp"
8+
"strings"
89

910
"github.com/0xJacky/Nginx-UI/internal/cache"
1011
"github.com/0xJacky/Nginx-UI/internal/helper"
@@ -24,31 +25,75 @@ func init() {
2425

2526
// scanForLogDirectives scans and parses configuration files for log directives
2627
func scanForLogDirectives(configPath string, content []byte) error {
28+
// First, remove all log paths that came from this config file
29+
// This ensures that removed log directives are properly cleaned up
30+
RemoveLogPathsFromConfig(configPath)
31+
2732
// Find log directives using regex
2833
matches := logDirectiveRegex.FindAllSubmatch(content, -1)
2934

35+
prefix := nginx.GetPrefix()
3036
// Parse log paths
3137
for _, match := range matches {
3238
if len(match) >= 3 {
39+
// Check if this match is from a commented line
40+
if isCommentedMatch(content, match) {
41+
continue // Skip commented directives
42+
}
43+
3344
directiveType := string(match[1]) // "access_log" or "error_log"
3445
logPath := string(match[2]) // Path to log file
3546

47+
// Handle relative paths by joining with nginx prefix
48+
if !filepath.IsAbs(logPath) {
49+
logPath = filepath.Join(prefix, logPath)
50+
}
51+
3652
// Validate log path
37-
if IsLogPathUnderWhiteList(logPath) && isValidLogPath(logPath) {
53+
if isValidLogPath(logPath) {
3854
logType := "access"
3955
if directiveType == "error_log" {
4056
logType = "error"
4157
}
4258

43-
// Add to cache
44-
AddLogPath(logPath, logType, filepath.Base(logPath))
59+
// Add to cache with config file path
60+
AddLogPath(logPath, logType, filepath.Base(logPath), configPath)
4561
}
4662
}
4763
}
4864

4965
return nil
5066
}
5167

68+
// isCommentedMatch checks if a regex match is from a commented line
69+
func isCommentedMatch(content []byte, match [][]byte) bool {
70+
// Find the position of the match in the content
71+
matchStr := string(match[0])
72+
matchIndex := strings.Index(string(content), matchStr)
73+
if matchIndex == -1 {
74+
return false
75+
}
76+
77+
// Find the start of the line containing this match
78+
lineStart := matchIndex
79+
for lineStart > 0 && content[lineStart-1] != '\n' {
80+
lineStart--
81+
}
82+
83+
// Check if the line starts with # (possibly with leading whitespace)
84+
for i := lineStart; i < matchIndex; i++ {
85+
char := content[i]
86+
if char == '#' {
87+
return true // This is a commented line
88+
}
89+
if char != ' ' && char != '\t' {
90+
return false // Found non-whitespace before the directive, not a comment
91+
}
92+
}
93+
94+
return false
95+
}
96+
5297
// GetAllLogs returns all log paths
5398
func GetAllLogs(filters ...func(*NginxLogCache) bool) []*NginxLogCache {
5499
return GetAllLogPaths(filters...)
@@ -116,6 +161,9 @@ func IsLogPathUnderWhiteList(path string) bool {
116161
if errorLogPath != "" {
117162
logDirWhiteList = append(logDirWhiteList, filepath.Dir(errorLogPath))
118163
}
164+
if nginx.GetPrefix() != "" {
165+
logDirWhiteList = append(logDirWhiteList, nginx.GetPrefix())
166+
}
119167

120168
// No cache, check it
121169
if !ok {

0 commit comments

Comments
 (0)