From 54c5642879eea304ecedadc9a615e91de070a3ef Mon Sep 17 00:00:00 2001 From: slayer321 Date: Tue, 12 Apr 2022 19:05:06 +0530 Subject: [PATCH] add limit flag Signed-off-by: slayer321 --- cmd/log.go | 1 + go.mod | 5 - go.sum | 10 -- log/log.go | 19 ++- log/logClient.go | 369 ++++++++++++++++++++++++++--------------------- 5 files changed, 223 insertions(+), 181 deletions(-) diff --git a/cmd/log.go b/cmd/log.go index d690cdce..8b71ea94 100644 --- a/cmd/log.go +++ b/cmd/log.go @@ -39,4 +39,5 @@ func init() { logCmd.Flags().StringVar(&logOptions.PodName, "pod", "", "name of the pod ") logCmd.Flags().StringVar(&logOptions.Resource, "resource", "", "command used by the user") logCmd.Flags().StringVar(&logOptions.Source, "source", "", "binary used by the system ") + logCmd.Flags().Uint32Var(&logOptions.Limit, "limit", 0, "number of logs you want to see") } diff --git a/go.mod b/go.mod index afd46eb1..c050d117 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,6 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/DATA-DOG/go-sqlmock v1.5.0 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/StackExchange/wmi v1.2.1 // indirect @@ -51,7 +50,6 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/confluentinc/confluent-kafka-go v1.6.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect @@ -69,7 +67,6 @@ require ( github.com/go-openapi/strfmt v0.21.0 // indirect github.com/go-openapi/swag v0.19.15 // indirect github.com/go-openapi/validate v0.20.3 // indirect - github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.1.0 // indirect @@ -115,7 +112,6 @@ require ( github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect - github.com/robfig/cron v1.2.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil/v3 v3.21.10 // indirect @@ -143,7 +139,6 @@ require ( google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.64.0 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.30.0 // indirect diff --git a/go.sum b/go.sum index 693604cf..8cb6d28f 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,6 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -122,8 +120,6 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/accuknox/auto-policy-discovery/src v0.0.0-20220407062502-7a17738e4ebc h1:bmbqlL+2Nu4wnh53a1jq1hyW7KhjSXl3PqcbKtTeCeo= -github.com/accuknox/auto-policy-discovery/src v0.0.0-20220407062502-7a17738e4ebc/go.mod h1:PjyjUUBKD3cfU4a2FlUJfH3b+coUvOS8MovbZtf6xSk= github.com/accuknox/auto-policy-discovery/src v0.0.0-20220412023742-5df1489d264b h1:r4Bw2IznyBivFgu0qrkls3vn+CowjXqtWagxp3qAHk4= github.com/accuknox/auto-policy-discovery/src v0.0.0-20220412023742-5df1489d264b/go.mod h1:PjyjUUBKD3cfU4a2FlUJfH3b+coUvOS8MovbZtf6xSk= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= @@ -233,8 +229,6 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/confluentinc/confluent-kafka-go v1.6.1 h1:YxM/UtMQ2vgJX2gIgeJFUD0ANQYTEvfo4Cs4qKUlmGE= -github.com/confluentinc/confluent-kafka-go v1.6.1/go.mod h1:u2zNLny2xq+5rWeTQjFHbDzzNuba4P1vo31r9r4uAdg= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -556,7 +550,6 @@ github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw= github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= @@ -1120,8 +1113,6 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1929,7 +1920,6 @@ gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.64.0 h1:Mj2zXEXcNb5joEiSA0zc3HZpTst/iyjNiR4CN8tDzOg= gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= diff --git a/log/log.go b/log/log.go index a7916195..8fe2f288 100644 --- a/log/log.go +++ b/log/log.go @@ -40,6 +40,7 @@ type Options struct { PodName string Source string Resource string + Limit uint32 } // StopChan Channel @@ -120,7 +121,7 @@ func StartObserver(o Options) error { } // create a client - logClient := NewClient(gRPC, o.MsgPath, o.LogPath, o.LogFilter) + logClient := NewClient(gRPC, o.MsgPath, o.LogPath, o.LogFilter, o.Limit) if logClient == nil { return errors.New("failed to connect to the gRPC server\nPossible troubleshooting:\n- Check if Kubearmor is running\n- Create a portforward to KubeArmor relay service using\n\t\033[1mkubectl -n kube-system port-forward service/kubearmor --address 0.0.0.0 --address :: 32767:32767\033[0m\n- Configure grpc server information using\n\t\033[1mkarmor log --grpc \033[0m") } @@ -143,6 +144,7 @@ func StartObserver(o Options) error { return err } + Limitchan = make(chan bool, 2) if o.LogPath != "none" { if o.LogFilter == "all" || o.LogFilter == "policy" { // watch alerts @@ -157,9 +159,18 @@ func StartObserver(o Options) error { } } - // listen for interrupt signals - sigChan := GetOSSigChannel() - <-sigChan + if o.Limit != 0 { + if o.LogFilter == "all" { + <-Limitchan + <-Limitchan + } else { + <-Limitchan + } + } else { + // listen for interrupt signals + sigChan := GetOSSigChannel() + <-sigChan + } close(StopChan) logClient.Running = false diff --git a/log/logClient.go b/log/logClient.go index d06b477d..ff946e70 100644 --- a/log/logClient.go +++ b/log/logClient.go @@ -18,6 +18,9 @@ import ( "google.golang.org/grpc" ) +var Limitchan chan bool +var i uint32 + // ============ // // == Common == // // ============ // @@ -64,6 +67,9 @@ type Feeder struct { // server server string + //limit + limit uint32 + // connection conn *grpc.ClientConn @@ -84,13 +90,15 @@ type Feeder struct { } // NewClient Function -func NewClient(server, msgPath, logPath, logFilter string) *Feeder { +func NewClient(server, msgPath, logPath, logFilter string, limit uint32) *Feeder { fd := &Feeder{} fd.Running = true fd.server = server + fd.limit = limit + conn, err := grpc.Dial(fd.server, grpc.WithInsecure()) if err != nil { return nil @@ -202,124 +210,143 @@ func regexMatcher(filter *regexp.Regexp, res string) bool { return true } -// WatchAlerts Function -func (fd *Feeder) WatchAlerts(o Options) error { - fd.WgClient.Add(1) - defer fd.WgClient.Done() - - for fd.Running { - res, err := fd.alertStream.Recv() - if err != nil { - fmt.Printf("Failed to receive an alert (%s)\n", err.Error()) - break +func watchAlertsHelper(res *pb.Alert, o Options) error { + if o.Namespace != "" { + match := regexMatcher(CNamespace, res.NamespaceName) + if !match { + return nil } + } - if o.Namespace != "" { - match := regexMatcher(CNamespace, res.NamespaceName) - if !match { - return nil - } + if o.LogType != "" { + match := regexMatcher(CLogtype, res.Type) + if !match { + return nil } + } - if o.LogType != "" { - match := regexMatcher(CLogtype, res.Type) - if !match { - return nil - } + if o.Operation != "" { + match := regexMatcher(COperation, res.Operation) + if !match { + return nil } + } - if o.Operation != "" { - match := regexMatcher(COperation, res.Operation) - if !match { - return nil - } + if o.ContainerName != "" { + match := regexMatcher(CContainerName, res.ContainerName) + if !match { + return nil } + } - if o.ContainerName != "" { - match := regexMatcher(CContainerName, res.ContainerName) - if !match { - return nil - } + if o.PodName != "" { + match := regexMatcher(CPodName, res.PodName) + if !match { + return nil } + } - if o.PodName != "" { - match := regexMatcher(CPodName, res.PodName) - if !match { - return nil - } + if o.Source != "" { + match := regexMatcher(CSource, res.Source) + if !match { + return nil } + } - if o.Source != "" { - match := regexMatcher(CSource, res.Source) - if !match { - return nil - } + if o.Resource != "" { + match := regexMatcher(CResource, res.Resource) + if !match { + return nil } + } - if o.Resource != "" { - match := regexMatcher(CResource, res.Resource) - if !match { - return nil - } - } + str := "" - str := "" + if o.JSON { + arr, _ := json.Marshal(res) + str = fmt.Sprintf("%s\n", string(arr)) + } else { + updatedTime := strings.Replace(res.UpdatedTime, "T", " ", -1) + updatedTime = strings.Replace(updatedTime, "Z", "", -1) - if o.JSON { - arr, _ := json.Marshal(res) - str = fmt.Sprintf("%s\n", string(arr)) - } else { - updatedTime := strings.Replace(res.UpdatedTime, "T", " ", -1) - updatedTime = strings.Replace(updatedTime, "Z", "", -1) + str = fmt.Sprintf("== Alert / %s ==\n", updatedTime) - str = fmt.Sprintf("== Alert / %s ==\n", updatedTime) + str = str + fmt.Sprintf("Cluster Name: %s\n", res.ClusterName) + str = str + fmt.Sprintf("Host Name: %s\n", res.HostName) - str = str + fmt.Sprintf("Cluster Name: %s\n", res.ClusterName) - str = str + fmt.Sprintf("Host Name: %s\n", res.HostName) + if res.NamespaceName != "" { + str = str + fmt.Sprintf("Namespace Name: %s\n", res.NamespaceName) + str = str + fmt.Sprintf("Pod Name: %s\n", res.PodName) + str = str + fmt.Sprintf("Container ID: %s\n", res.ContainerID) + str = str + fmt.Sprintf("Container Name: %s\n", res.ContainerName) + } - if res.NamespaceName != "" { - str = str + fmt.Sprintf("Namespace Name: %s\n", res.NamespaceName) - str = str + fmt.Sprintf("Pod Name: %s\n", res.PodName) - str = str + fmt.Sprintf("Container ID: %s\n", res.ContainerID) - str = str + fmt.Sprintf("Container Name: %s\n", res.ContainerName) - } + if len(res.PolicyName) > 0 { + str = str + fmt.Sprintf("Policy Name: %s\n", res.PolicyName) + } - if len(res.PolicyName) > 0 { - str = str + fmt.Sprintf("Policy Name: %s\n", res.PolicyName) - } + if len(res.Severity) > 0 { + str = str + fmt.Sprintf("Severity: %s\n", res.Severity) + } - if len(res.Severity) > 0 { - str = str + fmt.Sprintf("Severity: %s\n", res.Severity) - } + if len(res.Tags) > 0 { + str = str + fmt.Sprintf("Tags: %s\n", res.Tags) + } - if len(res.Tags) > 0 { - str = str + fmt.Sprintf("Tags: %s\n", res.Tags) - } + if len(res.Message) > 0 { + str = str + fmt.Sprintf("Message: %s\n", res.Message) + } - if len(res.Message) > 0 { - str = str + fmt.Sprintf("Message: %s\n", res.Message) - } + str = str + fmt.Sprintf("Type: %s\n", res.Type) + str = str + fmt.Sprintf("Source: %s\n", res.Source) + str = str + fmt.Sprintf("Operation: %s\n", res.Operation) + str = str + fmt.Sprintf("Resource: %s\n", res.Resource) - str = str + fmt.Sprintf("Type: %s\n", res.Type) - str = str + fmt.Sprintf("Source: %s\n", res.Source) - str = str + fmt.Sprintf("Operation: %s\n", res.Operation) - str = str + fmt.Sprintf("Resource: %s\n", res.Resource) + if len(res.Data) > 0 { + str = str + fmt.Sprintf("Data: %s\n", res.Data) + } - if len(res.Data) > 0 { - str = str + fmt.Sprintf("Data: %s\n", res.Data) - } + if len(res.Action) > 0 { + str = str + fmt.Sprintf("Action: %s\n", res.Action) + } - if len(res.Action) > 0 { - str = str + fmt.Sprintf("Action: %s\n", res.Action) + str = str + fmt.Sprintf("Result: %s\n", res.Result) + } + + if o.LogPath == "stdout" { + fmt.Printf("%s", str) + } else { + StrToFile(str, o.LogPath) + } + return nil +} + +// WatchAlerts Function +func (fd *Feeder) WatchAlerts(o Options) error { + fd.WgClient.Add(1) + defer fd.WgClient.Done() + + if o.Limit > 0 { + for i = 0; i < o.Limit; i++ { + res, err := fd.alertStream.Recv() + if err != nil { + fmt.Printf("Failed to receive an alert (%s)\n", err.Error()) + break } + _ = watchAlertsHelper(res, o) - str = str + fmt.Sprintf("Result: %s\n", res.Result) } + Limitchan <- true + + } else { + for fd.Running { + res, err := fd.alertStream.Recv() + if err != nil { + fmt.Printf("Failed to receive an alert (%s)\n", err.Error()) + break + } + _ = watchAlertsHelper(res, o) - if o.LogPath == "stdout" { - fmt.Printf("%s", str) - } else { - StrToFile(str, o.LogPath) } } @@ -328,104 +355,122 @@ func (fd *Feeder) WatchAlerts(o Options) error { return nil } -// WatchLogs Function -func (fd *Feeder) WatchLogs(o Options) error { - fd.WgClient.Add(1) - defer fd.WgClient.Done() - - for fd.Running { - res, err := fd.logStream.Recv() - if err != nil { - fmt.Printf("Failed to receive a log (%s)\n", err.Error()) - break +func WatchLogsHelper(res *pb.Log, o Options) error { + if o.Namespace != "" { + match := regexMatcher(CNamespace, res.NamespaceName) + if !match { + return nil } + } - if o.Namespace != "" { - match := regexMatcher(CNamespace, res.NamespaceName) - if !match { - return nil - } + if o.LogType != "" { + match := regexMatcher(CLogtype, res.Type) + if !match { + return nil } + } - if o.LogType != "" { - match := regexMatcher(CLogtype, res.Type) - if !match { - return nil - } + if o.Operation != "" { + match := regexMatcher(COperation, res.Operation) + if !match { + return nil } + } - if o.Operation != "" { - match := regexMatcher(COperation, res.Operation) - if !match { - return nil - } + if o.ContainerName != "" { + match := regexMatcher(CContainerName, res.ContainerName) + if !match { + return nil } + } - if o.ContainerName != "" { - match := regexMatcher(CContainerName, res.ContainerName) - if !match { - return nil - } + if o.PodName != "" { + match := regexMatcher(CPodName, res.PodName) + if !match { + return nil } + } - if o.PodName != "" { - match := regexMatcher(CPodName, res.PodName) - if !match { - return nil - } + if o.Source != "" { + match := regexMatcher(CSource, res.Source) + if !match { + return nil } + } - if o.Source != "" { - match := regexMatcher(CSource, res.Source) - if !match { - return nil - } + if o.Resource != "" { + match := regexMatcher(CResource, res.Resource) + if !match { + return nil } + } - if o.Resource != "" { - match := regexMatcher(CResource, res.Resource) - if !match { - return nil - } + str := "" + + if o.JSON { + arr, _ := json.Marshal(res) + str = fmt.Sprintf("%s\n", string(arr)) + } else { + updatedTime := strings.Replace(res.UpdatedTime, "T", " ", -1) + updatedTime = strings.Replace(updatedTime, "Z", "", -1) + + str = fmt.Sprintf("== Log / %s ==\n", updatedTime) + + str = str + fmt.Sprintf("Cluster Name: %s\n", res.ClusterName) + str = str + fmt.Sprintf("Host Name: %s\n", res.HostName) + + if res.NamespaceName != "" { + str = str + fmt.Sprintf("Namespace Name: %s\n", res.NamespaceName) + str = str + fmt.Sprintf("Pod Name: %s\n", res.PodName) + str = str + fmt.Sprintf("Container ID: %s\n", res.ContainerID) + str = str + fmt.Sprintf("Container Name: %s\n", res.ContainerName) } - str := "" + str = str + fmt.Sprintf("Type: %s\n", res.Type) + str = str + fmt.Sprintf("Source: %s\n", res.Source) + str = str + fmt.Sprintf("Operation: %s\n", res.Operation) + str = str + fmt.Sprintf("Resource: %s\n", res.Resource) - if o.JSON { - arr, _ := json.Marshal(res) - str = fmt.Sprintf("%s\n", string(arr)) - } else { - updatedTime := strings.Replace(res.UpdatedTime, "T", " ", -1) - updatedTime = strings.Replace(updatedTime, "Z", "", -1) + if len(res.Data) > 0 { + str = str + fmt.Sprintf("Data: %s\n", res.Data) + } - str = fmt.Sprintf("== Log / %s ==\n", updatedTime) + str = str + fmt.Sprintf("Result: %s\n", res.Result) + } - str = str + fmt.Sprintf("Cluster Name: %s\n", res.ClusterName) - str = str + fmt.Sprintf("Host Name: %s\n", res.HostName) + if o.LogPath == "stdout" { + fmt.Printf("%s", str) + } else { + StrToFile(str, o.LogPath) + } + return nil - if res.NamespaceName != "" { - str = str + fmt.Sprintf("Namespace Name: %s\n", res.NamespaceName) - str = str + fmt.Sprintf("Pod Name: %s\n", res.PodName) - str = str + fmt.Sprintf("Container ID: %s\n", res.ContainerID) - str = str + fmt.Sprintf("Container Name: %s\n", res.ContainerName) - } +} - str = str + fmt.Sprintf("Type: %s\n", res.Type) - str = str + fmt.Sprintf("Source: %s\n", res.Source) - str = str + fmt.Sprintf("Operation: %s\n", res.Operation) - str = str + fmt.Sprintf("Resource: %s\n", res.Resource) +// WatchLogs Function +func (fd *Feeder) WatchLogs(o Options) error { + fd.WgClient.Add(1) + defer fd.WgClient.Done() - if len(res.Data) > 0 { - str = str + fmt.Sprintf("Data: %s\n", res.Data) + if o.Limit > 0 { + for i = 0; i < o.Limit; i++ { + res, err := fd.logStream.Recv() + if err != nil { + fmt.Printf("Failed to receive an alert (%s)\n", err.Error()) + break } - - str = str + fmt.Sprintf("Result: %s\n", res.Result) + _ = WatchLogsHelper(res, o) } + Limitchan <- true + } else { + for fd.Running { + res, err := fd.logStream.Recv() + if err != nil { + fmt.Printf("Failed to receive an alert (%s)\n", err.Error()) + break + } + _ = WatchLogsHelper(res, o) - if o.LogPath == "stdout" { - fmt.Printf("%s", str) - } else { - StrToFile(str, o.LogPath) } }