diff --git a/README.md b/README.md index 41252a3afa..37af92c782 100644 --- a/README.md +++ b/README.md @@ -427,6 +427,8 @@ You can now override the context portForward default address configuration by se textWrap: false # Toggles log line timestamp info. Default false showTime: false + # Toggles whether JSON log lines should be colorized. Default false + showJSON: false # Provide shell pod customization when nodeShell feature gate is enabled! shellPod: # The shell pod image to use. diff --git a/go.mod b/go.mod index ac462d4651..a0e5bbd5a9 100644 --- a/go.mod +++ b/go.mod @@ -246,6 +246,7 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rm-hull/colorjson v0.0.0-20220923220430-b50ee91dc6f6 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 6694de0e64..b74e406280 100644 --- a/go.sum +++ b/go.sum @@ -1038,6 +1038,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rm-hull/colorjson v0.0.0-20220923220430-b50ee91dc6f6 h1:avrA8y9AJF9WtGipEvrM8I/7XoKcxEk30659rPHJlnM= +github.com/rm-hull/colorjson v0.0.0-20220923220430-b50ee91dc6f6/go.mod h1:tJTNxpJk1e15vd8WY5lsj9Tq5vjdnNz3YAbCwxYskBs= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= diff --git a/internal/config/json/schemas/k9s.json b/internal/config/json/schemas/k9s.json index e217bbec29..8f02c370c4 100644 --- a/internal/config/json/schemas/k9s.json +++ b/internal/config/json/schemas/k9s.json @@ -103,7 +103,8 @@ "buffer": {"type": "integer"}, "sinceSeconds": {"type": "integer"}, "textWrap": {"type": "boolean"}, - "showTime": {"type": "boolean"} + "showTime": {"type": "boolean"}, + "showJSON": {"type": "boolean"} } }, "thresholds": { diff --git a/internal/config/logger.go b/internal/config/logger.go index 4c6a6a1832..1b199a71fe 100644 --- a/internal/config/logger.go +++ b/internal/config/logger.go @@ -21,6 +21,7 @@ type Logger struct { SinceSeconds int64 `json:"sinceSeconds" yaml:"sinceSeconds"` TextWrap bool `json:"textWrap" yaml:"textWrap"` ShowTime bool `json:"showTime" yaml:"showTime"` + ShowJSON bool `json:"showJSON" yaml:"showJSON"` } // NewLogger returns a new instance. diff --git a/internal/config/testdata/configs/default.yaml b/internal/config/testdata/configs/default.yaml index abf8432ba4..3ea67cbfbb 100644 --- a/internal/config/testdata/configs/default.yaml +++ b/internal/config/testdata/configs/default.yaml @@ -32,6 +32,7 @@ k9s: sinceSeconds: -1 textWrap: false showTime: false + showJSON: false thresholds: cpu: critical: 90 diff --git a/internal/config/testdata/configs/expected.yaml b/internal/config/testdata/configs/expected.yaml index e85a32f160..4708f656b9 100644 --- a/internal/config/testdata/configs/expected.yaml +++ b/internal/config/testdata/configs/expected.yaml @@ -32,6 +32,7 @@ k9s: sinceSeconds: -1 textWrap: false showTime: false + showJSON: false thresholds: cpu: critical: 90 diff --git a/internal/config/testdata/configs/k9s.yaml b/internal/config/testdata/configs/k9s.yaml index 8f3546d357..b9837c7290 100644 --- a/internal/config/testdata/configs/k9s.yaml +++ b/internal/config/testdata/configs/k9s.yaml @@ -32,6 +32,7 @@ k9s: sinceSeconds: -1 textWrap: false showTime: false + showJSON: false thresholds: cpu: critical: 90 diff --git a/internal/dao/log_item.go b/internal/dao/log_item.go index ff90bbff3b..f20f2334e9 100644 --- a/internal/dao/log_item.go +++ b/internal/dao/log_item.go @@ -5,6 +5,9 @@ package dao import ( "bytes" + "encoding/json" + + "github.com/rm-hull/colorjson" ) // LogChan represents a channel for logs. @@ -67,7 +70,7 @@ func (l *LogItem) Size() int { } // Render returns a log line as string. -func (l *LogItem) Render(paint string, showTime bool, bb *bytes.Buffer) { +func (l *LogItem) Render(paint string, showTime bool, showJson bool, bb *bytes.Buffer) { index := bytes.Index(l.Bytes, []byte{' '}) if showTime && index > 0 { bb.WriteString("[gray::b]") @@ -92,9 +95,25 @@ func (l *LogItem) Render(paint string, showTime bool, bb *bytes.Buffer) { bb.WriteString("[-::] ") } - if index > 0 { - bb.Write(l.Bytes[index+1:]) - } else { - bb.Write(l.Bytes) + bb.Write(colorizeJSON(l.Bytes[index+1:], showJson)) +} + +func colorizeJSON(text []byte, showJson bool) []byte { + if !showJson { + return text + } + var obj map[string]interface{} + err := json.Unmarshal(text, &obj) + if err != nil { + return text + } + f := colorjson.NewFormatter() + f.Indent = 0 + f.ObjectSeparator = false + + s, err := f.Marshal(obj) + if err != nil { + return text } + return append(s, '\n') } diff --git a/internal/dao/log_item_test.go b/internal/dao/log_item_test.go index 711db12384..b791f54432 100644 --- a/internal/dao/log_item_test.go +++ b/internal/dao/log_item_test.go @@ -88,7 +88,7 @@ func TestLogItemRender(t *testing.T) { i.Pod, i.Container = n, u.opts.Container bb := bytes.NewBuffer(make([]byte, 0, i.Size())) - i.Render("yellow", u.opts.ShowTimestamp, bb) + i.Render("yellow", u.opts.ShowTimestamp, u.opts.ShowJSON, bb) assert.Equal(t, u.e, bb.String()) }) } @@ -103,7 +103,7 @@ func BenchmarkLogItemRenderTS(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { bb := bytes.NewBuffer(make([]byte, 0, i.Size())) - i.Render("yellow", true, bb) + i.Render("yellow", true, false, bb) } } @@ -116,6 +116,6 @@ func BenchmarkLogItemRenderNoTS(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { bb := bytes.NewBuffer(make([]byte, 0, i.Size())) - i.Render("yellow", false, bb) + i.Render("yellow", false, false, bb) } } diff --git a/internal/dao/log_items.go b/internal/dao/log_items.go index 898c0c842f..630df9e623 100644 --- a/internal/dao/log_items.go +++ b/internal/dao/log_items.go @@ -105,7 +105,7 @@ func (l *LogItems) Add(ii ...*LogItem) { } // Lines returns a collection of log lines. -func (l *LogItems) Lines(index int, showTime bool, ll [][]byte) { +func (l *LogItems) Lines(index int, showTime bool, showJson bool, ll [][]byte) { l.mx.Lock() defer l.mx.Unlock() @@ -122,20 +122,20 @@ func (l *LogItems) Lines(index int, showTime bool, ll [][]byte) { colorIndex++ } bb := bytes.NewBuffer(make([]byte, 0, item.Size())) - item.Render(color, showTime, bb) + item.Render(color, showTime, showJson, bb) ll[i] = bb.Bytes() } } // StrLines returns a collection of log lines. -func (l *LogItems) StrLines(index int, showTime bool) []string { +func (l *LogItems) StrLines(index int, showTime bool, showJson bool) []string { l.mx.Lock() defer l.mx.Unlock() ll := make([]string, len(l.items[index:])) for i, item := range l.items[index:] { bb := bytes.NewBuffer(make([]byte, 0, item.Size())) - item.Render("white", showTime, bb) + item.Render("white", showTime, showJson, bb) ll[i] = bb.String() } @@ -143,7 +143,7 @@ func (l *LogItems) StrLines(index int, showTime bool) []string { } // Render returns logs as a collection of strings. -func (l *LogItems) Render(index int, showTime bool, ll [][]byte) { +func (l *LogItems) Render(index int, showTime bool, showJson bool, ll [][]byte) { var colorIndex int for i, item := range l.items[index:] { id := item.ID() @@ -157,7 +157,7 @@ func (l *LogItems) Render(index int, showTime bool, ll [][]byte) { colorIndex++ } bb := bytes.NewBuffer(make([]byte, 0, item.Size())) - item.Render(color, showTime, bb) + item.Render(color, showTime, showJson, bb) ll[i] = bb.Bytes() } } @@ -171,15 +171,15 @@ func (l *LogItems) DumpDebug(m string) { } // Filter filters out log items based on given filter. -func (l *LogItems) Filter(index int, q string, showTime bool) ([]int, [][]int, error) { +func (l *LogItems) Filter(index int, q string, showTime bool, showJson bool) ([]int, [][]int, error) { if q == "" { return nil, nil, nil } if f, ok := internal.IsFuzzySelector(q); ok { - mm, ii := l.fuzzyFilter(index, f, showTime) + mm, ii := l.fuzzyFilter(index, f, showTime, showJson) return mm, ii, nil } - matches, indices, err := l.filterLogs(index, q, showTime) + matches, indices, err := l.filterLogs(index, q, showTime, showJson) if err != nil { return nil, nil, err } @@ -187,10 +187,10 @@ func (l *LogItems) Filter(index int, q string, showTime bool) ([]int, [][]int, e return matches, indices, nil } -func (l *LogItems) fuzzyFilter(index int, q string, showTime bool) ([]int, [][]int) { +func (l *LogItems) fuzzyFilter(index int, q string, showTime bool, showJson bool) ([]int, [][]int) { q = strings.TrimSpace(q) matches, indices := make([]int, 0, len(l.items)), make([][]int, 0, 10) - mm := fuzzy.Find(q, l.StrLines(index, showTime)) + mm := fuzzy.Find(q, l.StrLines(index, showTime, showJson)) for _, m := range mm { matches = append(matches, m.Index) indices = append(indices, m.MatchedIndexes) @@ -199,7 +199,7 @@ func (l *LogItems) fuzzyFilter(index int, q string, showTime bool) ([]int, [][]i return matches, indices } -func (l *LogItems) filterLogs(index int, q string, showTime bool) ([]int, [][]int, error) { +func (l *LogItems) filterLogs(index int, q string, showTime bool, showJson bool) ([]int, [][]int, error) { var invert bool if internal.IsInverseSelector(q) { invert = true @@ -211,7 +211,7 @@ func (l *LogItems) filterLogs(index int, q string, showTime bool) ([]int, [][]in } matches, indices := make([]int, 0, len(l.items)), make([][]int, 0, 10) ll := make([][]byte, len(l.items[index:])) - l.Lines(index, showTime, ll) + l.Lines(index, showTime, showJson, ll) for i, line := range ll { locs := rx.FindIndex(line) if locs != nil && invert { diff --git a/internal/dao/log_items_test.go b/internal/dao/log_items_test.go index 787fddfe13..5e71debe9b 100644 --- a/internal/dao/log_items_test.go +++ b/internal/dao/log_items_test.go @@ -74,7 +74,7 @@ func TestLogItemsFilter(t *testing.T) { for _, i := range ii.Items() { i.Pod, i.Container = n, u.opts.Container } - res, _, err := ii.Filter(0, u.q, false) + res, _, err := ii.Filter(0, u.q, false, false) assert.Equal(t, u.err, err) if err == nil { assert.Equal(t, u.e, res) @@ -124,7 +124,7 @@ func TestLogItemsRender(t *testing.T) { ii.Items()[0].Pod, ii.Items()[0].Container = n, u.opts.Container t.Run(k, func(t *testing.T) { res := make([][]byte, 1) - ii.Render(0, u.opts.ShowTimestamp, res) + ii.Render(0, u.opts.ShowTimestamp, u.opts.ShowJSON, res) assert.Equal(t, u.e, string(res[0])) }) } diff --git a/internal/dao/log_options.go b/internal/dao/log_options.go index edd20afb6b..c3c4cb3378 100644 --- a/internal/dao/log_options.go +++ b/internal/dao/log_options.go @@ -26,6 +26,7 @@ type LogOptions struct { SingleContainer bool MultiPods bool ShowTimestamp bool + ShowJSON bool AllContainers bool } diff --git a/internal/model/log.go b/internal/model/log.go index d194fcf017..43f294c3c3 100644 --- a/internal/model/log.go +++ b/internal/model/log.go @@ -92,6 +92,12 @@ func (l *Log) ToggleShowTimestamp(b bool) { l.Refresh() } +// ToggleShowJSON toggles to colorize JSON logs. +func (l *Log) ToggleShowJSON(b bool) { + l.logOptions.ShowJSON = b + l.Refresh() +} + func (l *Log) Head(ctx context.Context) { l.mx.Lock() { @@ -149,7 +155,7 @@ func (l *Log) Clear() { func (l *Log) Refresh() { l.fireLogCleared() ll := make([][]byte, l.lines.Len()) - l.lines.Render(0, l.logOptions.ShowTimestamp, ll) + l.lines.Render(0, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) l.fireLogChanged(ll) } @@ -184,7 +190,7 @@ func (l *Log) Set(lines *dao.LogItems) { l.fireLogCleared() ll := make([][]byte, l.lines.Len()) - l.lines.Render(0, l.logOptions.ShowTimestamp, ll) + l.lines.Render(0, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) l.fireLogChanged(ll) } @@ -198,7 +204,7 @@ func (l *Log) ClearFilter() { l.fireLogCleared() ll := make([][]byte, l.lines.Len()) - l.lines.Render(0, l.logOptions.ShowTimestamp, ll) + l.lines.Render(0, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) l.fireLogChanged(ll) } @@ -350,7 +356,7 @@ func (l *Log) applyFilter(index int, q string) ([][]byte, error) { if q == "" { return nil, nil } - matches, indices, err := l.lines.Filter(index, q, l.logOptions.ShowTimestamp) + matches, indices, err := l.lines.Filter(index, q, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON) if err != nil { return nil, err } @@ -358,7 +364,7 @@ func (l *Log) applyFilter(index int, q string) ([][]byte, error) { // No filter! if matches == nil { ll := make([][]byte, l.lines.Len()) - l.lines.Render(index, l.logOptions.ShowTimestamp, ll) + l.lines.Render(index, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) return ll, nil } // Blank filter @@ -367,7 +373,7 @@ func (l *Log) applyFilter(index int, q string) ([][]byte, error) { } filtered := make([][]byte, 0, len(matches)) ll := make([][]byte, l.lines.Len()) - l.lines.Lines(index, l.logOptions.ShowTimestamp, ll) + l.lines.Lines(index, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) for i, idx := range matches { filtered = append(filtered, color.Highlight(ll[idx], indices[i], 209)) } @@ -378,7 +384,7 @@ func (l *Log) applyFilter(index int, q string) ([][]byte, error) { func (l *Log) fireLogBuffChanged(index int) { ll := make([][]byte, l.lines.Len()-index) if l.filter == "" { - l.lines.Render(index, l.logOptions.ShowTimestamp, ll) + l.lines.Render(index, l.logOptions.ShowTimestamp, l.logOptions.ShowJSON, ll) } else { ff, err := l.applyFilter(index, l.filter) if err != nil { diff --git a/internal/model/log_test.go b/internal/model/log_test.go index 18f629bace..8f09f86ea4 100644 --- a/internal/model/log_test.go +++ b/internal/model/log_test.go @@ -157,7 +157,7 @@ func TestLogBasic(t *testing.T) { assert.Equal(t, 1, v.clearCalled) assert.Equal(t, 0, v.errCalled) ll := make([][]byte, data.Len()) - data.Lines(0, false, ll) + data.Lines(0, false, false, ll) assert.Equal(t, ll, v.data) } @@ -171,7 +171,7 @@ func TestLogAppend(t *testing.T) { items.Add(dao.NewLogItemFromString("blah blah")) m.Set(items) ll := make([][]byte, items.Len()) - items.Lines(0, false, ll) + items.Lines(0, false, false, ll) assert.Equal(t, ll, v.data) data := dao.NewLogItems() @@ -184,7 +184,7 @@ func TestLogAppend(t *testing.T) { } assert.Equal(t, 1, v.dataCalled) ll = make([][]byte, items.Len()) - items.Lines(0, false, ll) + items.Lines(0, false, false, ll) assert.Equal(t, ll, v.data) m.Notify() diff --git a/internal/view/container.go b/internal/view/container.go index 01f4f1e5e5..e2793c0eab 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -117,6 +117,7 @@ func (c *Container) logOptions(prev bool) (*dao.LogOptions, error) { SinceSeconds: cfg.SinceSeconds, SingleContainer: true, ShowTimestamp: cfg.ShowTime, + ShowJSON: cfg.ShowJSON, Previous: prev, } diff --git a/internal/view/log.go b/internal/view/log.go index be01ed5a5d..36902cc499 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -102,6 +102,7 @@ func (l *Log) Init(ctx context.Context) (err error) { l.updateTitle() l.model.ToggleShowTimestamp(l.app.Config.K9s.Logger.ShowTime) + l.model.ToggleShowJSON((l.app.Config.K9s.Logger.ShowJSON)) return nil } @@ -256,6 +257,7 @@ func (l *Log) bindKeys() { ui.KeyM: ui.NewKeyAction("Mark", l.markCmd, true), ui.KeyS: ui.NewKeyAction("Toggle AutoScroll", l.toggleAutoScrollCmd, true), ui.KeyF: ui.NewKeyAction("Toggle FullScreen", l.toggleFullScreenCmd, true), + tcell.KeyCtrlJ: ui.NewKeyAction("Toggle JSON", l.toggleJSONCmd, true), ui.KeyT: ui.NewKeyAction("Toggle Timestamp", l.toggleTimestampCmd, true), ui.KeyW: ui.NewKeyAction("Toggle Wrap", l.toggleTextWrapCmd, true), tcell.KeyCtrlS: ui.NewKeyAction("Save", l.SaveCmd, true), @@ -354,6 +356,7 @@ func (l *Log) Flush(lines [][]byte) { if l.cancelUpdates { break } + _, _ = l.ansiWriter.Write(lines[i]) } if l.follow { @@ -515,6 +518,17 @@ func (l *Log) toggleFullScreen() { } } +func (l *Log) toggleJSONCmd(evt *tcell.EventKey) *tcell.EventKey { + if l.app.InCmdMode() { + return evt + } + l.indicator.ToggleJSON() + l.model.ToggleShowJSON(l.indicator.showJson) + l.indicator.Refresh() + + return nil +} + func (l *Log) isContainerLogView() bool { return l.model.HasDefaultContainer() } diff --git a/internal/view/log_indicator.go b/internal/view/log_indicator.go index ce80654b09..06e1d7f159 100644 --- a/internal/view/log_indicator.go +++ b/internal/view/log_indicator.go @@ -23,6 +23,7 @@ type LogIndicator struct { fullScreen bool textWrap bool showTime bool + showJson bool allContainers bool shouldDisplayAllContainers bool } @@ -37,6 +38,7 @@ func NewLogIndicator(cfg *config.Config, styles *config.Styles, allContainers bo fullScreen: cfg.K9s.UI.DefaultsToFullScreen, textWrap: cfg.K9s.Logger.TextWrap, showTime: cfg.K9s.Logger.ShowTime, + showJson: cfg.K9s.Logger.ShowJSON, shouldDisplayAllContainers: allContainers, } l.StylesChanged(styles) @@ -74,6 +76,11 @@ func (l *LogIndicator) FullScreen() bool { return l.fullScreen } +// Json reports the whether the logs are JSON colorized. +func (l *LogIndicator) Json() bool { + return l.showJson +} + // ToggleTimestamp toggles the current timestamp mode. func (l *LogIndicator) ToggleTimestamp() { l.showTime = !l.showTime @@ -85,6 +92,12 @@ func (l *LogIndicator) ToggleFullScreen() { l.Refresh() } +// ToggleJSON toggles the whether JSON logging is colorized. +func (l *LogIndicator) ToggleJSON() { + l.showJson = !l.showJson + l.Refresh() +} + // ToggleTextWrap toggles the wrap mode. func (l *LogIndicator) ToggleTextWrap() { l.textWrap = !l.textWrap @@ -142,6 +155,12 @@ func (l *LogIndicator) Refresh() { l.indicator = append(l.indicator, fmt.Sprintf(toggleOffFmt, "FullScreen", spacer)...) } + if l.Json() { + l.indicator = append(l.indicator, "[::b]JSON:[limegreen::b]On[-::] "+spacer...) + } else { + l.indicator = append(l.indicator, "[::b]JSON:[gray::d]Off[-::]"+spacer...) + } + if l.Timestamp() { l.indicator = append(l.indicator, fmt.Sprintf(toggleOnFmt, "Timestamps", spacer)...) } else { diff --git a/internal/view/log_indicator_test.go b/internal/view/log_indicator_test.go index 0c793f594d..26381eef9f 100644 --- a/internal/view/log_indicator_test.go +++ b/internal/view/log_indicator_test.go @@ -18,10 +18,10 @@ func TestLogIndicatorRefresh(t *testing.T) { e string }{ "all-containers": { - view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[::b]AllContainers:[gray::d]Off[-::] [::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n", + view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[::b]AllContainers:[gray::d]Off[-::] [::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]JSON:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n", }, "plain": { - view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n", + view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]JSON:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n", }, } diff --git a/internal/view/log_int_test.go b/internal/view/log_int_test.go index f6b5e4aeab..0ea627aec0 100644 --- a/internal/view/log_int_test.go +++ b/internal/view/log_int_test.go @@ -26,10 +26,10 @@ func TestLogAutoScroll(t *testing.T) { v.GetModel().Set(ii) v.GetModel().Notify() - assert.Equal(t, 16, len(v.Hints())) + assert.Equal(t, 17, len(v.Hints())) v.toggleAutoScrollCmd(nil) - assert.Equal(t, "Autoscroll:Off FullScreen:Off Timestamps:Off Wrap:Off", v.Indicator().GetText(true)) + assert.Equal(t, "Autoscroll:Off FullScreen:Off JSON:Off Timestamps:Off Wrap:Off", v.Indicator().GetText(true)) } func TestLogViewNav(t *testing.T) { @@ -87,7 +87,7 @@ func TestLogTimestamp(t *testing.T) { l.SendKeys(ui.KeyT) l.Logs().Clear() ll := make([][]byte, ii.Len()) - ii.Lines(0, true, ll) + ii.Lines(0, true, false, ll) l.Flush(ll) assert.Equal(t, fmt.Sprintf("%-30s %s", "ttt", "fred/blee c1 Testing 1, 2, 3\n"), l.Logs().GetText(true)) diff --git a/internal/view/log_test.go b/internal/view/log_test.go index 5db3fcaf8f..689c9e8642 100644 --- a/internal/view/log_test.go +++ b/internal/view/log_test.go @@ -32,7 +32,7 @@ func TestLog(t *testing.T) { ii := dao.NewLogItems() ii.Add(dao.NewLogItemFromString("blee\n"), dao.NewLogItemFromString("bozo\n")) ll := make([][]byte, ii.Len()) - ii.Lines(0, false, ll) + ii.Lines(0, false, false, ll) v.Flush(ll) assert.Equal(t, "Waiting for logs...\nblee\nbozo\n", v.Logs().GetText(true)) @@ -52,7 +52,7 @@ func TestLogFlush(t *testing.T) { dao.NewLogItemFromString("\033[0;32mBozo\n"), ) ll := make([][]byte, items.Len()) - items.Lines(0, false, ll) + items.Lines(0, false, false, ll) v.Flush(ll) assert.Equal(t, "[orange::d]Waiting for logs...\n[black::]blee\n[green::]Bozo\n\n", v.Logs().GetText(false)) @@ -73,7 +73,7 @@ func BenchmarkLogFlush(b *testing.B) { dao.NewLogItemFromString("\033[0;101mBozo\n"), ) ll := make([][]byte, items.Len()) - items.Lines(0, false, ll) + items.Lines(0, false, false, ll) b.ReportAllocs() b.ResetTimer() @@ -108,7 +108,7 @@ func TestLogViewSave(t *testing.T) { ii := dao.NewLogItems() ii.Add(dao.NewLogItemFromString("blee"), dao.NewLogItemFromString("bozo")) ll := make([][]byte, ii.Len()) - ii.Lines(0, false, ll) + ii.Lines(0, false, false, ll) v.Flush(ll) dd := "/tmp/test-dumps/na" diff --git a/internal/view/logs_extender.go b/internal/view/logs_extender.go index d2a8ad4f39..589283ea6e 100644 --- a/internal/view/logs_extender.go +++ b/internal/view/logs_extender.go @@ -86,6 +86,7 @@ func (l *LogsExtender) buildLogOpts(path, co string, prevLogs bool) *dao.LogOpti Lines: int64(cfg.TailCount), Previous: prevLogs, ShowTimestamp: cfg.ShowTime, + ShowJSON: cfg.ShowJSON, } if opts.Container == "" { opts.AllContainers = true