Skip to content

Commit d909648

Browse files
committed
dont watch log files
1 parent 2f4ce40 commit d909648

File tree

14 files changed

+140
-40
lines changed

14 files changed

+140
-40
lines changed

api/grpc/mpi/v1/command.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/grpc/mpi/v1/common.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/grpc/mpi/v1/files.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/config/config.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func ResolveConfig() (*Config, error) {
110110

111111
slog.Debug("Agent config", "config", config)
112112
slog.Info("Enabled features", "features", config.Features)
113+
slog.Info("Excluded files from file monitoring", "exclude_files", config.Watchers.FileWatcher.ExcludeFiles)
113114

114115
return config, nil
115116
}
@@ -154,7 +155,7 @@ func registerFlags() {
154155
fs.StringSlice(
155156
NginxExcludeLogsKey, []string{},
156157
"A comma-separated list of one or more NGINX log paths that you want to exclude from metrics "+
157-
"collection or error monitoring",
158+
"collection or error monitoring. This includes absolute paths or regex patterns",
158159
)
159160

160161
fs.StringSlice(AllowedDirectoriesKey,
@@ -179,6 +180,12 @@ func registerFlags() {
179180
"How often the NGINX Agent will check for file changes.",
180181
)
181182

183+
fs.StringSlice(
184+
NginxExcludeFilesKey, DefaultExcludedFiles(),
185+
"A comma-separated list of one or more file paths that you want to exclude from file monitoring. "+
186+
"This includes absolute paths or regex patterns",
187+
)
188+
182189
fs.StringSlice(
183190
FeaturesKey,
184191
DefaultFeatures(),
@@ -881,6 +888,7 @@ func resolveWatchers() *Watchers {
881888
},
882889
FileWatcher: FileWatcher{
883890
MonitoringFrequency: DefFileWatcherMonitoringFrequency,
891+
ExcludeFiles: viperInstance.GetStringSlice(NginxExcludeFilesKey),
884892
},
885893
}
886894
}

internal/config/config_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ func TestResolveConfig(t *testing.T) {
4444
"/etc/nginx", "/usr/local/etc/nginx", "/var/run/nginx",
4545
"/usr/share/nginx/modules", "/var/log/nginx",
4646
}
47+
48+
excludeFiles := []string{
49+
"\\.*log$",
50+
}
51+
4752
viperInstance = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter))
4853
err := loadPropertiesFromFile("./testdata/nginx-agent.conf")
4954
require.NoError(t, err)
@@ -64,8 +69,9 @@ func TestResolveConfig(t *testing.T) {
6469

6570
assert.Equal(t, 30*time.Second, actual.DataPlaneConfig.Nginx.ReloadMonitoringPeriod)
6671
assert.False(t, actual.DataPlaneConfig.Nginx.TreatWarningsAsErrors)
67-
assert.Equal(t, []string{"/var/log/nginx/error.log", "/var/log/nginx/access.log"},
72+
assert.Equal(t, []string{"/var/log/nginx/error.log", "^/var/log/nginx/.*.log$"},
6873
actual.DataPlaneConfig.Nginx.ExcludeLogs)
74+
assert.Equal(t, excludeFiles, actual.Watchers.FileWatcher.ExcludeFiles)
6975

7076
require.NotNil(t, actual.Collector)
7177
assert.Equal(t, "/etc/nginx-agent/nginx-agent-otelcol.yaml", actual.Collector.ConfigPath)

internal/config/defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ func DefaultAllowedDirectories() []string {
9494
}
9595
}
9696

97+
func DefaultExcludedFiles() []string {
98+
return []string{
99+
"^.*(\\.log|.swx|~|.swp)$",
100+
}
101+
}
102+
97103
func DefaultLabels() map[string]string {
98104
return make(map[string]string)
99105
}

internal/config/flags.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const (
2222
FeaturesKey = "features"
2323
InstanceWatcherMonitoringFrequencyKey = "watchers_instance_watcher_monitoring_frequency"
2424
InstanceHealthWatcherMonitoringFrequencyKey = "watchers_instance_health_watcher_monitoring_frequency"
25-
FileWatcherMonitoringFrequencyKey = "watchers_file_watcher_monitoring_frequency"
25+
FileWatcherKey = "watchers_file_watcher"
2626
)
2727

2828
var (
@@ -96,6 +96,8 @@ var (
9696
NginxReloadMonitoringPeriodKey = pre(DataPlaneConfigRootKey, "nginx") + "reload_monitoring_period"
9797
NginxTreatWarningsAsErrorsKey = pre(DataPlaneConfigRootKey, "nginx") + "treat_warnings_as_errors"
9898
NginxExcludeLogsKey = pre(DataPlaneConfigRootKey, "nginx") + "exclude_logs"
99+
FileWatcherMonitoringFrequencyKey = pre(FileWatcherKey) + "monitoring_frequency"
100+
NginxExcludeFilesKey = pre(FileWatcherKey) + "exclude_files"
99101
)
100102

101103
func pre(prefixes ...string) string {

internal/config/testdata/nginx-agent.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ watchers:
99
monitoring_frequency: 5s
1010
file_watcher:
1111
monitoring_frequency: 5s
12+
exclude_files:
13+
- \.*log$
1214

1315
data_plane_config:
1416
nginx:
1517
reload_monitoring_period: 30s
1618
treat_warnings_as_errors: false
1719
exclude_logs:
1820
- /var/log/nginx/error.log
19-
- /var/log/nginx/access.log
21+
- ^/var/log/nginx/.*.log$
2022
client:
2123
http:
2224
timeout: 15s

internal/config/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ type (
290290
}
291291

292292
Watchers struct {
293+
FileWatcher FileWatcher `yaml:"-" mapstructure:"file_watcher"`
293294
InstanceWatcher InstanceWatcher `yaml:"-" mapstructure:"instance_watcher"`
294295
InstanceHealthWatcher InstanceHealthWatcher `yaml:"-" mapstructure:"instance_health_watcher"`
295-
FileWatcher FileWatcher `yaml:"-" mapstructure:"file_watcher"`
296296
}
297297

298298
InstanceWatcher struct {
@@ -304,6 +304,7 @@ type (
304304
}
305305

306306
FileWatcher struct {
307+
ExcludeFiles []string `yaml:"-" mapstructure:"exclude_files"`
307308
MonitoringFrequency time.Duration `yaml:"-" mapstructure:"monitoring_frequency"`
308309
}
309310
)

internal/watcher/file/file_watcher_service.go

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ package file
88
import (
99
"context"
1010
"errors"
11+
"io/fs"
1112
"log/slog"
1213
"os"
1314
"path/filepath"
15+
"regexp"
1416
"strings"
1517
"sync"
1618
"sync/atomic"
@@ -110,20 +112,33 @@ func (fws *FileWatcherService) watchDirectories(ctx context.Context) {
110112

111113
slog.DebugContext(ctx, "Creating file watchers", "directory", dir)
112114

113-
err := filepath.Walk(dir, func(path string, info os.FileInfo, fileWalkErr error) error {
114-
if fileWalkErr != nil {
115-
return fileWalkErr
116-
}
117-
fws.addWatcher(ctx, path, info)
118-
119-
return nil
120-
})
115+
err := fws.walkDir(ctx, dir)
121116
if err != nil {
122117
slog.ErrorContext(ctx, "Failed to create file watchers", "directory", dir, "error", err)
123118
}
124119
}
125120
}
126121

122+
func (fws *FileWatcherService) walkDir(ctx context.Context, dir string) error {
123+
return filepath.WalkDir(dir, func(path string, d fs.DirEntry, fileWalkErr error) error {
124+
if fileWalkErr != nil {
125+
return fileWalkErr
126+
}
127+
128+
info, infoErr := d.Info()
129+
if infoErr != nil {
130+
slog.ErrorContext(ctx, "Error getting info for file", "error", infoErr)
131+
return infoErr
132+
}
133+
134+
if d.IsDir() {
135+
fws.addWatcher(ctx, path, info)
136+
}
137+
138+
return nil
139+
})
140+
}
141+
127142
func (fws *FileWatcherService) addWatcher(ctx context.Context, path string, info os.FileInfo) {
128143
if info.IsDir() && !fws.isWatching(path) {
129144
if err := fws.watcher.Add(path); err != nil {
@@ -164,7 +179,7 @@ func (fws *FileWatcherService) isWatching(name string) bool {
164179

165180
func (fws *FileWatcherService) handleEvent(ctx context.Context, event fsnotify.Event) {
166181
if fws.enabled.Load() {
167-
if isEventSkippable(event) {
182+
if fws.isEventSkippable(event) {
168183
slog.DebugContext(ctx, "Skipping FSNotify event", "event", event)
169184
return
170185
}
@@ -204,10 +219,29 @@ func (fws *FileWatcherService) checkForUpdates(ctx context.Context, ch chan<- Fi
204219
}
205220
}
206221

207-
func isEventSkippable(event fsnotify.Event) bool {
222+
func (fws *FileWatcherService) isEventSkippable(event fsnotify.Event) bool {
208223
return event == emptyEvent ||
209-
event.Name == "" ||
210-
strings.HasSuffix(event.Name, ".swp") ||
211-
strings.HasSuffix(event.Name, ".swx") ||
212-
strings.HasSuffix(event.Name, "~")
224+
event.Name == "" || isExcludedFile(event.Name, fws.agentConfig.Watchers.FileWatcher.ExcludeFiles)
225+
}
226+
227+
func isExcludedFile(path string, excludeFiles []string) bool {
228+
path = strings.ToLower(path)
229+
for _, pattern := range excludeFiles {
230+
_, compileErr := regexp.Compile(pattern)
231+
if compileErr != nil {
232+
slog.Error("Invalid path for excluding file", "file_path", pattern)
233+
continue
234+
}
235+
236+
ok, err := regexp.MatchString(pattern, path)
237+
if err != nil {
238+
slog.Error("Invalid path for excluding file", "file_path", pattern)
239+
continue
240+
} else if ok {
241+
slog.Debug("Excluding file from watcher as specified in config", "file_path", path)
242+
return true
243+
}
244+
}
245+
246+
return false
213247
}

0 commit comments

Comments
 (0)