diff --git a/cmd/info.go b/cmd/info.go index 8fbb01e500..52454b2fef 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -36,6 +36,7 @@ func printInfo(cmd *cobra.Command, args []string) error { printTuple(fmat, "Plugins", config.AppPluginsFile, color.Cyan) printTuple(fmat, "Hotkeys", config.AppHotKeysFile, color.Cyan) printTuple(fmat, "Aliases", config.AppAliasesFile, color.Cyan) + printTuple(fmat, "Filters", config.AppFilterFile, color.Cyan) printTuple(fmat, "Skins", config.AppSkinsDir, color.Cyan) printTuple(fmat, "Context Configs", config.AppContextsDir, color.Cyan) printTuple(fmat, "Logs", config.AppLogFile, color.Cyan) diff --git a/internal/config/files.go b/internal/config/files.go index 2b246d5172..5f3b3c050f 100644 --- a/internal/config/files.go +++ b/internal/config/files.go @@ -80,6 +80,9 @@ var ( // AppHotKeysFile tracks hotkeys config file. AppHotKeysFile string + + // AppFilterFile tracks filter config file. + AppFilterFile string ) // InitLogLoc initializes K9s logs location. @@ -146,7 +149,7 @@ func initK9sEnvLocs() error { AppAliasesFile = filepath.Join(AppConfigDir, "aliases.yaml") AppPluginsFile = filepath.Join(AppConfigDir, "plugins.yaml") AppViewsFile = filepath.Join(AppConfigDir, "views.yaml") - + AppFilterFile = filepath.Join(AppConfigDir, "filters.yaml") return nil } @@ -167,6 +170,7 @@ func initXDGLocs() error { AppAliasesFile = filepath.Join(AppConfigDir, "aliases.yaml") AppPluginsFile = filepath.Join(AppConfigDir, "plugins.yaml") AppViewsFile = filepath.Join(AppConfigDir, "views.yaml") + AppFilterFile = filepath.Join(AppConfigDir, "filters.yaml") AppSkinsDir = filepath.Join(AppConfigDir, "skins") if err := data.EnsureFullPath(AppSkinsDir, data.DefaultDirMod); err != nil { diff --git a/internal/model/log.go b/internal/model/log.go index d194fcf017..812c8fb534 100644 --- a/internal/model/log.go +++ b/internal/model/log.go @@ -6,15 +6,19 @@ package model import ( "context" "fmt" + "os" "sync" "time" + "strings" + "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/color" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/dao" "github.com/rs/zerolog/log" + "gopkg.in/yaml.v2" ) // LogsListener represents a log model listener. @@ -38,6 +42,11 @@ type LogsListener interface { LogCanceled() } +// FilterConfig represents the structure of the filter.yaml file +type FilterConfig struct { + Filters map[string]string `yaml:"filters"` +} + // Log represents a resource logger. type Log struct { factory dao.Factory @@ -50,16 +59,19 @@ type Log struct { filter string lastSent int flushTimeout time.Duration + filterConfig FilterConfig } // NewLog returns a new model. func NewLog(gvr client.GVR, opts *dao.LogOptions, flushTimeout time.Duration) *Log { - return &Log{ + l := &Log{ gvr: gvr, logOptions: opts, lines: dao.NewLogItems(), flushTimeout: flushTimeout, } + l.loadFilterConfig() + return l } func (l *Log) GVR() client.GVR { @@ -202,14 +214,27 @@ func (l *Log) ClearFilter() { l.fireLogChanged(ll) } -// Filter filters the model using either fuzzy or regexp. +// GetFilter returns the current filter. +func (l *Log) GetFilter() string { + return l.filter +} + +// Filter filters the model using either fuzzy, regexp, or predefined filters. func (l *Log) Filter(q string) { l.mx.Lock() - { + if !strings.HasPrefix(q, "@") { l.filter = q + } else { + customFilter, ok := l.filterConfig.Filters[q[1:]] + if !ok { + log.Debug().Msgf("Failed to find custom filter for: %s", q) + l.filter = q + } else { + log.Debug().Msgf("Using custom filter: %s", customFilter) + l.filter = customFilter + } } l.mx.Unlock() - l.fireLogCleared() l.fireLogBuffChanged(0) } @@ -428,3 +453,16 @@ func (l *Log) fireLogCleared() { lis.LogCleared() } } + +// loadFilterConfig loads the filter configuration from filters.yaml +func (l *Log) loadFilterConfig() { + data, err := os.ReadFile(config.AppFilterFile) + if err != nil { + log.Error().Err(err).Msg("Failed to read filter config") + return + } + + if err := yaml.Unmarshal(data, &l.filterConfig); err != nil { + log.Error().Err(err).Msg("Failed to parse filter config") + } +} diff --git a/internal/view/log.go b/internal/view/log.go index be01ed5a5d..9a7053fc39 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -321,9 +321,9 @@ func (l *Log) updateTitle() { title += ui.SkinTitle(fmt.Sprintf(logCoFmt, path, co, since), l.app.Styles.Frame()) } - buff := l.logs.cmdBuff.GetText() - if buff != "" { - title += ui.SkinTitle(fmt.Sprintf(ui.SearchFmt, buff), l.app.Styles.Frame()) + filter := l.model.GetFilter() + if filter != "" { + title += ui.SkinTitle(fmt.Sprintf(ui.SearchFmt, filter), l.app.Styles.Frame()) } l.SetTitle(title) }