From 824f04f86af26b5bd23d8c3659cfe85d6a52e66c Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Thu, 31 Aug 2017 19:08:14 -0400 Subject: [PATCH] Simplify describe events table The describe table for events is not easy to read and violates other output guidelines. Change to use spaces (we don't use tabs in formal output for tables). Remove columns that are not normally needed or available on events. Example for pods: ``` ... QoS Class: BestEffort Node-Selectors: role=app Tolerations: Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulling 1h (x51 over 5h) kubelet, origin-ci-ig-n-gj0x pulling image "registry.svc.ci.openshift.org/experiment/commenter:latest" Normal BackOff 8m (x1274 over 5h) kubelet, origin-ci-ig-n-gj0x Back-off pulling image "registry.svc.ci.openshift.org/experiment/commenter:latest" Warning FailedSync 3m (x1359 over 5h) kubelet, origin-ci-ig-n-gj0x Error syncing pod ``` Puts the type first (separate important from not), then reason (which is the most impactful scanning field). Collapses first seen, last seen, and times into a single field, since most of the time you care about the last time the event happened, not the first time. --- pkg/kubectl/history.go | 2 +- pkg/printers/internalversion/describe.go | 37 ++++++++++++++----- pkg/printers/internalversion/describe_test.go | 30 +++++++-------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/pkg/kubectl/history.go b/pkg/kubectl/history.go index 7bf4eb5b88c..5464686291d 100644 --- a/pkg/kubectl/history.go +++ b/pkg/kubectl/history.go @@ -335,7 +335,7 @@ func applyHistory(ds *extensionsv1beta1.DaemonSet, history *appsv1beta1.Controll func tabbedString(f func(io.Writer) error) (string, error) { out := new(tabwriter.Writer) buf := &bytes.Buffer{} - out.Init(buf, 0, 8, 1, '\t', 0) + out.Init(buf, 0, 8, 2, ' ', 0) err := f(out) if err != nil { diff --git a/pkg/printers/internalversion/describe.go b/pkg/printers/internalversion/describe.go index 94a3f39187f..e00be107542 100644 --- a/pkg/printers/internalversion/describe.go +++ b/pkg/printers/internalversion/describe.go @@ -89,6 +89,8 @@ type PrefixWriter interface { Write(level int, format string, a ...interface{}) // WriteLine writes an entire line with no indentation level. WriteLine(a ...interface{}) + // Flush forces indendation to be reset. + Flush() } // prefixWriter implements PrefixWriter @@ -116,6 +118,12 @@ func (pw *prefixWriter) WriteLine(a ...interface{}) { fmt.Fprintln(pw.out, a...) } +func (pw *prefixWriter) Flush() { + if f, ok := pw.out.(flusher); ok { + f.Flush() + } +} + func describerMap(c clientset.Interface) map[schema.GroupKind]printers.Describer { m := map[schema.GroupKind]printers.Describer{ api.Kind("Pod"): &PodDescriber{c}, @@ -2853,19 +2861,24 @@ func DescribeEvents(el *api.EventList, w PrefixWriter) { w.Write(LEVEL_0, "Events:\t\n") return } + w.Flush() sort.Sort(events.SortableEvents(el.Items)) - w.Write(LEVEL_0, "Events:\n FirstSeen\tLastSeen\tCount\tFrom\tSubObjectPath\tType\tReason\tMessage\n") - w.Write(LEVEL_1, "---------\t--------\t-----\t----\t-------------\t--------\t------\t-------\n") + w.Write(LEVEL_0, "Events:\n Type\tReason\tAge\tFrom\tMessage\n") + w.Write(LEVEL_1, "----\t------\t----\t----\t-------\n") for _, e := range el.Items { - w.Write(LEVEL_1, "%s\t%s\t%d\t%v\t%v\t%v\t%v\t%v\n", - translateTimestamp(e.FirstTimestamp), - translateTimestamp(e.LastTimestamp), - e.Count, - formatEventSource(e.Source), - e.InvolvedObject.FieldPath, + var interval string + if e.Count > 1 { + interval = fmt.Sprintf("%s (x%d over %s)", translateTimestamp(e.LastTimestamp), e.Count, translateTimestamp(e.FirstTimestamp)) + } else { + interval = translateTimestamp(e.FirstTimestamp) + } + w.Write(LEVEL_1, "%v\t%v\t%s\t%v\t%v\n", e.Type, e.Reason, - e.Message) + interval, + formatEventSource(e.Source), + strings.TrimSpace(e.Message), + ) } } @@ -3591,10 +3604,14 @@ func printTolerationsMultilineWithIndent(w PrefixWriter, initialIndent, title, i } } +type flusher interface { + Flush() +} + func tabbedString(f func(io.Writer) error) (string, error) { out := new(tabwriter.Writer) buf := &bytes.Buffer{} - out.Init(buf, 0, 8, 1, '\t', 0) + out.Init(buf, 0, 8, 2, ' ', 0) err := f(out) if err != nil { diff --git a/pkg/printers/internalversion/describe_test.go b/pkg/printers/internalversion/describe_test.go index 2d74b242200..8df36736c7f 100644 --- a/pkg/printers/internalversion/describe_test.go +++ b/pkg/printers/internalversion/describe_test.go @@ -1499,22 +1499,22 @@ URL: http://localhost func TestDescribePodSecurityPolicy(t *testing.T) { expected := []string{ - "Name:\t*mypsp", - "Allow Privileged:\t*false", - "Default Add Capabilities:\t*", - "Required Drop Capabilities:\t*", - "Allowed Capabilities:\t*", - "Allowed Volume Types:\t*", - "Allow Host Network:\t*false", - "Allow Host Ports:\t*", - "Allow Host PID:\t*false", - "Allow Host IPC:\t*false", - "Read Only Root Filesystem:\t*false", + "Name:\\s*mypsp", + "Allow Privileged:\\s*false", + "Default Add Capabilities:\\s*", + "Required Drop Capabilities:\\s*", + "Allowed Capabilities:\\s*", + "Allowed Volume Types:\\s*", + "Allow Host Network:\\s*false", + "Allow Host Ports:\\s*", + "Allow Host PID:\\s*false", + "Allow Host IPC:\\s*false", + "Read Only Root Filesystem:\\s*false", "SELinux Context Strategy: RunAsAny", - "User:\t*", - "Role:\t*", - "Type:\t*", - "Level:\t*", + "User:\\s*", + "Role:\\s*", + "Type:\\s*", + "Level:\\s*", "Run As User Strategy: RunAsAny", "FSGroup Strategy: RunAsAny", "Supplemental Groups Strategy: RunAsAny",