Wie konvertiere ich die verstrichene Zeit im Kubernetes-Stil in Sekunden, damit ich einige Vergleiche anstellen kann?

Wie konvertiere ich die verstrichene Zeit im Kubernetes-Stil in Sekunden, damit ich einige Vergleiche anstellen kann?

Aus

kubectl get pods -o wide

Die Ausgabe sieht ähnlich aus wie

some-pod-name-with-numbers-123             1/1     Running   0          6d4h      192.168.0.23   node-name-abcdeft-host.domain   <none>           <none>
some-pod-name-with-numbers-1234            1/1     Running   0          4h38m      192.168.0.24   node-name-abcdeft-host.domain   <none>           <none>
some-pod-name-with-numbers-1235            1/1     Running   0          2m38s      192.168.0.25   node-name-abcdeft-host.domain   <none>           <none>

Ich erhalte die verstrichene Zeit für die Pods in einem Format wie: 4d3h15m3s (es sieht so aus, als wären das Höchste zwei aufeinanderfolgende Einheiten, Tage und Stunden, Stunden, Minuten, Minuten und Sekunden, aber das kann ich nicht garantieren).

Ich muss überprüfen, ob eine Kapsel länger als ein bestimmter Schwellenwert X existiert.

Ich habe versucht, eine Möglichkeit zu finden, dieses Feld über kubectl als Sekunden zu extrahieren, aber ohne Erfolg. Ich habe im Internet nach einer vorgefertigten Lösung gesucht, konnte aber keine finden.

Ich denke, dass ich awk verwenden kann, um die Zeichenfolge in eine Sekundenangabe umzuwandeln, sodass ich dann vergleichen kann, ob sie > $X ist. Dieser Wert ist konfigurierbar.

Antwort1

Sie müssen keinen externen Prozess forken, nur um die verstrichene Zeit von Kubernetes in Sekunden zu erhalten. Der folgende GNU-awk-Code hat eine benutzerdefinierte Funktion, fx()die diese Konvertierung durchführt, und von da an können Sie sie für Ihre Vergleichszwecke verwenden.

kubectl get pods -o wide |
awk '
BEGIN {
    a["d"] = 24*(\
    a["h"] = 60*(\
    a["m"] = 60*(\
    a["s"] = 1)));
  }
  {
    print fx($5); # kubernetes time elapsed in seconds 
  }
  function fx(ktym,    f,u,n,t,i) {
    n = split(ktym, f, /[dhms]/, u)
    t = 0
    for (i=1; i<n; i++) {
      t += f[i] * a[u[i]] 
    }
    return t
  }
'

Falls Sie eine benutzerdefinierte Funktion in Bash verwenden möchten, können wir Folgendes tun. Wir haben eine Funktion fx(), die ein Argument benötigt, nämlich die verstrichene Zeit im Kubernetes-Format, und sie gibt eine Zeit in Sekunden aus.

fx() {
echo "$1" |
sed -Ee '
  s/[1-9][0-9]*[dhms]/&+ /g
  :a;s/[+]([^+].*)/\1+/;ta
  s/.$//
  :loop
    s/d/ 24h*/
    s/h/ 60m*/
    s/m/ 60s*/
    s/s//
  t loop
  s/.*/echo "&" | dc -e "?p"/e
'
}

Wir generieren dynamisch einen Code für das Linux-Dienstprogramm namensGleichstromoder der Tischrechner imRPN(Umgekehrte polnische Notation).

Antwort2

Falls jemand wie ich nach einer Python-Funktion sucht, hier ist sie:

def kubctle_dur_to_secs(kubectl_time:str) -> int:
    total_time = 0
    for t_char, sec_in_t in zip( ('d', 'h', 'm', 's'), (86400, 3600, 60, 1) ):
        if t_char in kubectl_time:
            t_index = kubectl_time.find(t_char)
            total_time += int(kubectl_time[:t_index])*sec_in_t
            kubectl_time = kubectl_time[t_index+1:]
    return total_time

Antwort3

Ich habe einige Zeit damit verbracht und herausgefunden, dass der schnellste Weg, dies zu erreichen, darin besteht, die Zeit mit einem „sed replace“ zu tokenisieren.

sed -e 's/\([smhd]\)/\1 /g' | awk '{ b=0; for(i=1; i<=NF; ++i) { s=substr($i,1,length($i)-1); u=substr($i,length($i)); if (u=="s") b+=s; else if (u=="m") b+=s*60; else if (u=="h") b+=s*60*60; else if (u=="d") b+=s*60*60*24; else u=""; } if (b>1) printf "%d", b}'

Bisher habe ich in diesem Bereich nur die Verwendung von d,h,m,s-Einheiten beobachtet, sogar bei Schoten, die älter als 100 Tage sind.

Der sed-Befehl teilt grundsätzlich jede Einheit mit einem Leerzeichen.
Awk durchläuft dann die Felder und teilt die Zeichenfolge in die Einheit (u) und die numerische Zeichenfolge (s) auf.
Die verketteten if-elseif-else-Anweisungen wandeln die Werte einfach basierend auf der Einheit in Sekunden um und addieren sie zu einer laufenden Summe der Zeit in Sekunden, die beibehalten wird.

Ich habe diesen Befehl in ein Skript „kube_elapsed_to_seconds“ eingefügt und plane, ein weiteres Awk außerhalb und den Systembefehl zu verwenden, um dieses Skript in diesem Feld auszuführen.

kubectl get pods -o wide | awk '{ system("echo " $5 " | kube_elapased_to_seconds"); print $0 }'

Ich bin offen für Vorschläge, wie dieser Befehl leichter lesbar gemacht werden kann oder wie die Interaktion mit eventuell vorhandenen, nicht zeitbezogenen Feldern wie Podname und Status verbessert werden kann.

Antwort4

Einen Befehl, der diese versteht 4d3h15m3s, finden Sie unter dateutils dadd:

$ TZ=UTC0 dateutils.dadd -f%s 1970-01-01T00:00:00 4d3h15m3s
357303

Hier wird diese Dauer zum Beginn der Unix-Epochenzeit addiert und das Ergebnis als Unix-Epochenzeit in einer Zeitzone mit 0 % Unterschied zur UTC ausgegeben.

verwandte Informationen