...
1
16
17 package events
18
19 import (
20 "fmt"
21 "io"
22 "strings"
23 "time"
24
25 corev1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/runtime"
28 "k8s.io/apimachinery/pkg/util/duration"
29 "k8s.io/cli-runtime/pkg/printers"
30 )
31
32
33
34 type EventPrinter struct {
35 NoHeaders bool
36 AllNamespaces bool
37
38 headersPrinted bool
39 }
40
41
42 func (ep *EventPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
43 if !ep.NoHeaders && !ep.headersPrinted {
44 ep.printHeadings(out)
45 ep.headersPrinted = true
46 }
47
48 switch t := obj.(type) {
49 case *corev1.EventList:
50 for _, e := range t.Items {
51 ep.printOneEvent(out, e)
52 }
53 case *corev1.Event:
54 ep.printOneEvent(out, *t)
55 default:
56 return fmt.Errorf("unknown event type %t", t)
57 }
58
59 return nil
60 }
61
62 func (ep *EventPrinter) printHeadings(w io.Writer) {
63 if ep.AllNamespaces {
64 fmt.Fprintf(w, "NAMESPACE\t")
65 }
66 fmt.Fprintf(w, "LAST SEEN\tTYPE\tREASON\tOBJECT\tMESSAGE\n")
67 }
68
69 func (ep *EventPrinter) printOneEvent(w io.Writer, e corev1.Event) {
70 interval := getInterval(e)
71 if ep.AllNamespaces {
72 fmt.Fprintf(w, "%v\t", e.Namespace)
73 }
74 fmt.Fprintf(w, "%s\t%s\t%s\t%s/%s\t%v\n",
75 interval,
76 printers.EscapeTerminal(e.Type),
77 printers.EscapeTerminal(e.Reason),
78 printers.EscapeTerminal(e.InvolvedObject.Kind),
79 printers.EscapeTerminal(e.InvolvedObject.Name),
80 printers.EscapeTerminal(strings.TrimSpace(e.Message)),
81 )
82 }
83
84 func getInterval(e corev1.Event) string {
85 var interval string
86 firstTimestampSince := translateMicroTimestampSince(e.EventTime)
87 if e.EventTime.IsZero() {
88 firstTimestampSince = translateTimestampSince(e.FirstTimestamp)
89 }
90 if e.Series != nil {
91 interval = fmt.Sprintf("%s (x%d over %s)", translateMicroTimestampSince(e.Series.LastObservedTime), e.Series.Count, firstTimestampSince)
92 } else if e.Count > 1 {
93 interval = fmt.Sprintf("%s (x%d over %s)", translateTimestampSince(e.LastTimestamp), e.Count, firstTimestampSince)
94 } else {
95 interval = firstTimestampSince
96 }
97
98 return interval
99 }
100
101
102
103 func translateMicroTimestampSince(timestamp metav1.MicroTime) string {
104 if timestamp.IsZero() {
105 return "<unknown>"
106 }
107
108 return duration.HumanDuration(time.Since(timestamp.Time))
109 }
110
111
112
113 func translateTimestampSince(timestamp metav1.Time) string {
114 if timestamp.IsZero() {
115 return "<unknown>"
116 }
117
118 return duration.HumanDuration(time.Since(timestamp.Time))
119 }
120
121 func NewEventPrinter(noHeader, allNamespaces bool) *EventPrinter {
122 return &EventPrinter{
123 NoHeaders: noHeader,
124 AllNamespaces: allNamespaces,
125 }
126 }
127
View as plain text