Как преобразовать прошедшее время в стиле Kubernetes в секунды, чтобы можно было провести некоторые сравнения

Как преобразовать прошедшее время в стиле Kubernetes в секунды, чтобы можно было провести некоторые сравнения

От

kubectl get pods -o wide

Вывод выглядит примерно так:

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>

Я получаю прошедшее время для модулей в формате: 4д3ч15м3с (похоже, что чаще всего это две последовательные единицы: дни и часы, часы минуты, минуты и секунды, но я не могу этого гарантировать).

Мне нужно проверить, существует ли модуль дольше некоторого порогового значения X.

Я пытался найти способ извлечь это поле как секунды через kubectl, но безуспешно. Я искал в интернете готовое решение, но не смог его найти.

Я думаю, что могу использовать awk для преобразования строки в числовое значение секунд, чтобы затем можно было сравнить, если оно > $X; это значение можно настраивать.

решение1

Вам не нужно разветвлять внешний процесс только для того, чтобы получить прошедшее время kubernetes в секундах. Нижеприведенный код GNU awk имеет определяемую пользователем функцию, fx()которая должна выполнить это преобразование, и с этого момента вы можете использовать ее для целей сравнения.

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

Если вы хотите воспользоваться пользовательской функцией в bash, то мы можем сделать следующее. У нас есть функция fx(), которой нужен один аргумент, представляющий собой прошедшее время в формате kubernetes, и она выведет время в секундах.

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

Мы динамически генерируем код для утилиты Linux под названиемОкруг Колумбияили настольный калькулятор вРПН(Обратная польская запись).

решение2

Если кто-то, как и я, ищет функцию Python, вот она:

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

решение3

Потратив на это некоторое время, я пришел к выводу, что самый быстрый способ получить это — токенизировать время с помощью замены 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}'

До сих пор я наблюдал только использование единиц измерения в этой области, даже для стручков, которым более 100 дней.

Команда sed в основном разделяет каждую единицу пробелом.
Затем Awk проходит по полям и разделяет строку на единицу (u) и числовую строку (s).
Связанные операторы if-elseif-else просто преобразуют значения в секунды на основе единицы и добавляют их к промежуточному итогу времени в секундах, который сохраняется.

Я поместил эту команду в скрипт «kube_elapsed_to_seconds» и планирую использовать другой awk снаружи и системную команду для запуска этого скрипта в этом поле.

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

Я открыт для предложений о том, как сделать эту команду более удобной для чтения или улучшить ее взаимодействие с другими полями, не связанными со временем, такими как podname и status, которые могут присутствовать.

решение4

Для команды, которая их понимает 4d3h15m3s, см. dateutils dadd:

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

Здесь эта длительность добавляется к началу времени эпохи Unix и результат выводится как время эпохи Unix в часовом поясе с нулевым смещением относительно UTC.

Связанный контент