77 "fmt"
88 "regexp"
99 "strings"
10+ "time"
1011
1112 g "github.com/onsi/ginkgo/v2"
1213 o "github.com/onsi/gomega"
@@ -60,6 +61,8 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer][Late]", func() {
6061 g .It ("kubelet terminates kube-apiserver gracefully extended" , func () {
6162 var finalMessageBuilder strings.Builder
6263 terminationRegexp := regexp .MustCompile (`Previous pod .* did not terminate gracefully` )
64+ // klog timestamp format: W0120 22:20:50.473381
65+ klogTimestampRegexp := regexp .MustCompile (`^[IWEF](\d{4}) (\d{2}:\d{2}:\d{2}\.\d+)` )
6366
6467 masters , err := oc .AsAdmin ().KubeClient ().CoreV1 ().Nodes ().List (context .Background (), metav1.ListOptions {LabelSelector : "node-role.kubernetes.io/master" })
6568 o .Expect (err ).NotTo (o .HaveOccurred ())
@@ -79,7 +82,8 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer][Late]", func() {
7982 for kasTerminationFileScanner .Scan () {
8083 line := kasTerminationFileScanner .Text ()
8184 if terminationRegexp .MatchString (line ) {
82- finalMessageBuilder .WriteString (fmt .Sprintf ("\n kube-apiserver on node %s wasn't gracefully terminated, reason: %s" , master .Name , line ))
85+ observedAt := parseKlogTimestamp (line , klogTimestampRegexp )
86+ finalMessageBuilder .WriteString (fmt .Sprintf ("\n kube-apiserver on node %s wasn't gracefully terminated (observed at %s), reason: %s" , master .Name , observedAt , line ))
8387 }
8488 }
8589 o .Expect (kasTerminationFileScanner .Err ()).NotTo (o .HaveOccurred ())
@@ -185,3 +189,20 @@ func extractAPIServerNameFromAuditFile(auditFileName string) string {
185189func isKASTerminationLogFile (fileName string ) bool {
186190 return strings .Contains (fileName , "termination" )
187191}
192+
193+ // parseKlogTimestamp extracts and formats the klog timestamp from a log line.
194+ // klog timestamps have the format: W0120 22:20:50.473381 (MMDD HH:MM:SS.ffffff without year).
195+ // We use the current year as klog does not include it.
196+ func parseKlogTimestamp (line string , klogTimestampRegexp * regexp.Regexp ) string {
197+ matches := klogTimestampRegexp .FindStringSubmatch (line )
198+ if len (matches ) < 3 {
199+ return "unknown"
200+ }
201+ // matches[1] = "0120" (MMDD), matches[2] = "22:20:50.473381"
202+ timestampStr := fmt .Sprintf ("%d-%s-%s" , time .Now ().Year (), matches [1 ][:2 ]+ "-" + matches [1 ][2 :], matches [2 ])
203+ t , err := time .Parse ("2006-01-02-15:04:05.000000" , timestampStr )
204+ if err != nil {
205+ return matches [1 ] + " " + matches [2 ]
206+ }
207+ return t .Format (time .RFC3339 )
208+ }
0 commit comments