...

Source file src/k8s.io/kubectl/pkg/cmd/events/event_printer.go

Documentation: k8s.io/kubectl/pkg/cmd/events

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    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  // EventPrinter stores required fields to be used for
    33  // default printing for events command.
    34  type EventPrinter struct {
    35  	NoHeaders     bool
    36  	AllNamespaces bool
    37  
    38  	headersPrinted bool
    39  }
    40  
    41  // PrintObj prints different type of event objects.
    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  // translateMicroTimestampSince returns the elapsed time since timestamp in
   102  // human-readable approximation.
   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  // translateTimestampSince returns the elapsed time since timestamp in
   112  // human-readable approximation.
   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