From 3767fc6cf8d9d27af649b9787574df2db56fd268 Mon Sep 17 00:00:00 2001 From: ppom <> Date: Wed, 4 Oct 2023 12:00:00 +0200 Subject: [PATCH] More complete reponse for `flush` --- app/client.go | 51 +++++++++++++++++++++++++++++++++++----------- app/daemon.go | 8 ++++---- app/pipe.go | 56 +++++++++++++++------------------------------------ app/types.go | 4 ++-- 4 files changed, 61 insertions(+), 58 deletions(-) diff --git a/app/client.go b/app/client.go index 53a3801..de1b929 100644 --- a/app/client.go +++ b/app/client.go @@ -23,10 +23,8 @@ type Request struct { } type Response struct { - Err error - ClientStatus ClientStatus - FlushedMatches map[string]map[string]int - FlushedActions map[string]map[string]map[string]int + Err error + ClientStatus ClientStatus } func SendAndRetrieve(data Request) Response { @@ -50,20 +48,23 @@ func SendAndRetrieve(data Request) Response { } type PatternStatus struct { - Matches int `yaml:"matches_since_last_trigger"` - Actions map[string][]string `yaml:"pending_actions"` + Matches int `yaml:"matches"` + Actions map[string][]string `yaml:"actions"` } type MapPatternStatus map[string]*PatternStatus +type MapPatternStatusFlush MapPatternStatus + type ClientStatus map[string]map[string]MapPatternStatus +type ClientStatusFlush ClientStatus // This block is made to hide pending_actions when empty // and matches_since_last_trigger when zero type FullPatternStatus PatternStatus type MatchesStatus struct { - Matches int `yaml:"matches_since_last_trigger"` + Matches int `yaml:"matches"` } type ActionsStatus struct { - Actions map[string][]string `yaml:"pending_actions"` + Actions map[string][]string `yaml:"actions"` } func (mps MapPatternStatus) MarshalYAML() (interface{}, error) { @@ -84,6 +85,35 @@ func (mps MapPatternStatus) MarshalYAML() (interface{}, error) { return ret, nil } +func (mps MapPatternStatusFlush) MarshalYAML() (interface{}, error) { + var ret interface{} + for _, v := range mps { + if v.Matches == 0 { + if len(v.Actions) != 0 { + ret = ActionsStatus{v.Actions} + } + } else { + if len(v.Actions) != 0 { + ret = v + } else { + ret = MatchesStatus{v.Matches} + } + } + } + return ret, nil +} + +func (csf ClientStatusFlush) MarshalYAML() (interface{}, error) { + ret := make(map[string]map[string]MapPatternStatusFlush) + for k, v := range csf { + ret[k] = make(map[string]MapPatternStatusFlush) + for kk, vv := range v { + ret[k][kk] = MapPatternStatusFlush(vv) + } + } + return ret, nil +} + // end block func usage(err string) { @@ -112,10 +142,7 @@ func ClientFlush(pattern, streamfilter string) { log.Fatalln("Received error from daemon:", response.Err) os.Exit(1) } - text, err := yaml.Marshal(struct { - Matches map[string]map[string]int - Actions map[string]map[string]map[string]int - }{response.FlushedMatches, response.FlushedActions}) + text, err := yaml.Marshal(ClientStatusFlush(response.ClientStatus)) if err != nil { log.Fatalln("Failed to convert daemon binary response to text format:", err) } diff --git a/app/daemon.go b/app/daemon.go index 37e2260..15f6905 100644 --- a/app/daemon.go +++ b/app/daemon.go @@ -127,14 +127,14 @@ func ActionsManager() { actionsLock.Unlock() action.exec(pattern) case fo := <-flushToActionsC: - ret := make(map[*Action]int) + ret := make(ActionsMap) actionsLock.Lock() for pa := range actions { if pa.p == fo.p { for range actions[pa] { pa.a.exec(pa.p) } - ret[pa.a] = len(actions[pa]) + ret[pa] = actions[pa] delete(actions, pa) } } @@ -188,12 +188,12 @@ func MatchesManager() { } func matchesManagerHandleFlush(fo FlushMatchOrder) { - ret := make(map[*Filter]int) + ret := make(MatchesMap) matchesLock.Lock() for pf := range matches { if fo.p == pf.p { if fo.ret != nil { - ret[pf.f] = len(matches[pf]) + ret[pf] = matches[pf] } delete(matches, pf) } diff --git a/app/pipe.go b/app/pipe.go index 6c2eac5..3345f09 100644 --- a/app/pipe.go +++ b/app/pipe.go @@ -6,15 +6,16 @@ import ( "net" "os" "path" + "sync" "time" ) -func genClientStatus() ClientStatus { +func genClientStatus(local_actions ActionsMap, local_matches MatchesMap, local_actionsLock, local_matchesLock *sync.Mutex) ClientStatus { cs := make(ClientStatus) - matchesLock.Lock() + local_matchesLock.Lock() // Painful data manipulation - for pf, times := range matches { + for pf, times := range local_matches { pattern, filter := pf.p, pf.f if cs[filter.stream.name] == nil { cs[filter.stream.name] = make(map[string]MapPatternStatus) @@ -25,11 +26,11 @@ func genClientStatus() ClientStatus { cs[filter.stream.name][filter.name][pattern] = &PatternStatus{len(times), nil} } - matchesLock.Unlock() - actionsLock.Lock() + local_matchesLock.Unlock() + local_actionsLock.Lock() // Painful data manipulation - for pa := range actions { + for pa, times := range local_actions { pattern, action := pa.p, pa.a if cs[action.filter.stream.name] == nil { cs[action.filter.stream.name] = make(map[string]MapPatternStatus) @@ -44,39 +45,14 @@ func genClientStatus() ClientStatus { if ps.Actions == nil { ps.Actions = make(map[string][]string) } - for then := range actions[pa] { + for then := range times { ps.Actions[action.name] = append(ps.Actions[action.name], then.Format(time.DateTime)) } } - actionsLock.Unlock() + local_actionsLock.Unlock() return cs } -func genFlushedMatches(og map[*Filter]int) map[string]map[string]int { - ret := make(map[string]map[string]int) - for filter, nb := range og { - if ret[filter.stream.name] == nil { - ret[filter.stream.name] = make(map[string]int) - } - ret[filter.stream.name][filter.name] = nb - } - return ret -} - -func genFlushedActions(og map[*Action]int) map[string]map[string]map[string]int { - ret := make(map[string]map[string]map[string]int) - for action, nb := range og { - if ret[action.filter.stream.name] == nil { - ret[action.filter.stream.name] = make(map[string]map[string]int) - } - if ret[action.filter.stream.name][action.filter.name] == nil { - ret[action.filter.stream.name][action.filter.name] = make(map[string]int) - } - ret[action.filter.stream.name][action.filter.name][action.name] = nb - } - return ret -} - func createOpenSocket() net.Listener { err := os.MkdirAll(path.Dir(*SocketPath), 0755) if err != nil { @@ -120,17 +96,17 @@ func SocketManager(streams map[string]*Stream) { switch request.Request { case Show: - response.ClientStatus = genClientStatus() + response.ClientStatus = genClientStatus(actions, matches, &actionsLock, &matchesLock) case Flush: le := LogEntry{time.Now(), request.Pattern, "", "", false} - matches := FlushMatchOrder{request.Pattern, make(chan map[*Filter]int)} - actions := FlushActionOrder{request.Pattern, make(chan map[*Action]int)} - flushToMatchesC <- matches - flushToActionsC <- actions + matchesC := FlushMatchOrder{request.Pattern, make(chan MatchesMap)} + actionsC := FlushActionOrder{request.Pattern, make(chan ActionsMap)} + flushToMatchesC <- matchesC + flushToActionsC <- actionsC flushToDatabaseC <- le - response.FlushedMatches = genFlushedMatches(<-matches.ret) - response.FlushedActions = genFlushedActions(<-actions.ret) + var lock sync.Mutex + response.ClientStatus = genClientStatus(<-actionsC.ret, <-matchesC.ret, &lock, &lock) default: log.Println("ERROR Invalid Message from cli: unrecognised Request type") return diff --git a/app/types.go b/app/types.go index 219ca0b..cae09c0 100644 --- a/app/types.go +++ b/app/types.go @@ -102,9 +102,9 @@ type PAT struct { type FlushMatchOrder struct { p string - ret chan map[*Filter]int + ret chan MatchesMap } type FlushActionOrder struct { p string - ret chan map[*Action]int + ret chan ActionsMap }