From 6e21bfc119cbab5ad88f7573d6041d6aeb3695f6 Mon Sep 17 00:00:00 2001 From: jayson Date: Wed, 19 Jun 2024 16:24:25 +0800 Subject: [PATCH 1/3] container logs should be escaped when printed --- internal/dao/log_item_test.go | 15 +++++++++++++-- internal/dao/pod.go | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/internal/dao/log_item_test.go b/internal/dao/log_item_test.go index 711db12384..f805f96fc8 100644 --- a/internal/dao/log_item_test.go +++ b/internal/dao/log_item_test.go @@ -10,6 +10,7 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" + "github.com/derailed/tview" "github.com/stretchr/testify/assert" ) @@ -76,14 +77,24 @@ func TestLogItemRender(t *testing.T) { ShowTimestamp: false, }, log: fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", "2021-10-28T13:06:37Z [INFO] [blah-blah] Testing 1,2,3..."), - e: "[yellow::]fred[-::] 2021-10-28T13:06:37Z [INFO] [blah-blah] Testing 1,2,3...\n", + e: "[yellow::]fred[-::] 2021-10-28T13:06:37Z [INFO[] [blah-blah[] Testing 1,2,3...\n", + }, + "escape": { + opts: dao.LogOptions{ + Path: "blee/fred", + Container: "", + SingleContainer: false, + ShowTimestamp: false, + }, + log: fmt.Sprintf("%s %s\n", "2018-12-14T10:36:43.326972-07:00", `{"foo":["bar"]} Server listening on: [::]:5000`), + e: `[yellow::]fred[-::] {"foo":["bar"[]} Server listening on: [::[]:5000` + "\n", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - i := dao.NewLogItem([]byte(u.log)) + i := dao.NewLogItem([]byte(tview.Escape(u.log))) _, n := client.Namespaced(u.opts.Path) i.Pod, i.Container = n, u.opts.Container diff --git a/internal/dao/pod.go b/internal/dao/pod.go index c836137dd6..cf8e8e9fc3 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -16,6 +16,7 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/watch" + "github.com/derailed/tview" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -380,8 +381,8 @@ func readLogs(ctx context.Context, wg *sync.WaitGroup, stream io.ReadCloser, out r := bufio.NewReader(stream) for { var item *LogItem - if bytes, err := r.ReadBytes('\n'); err == nil { - item = opts.ToLogItem(bytes) + if line, err := r.ReadString('\n'); err == nil { + item = opts.ToLogItem([]byte(tview.Escape(line))) } else { if errors.Is(err, io.EOF) { e := fmt.Errorf("Stream closed %w for %s", err, opts.Info()) From f141e2348c42849b56e67c6a79dec6a8d5fa9d58 Mon Sep 17 00:00:00 2001 From: jayson wang Date: Fri, 16 Aug 2024 09:05:32 +0800 Subject: [PATCH 2/3] reduce additional memory allocation --- internal/dao/pod.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/dao/pod.go b/internal/dao/pod.go index cf8e8e9fc3..dc2a4a6054 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "regexp" "sync" "time" @@ -16,7 +17,6 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/watch" - "github.com/derailed/tview" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,6 +35,8 @@ var ( _ Controller = (*Pod)(nil) _ ContainsPodSpec = (*Pod)(nil) _ ImageLister = (*Pod)(nil) + + nonEscapePattern = regexp.MustCompile(`(\[[a-zA-Z0-9_,;: \-\."#]+\[*)\]`) ) const ( @@ -381,8 +383,8 @@ func readLogs(ctx context.Context, wg *sync.WaitGroup, stream io.ReadCloser, out r := bufio.NewReader(stream) for { var item *LogItem - if line, err := r.ReadString('\n'); err == nil { - item = opts.ToLogItem([]byte(tview.Escape(line))) + if line, err := r.ReadBytes('\n'); err == nil { + item = opts.ToLogItem(Escape(line)) } else { if errors.Is(err, io.EOF) { e := fmt.Errorf("Stream closed %w for %s", err, opts.Info()) @@ -519,3 +521,9 @@ func (p *Pod) Sanitize(ctx context.Context, ns string) (int, error) { return count, nil } + +// Escape escapes the given bytes such that color and/or region tags are not +// recognized and substituted by the print functions of tview package. +func Escape(text []byte) []byte { + return nonEscapePattern.ReplaceAll(text, []byte("$1[]")) +} From 6ce7e7668898f22914232665c8995ecf82ea733f Mon Sep 17 00:00:00 2001 From: jayson wang Date: Sat, 17 Aug 2024 00:32:42 +0800 Subject: [PATCH 3/3] upgrade deps and move escape to tview --- go.mod | 14 +++++++------- go.sum | 29 +++++++++++++++-------------- internal/dao/pod.go | 14 +++----------- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 40899d3cc2..dd2709afbb 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/derailed/popeye v0.11.3 github.com/derailed/tcell/v2 v2.3.1-rc.3 - github.com/derailed/tview v0.8.3 + github.com/derailed/tview v0.8.4 github.com/fatih/color v1.16.0 github.com/fsnotify/fsnotify v1.7.0 github.com/fvbommel/sortorder v1.1.0 github.com/go-errors/errors v1.4.2 github.com/mattn/go-colorable v0.1.13 - github.com/mattn/go-runewidth v0.0.15 + github.com/mattn/go-runewidth v0.0.16 github.com/olekukonko/tablewriter v0.0.5 github.com/petergtz/pegomock v2.9.0+incompatible github.com/rakyll/hey v0.1.4 @@ -26,7 +26,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/text v0.16.0 + golang.org/x/text v0.17.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 @@ -122,7 +122,7 @@ require ( github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gdamore/encoding v1.0.0 // indirect + github.com/gdamore/encoding v1.0.1 // indirect github.com/github/go-spdx/v2 v2.2.0 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/glebarez/sqlite v1.11.0 // indirect @@ -298,9 +298,9 @@ require ( golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index dbcabd5965..ae1f4e4f05 100644 --- a/go.sum +++ b/go.sum @@ -393,8 +393,8 @@ github.com/derailed/popeye v0.11.3 h1:gQUp6zuSIRDBdyLS1Ln0nFs8FbQ+KGE+iQxe0w4Ug8 github.com/derailed/popeye v0.11.3/go.mod h1:HygqX7A8BwidorJjJUnWDZ5AvbxHIU7uRwXgOtn9GwY= github.com/derailed/tcell/v2 v2.3.1-rc.3 h1:9s1fmyRcSPRlwr/C9tcpJKCujbrtmPpST6dcMUD2piY= github.com/derailed/tcell/v2 v2.3.1-rc.3/go.mod h1:nf68BEL8fjmXQHJT3xZjoZFs2uXOzyJcNAQqGUEMrFY= -github.com/derailed/tview v0.8.3 h1:jhN7LW7pfCWf7Z6VC5Dpi/1usavOBZxz2mY90//TMsU= -github.com/derailed/tview v0.8.3/go.mod h1:q+odnnhO6QDPpBT+0dqaWj+X+uoJ6MJehXj9shgP+Cw= +github.com/derailed/tview v0.8.4 h1:V/ifCGCYRnYWTrYqFhqZZ/UTD0GASlSs+MD9mpYc/9A= +github.com/derailed/tview v0.8.4/go.mod h1:q+odnnhO6QDPpBT+0dqaWj+X+uoJ6MJehXj9shgP+Cw= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= @@ -480,8 +480,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= +github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/github/go-spdx/v2 v2.2.0 h1:yBBLMasHA70Ujd35OpL/OjJOWWVNXcJGbars0GinGRI= github.com/github/go-spdx/v2 v2.2.0/go.mod h1:hMCrsFgT0QnCwn7G8gxy/MxMpy67WgZrwFeISTn0o6w= @@ -863,8 +863,8 @@ github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1: github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -1408,8 +1408,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1507,8 +1507,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1516,8 +1516,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1531,8 +1531,9 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/internal/dao/pod.go b/internal/dao/pod.go index dc2a4a6054..6e5919381a 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "regexp" "sync" "time" @@ -17,6 +16,7 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/watch" + "github.com/derailed/tview" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,8 +35,6 @@ var ( _ Controller = (*Pod)(nil) _ ContainsPodSpec = (*Pod)(nil) _ ImageLister = (*Pod)(nil) - - nonEscapePattern = regexp.MustCompile(`(\[[a-zA-Z0-9_,;: \-\."#]+\[*)\]`) ) const ( @@ -383,8 +381,8 @@ func readLogs(ctx context.Context, wg *sync.WaitGroup, stream io.ReadCloser, out r := bufio.NewReader(stream) for { var item *LogItem - if line, err := r.ReadBytes('\n'); err == nil { - item = opts.ToLogItem(Escape(line)) + if bytes, err := r.ReadBytes('\n'); err == nil { + item = opts.ToLogItem(tview.EscapeBytes(bytes)) } else { if errors.Is(err, io.EOF) { e := fmt.Errorf("Stream closed %w for %s", err, opts.Info()) @@ -521,9 +519,3 @@ func (p *Pod) Sanitize(ctx context.Context, ns string) (int, error) { return count, nil } - -// Escape escapes the given bytes such that color and/or region tags are not -// recognized and substituted by the print functions of tview package. -func Escape(text []byte) []byte { - return nonEscapePattern.ReplaceAll(text, []byte("$1[]")) -}