Como converter o tempo decorrido no estilo Kubernetes em segundos para que eu possa fazer algumas comparações

Como converter o tempo decorrido no estilo Kubernetes em segundos para que eu possa fazer algumas comparações

De

kubectl get pods -o wide

A saída é semelhante a

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>

Recebo o tempo decorrido para os pods em um formato como: 4d3h15m3s (parece que o máximo são duas unidades consecutivas, dias e horas, horas minutos, minutos e segundos, mas não posso garantir isso.

Preciso verificar se um pod existe há mais tempo do que algum limite X.

Tentei encontrar alguma maneira de extrair esse campo em segundos via kubectl, sem sorte. Procurei na internet por uma solução pré-enlatada, mas não consegui encontrar.

Estou pensando que posso usar o awk para converter a string em segundos numéricos para poder comparar se é > $X, esse valor é configurável.

Responder1

Você não precisa bifurcar um processo externo apenas para obter o tempo decorrido do Kubernetes em segundos. O código GNU awk abaixo tem uma função definida pelo usuário fx()que fará essa conversão e a partir daí você poderá usá-la para fins de comparação.

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
  }
'

Caso você queira usar uma função definida pelo usuário no bash, podemos fazer o seguinte. Temos uma função fx() que precisa de um argumento, que é o tempo decorrido no formato kubernetes e produzirá um tempo em segundos.

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
'
}

Estamos gerando dinamicamente um código para o utilitário Linux chamadoCCou a calculadora de mesa noRPN(Notação polonesa reversa).

Responder2

Caso alguém esteja procurando uma função python como eu, aqui está:

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

Responder3

Passei algum tempo nisso e descobri que a maneira mais rápida de conseguir isso era tokenizar o tempo com uma substituição sed.

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}'

Até agora, observei apenas unidades d,h,m,s sendo usadas neste campo, mesmo para pods com mais de 100 dias.

O comando sed basicamente divide cada unidade com um espaço.
Awk então percorre os campos e divide a string na unidade (u) e na(s) string(s) numérica(s).
As instruções if-elseif-else encadeadas simplesmente convertem os valores em segundos com base na unidade e os adicionam a um total contínuo do tempo em segundos mantido.

Coloquei este comando em um script "kube_elapsed_to_seconds" e planejo usar outro awk do lado de fora e o comando do sistema para executar este script neste campo.

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

Estou aberto a sugestões sobre como tornar este comando mais fácil de ler ou interagir melhor com outros campos não relacionados ao tempo, como podname e status, que possam estar presentes.

Responder4

Para um comando que os entende 4d3h15m3s, consulte dateutils dadd:

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

Aqui, adicionando essa duração ao início do horário da época Unix e gerando o resultado como horário da época Unix, em um fuso horário com deslocamento 0 para UTC.

informação relacionada