Чи є спосіб зробити журнали журналу показу журналу "останній раз foo.service запущений"?


16

Мене це особливо цікавить, коли я дивлюся на висновок програм, що працюють на таймері. --unitПрапор близько, але це об'єднує всі пробіги служби разом. Найбільш очевидним способом, який я можу придумати, було б фільтрувати PID, але це змушує мене турбуватися про повторне використання / послуги PID, що розщедриться, та отримання останнього PID - дуже незручно. Чи є якийсь інший ідентифікатор, який відповідає одному циклу послуги, який я міг би використовувати для фільтрації журналів?

EDIT: Я б із задоволенням прийняв авторитетне "ні", якщо це справжня відповідь.

Відповіді:


8

З моменту systemdверсії у 232нас є концепція ідентифікатора виклику. Щоразу при запуску одиниці він має унікальний 128-бітний ідентифікатор виклику. На відміну від того, MainPIDякий може бути перероблений або ActiveEnterTimestampякий може мати проблеми з вирішенням, це безпечний спосіб отримати весь журнал виклику певного системного блоку.

Щоб отримати останній ідентифікатор виклику одиниці

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

Щоб отримати журнал останньої виклику, скажімо, openipmiневдалого чи ні, ви можете скористатися одним вкладишем

$ journalctl _SYSTEMD_INVOCATION_ID=`systemctl show -p InvocationID --value openipmi.service`
-- Logs begin at Thu 2018-07-26 12:09:57 IDT, end at Mon 2019-07-08 01:32:50 IDT. --
Jun 21 13:03:13 build03.lbits openipmi[1552]:  * Starting ipmi drivers
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...fail!
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...done.

(Зверніть увагу, що --valueдоступний, оскільки systemd 230старший InvocationID)


1
Якщо хтось намагається розслідувати це: journalctl --user -u UNITFILE -f -o json-prettyможе бути корисним; ви шукаєте MESSAGEполя, зокрема. Я з’ясував, що вам також можуть знадобитися USER_INVOCATION_ID, а також деякі повідомлення не мають приєднаного до них ідентифікатора виклику, тому неможливо відфільтрувати цей механізм. Не впевнений, чому, можливо, мій
лісозапис

14

Я не впевнений, яка мітка часу має найбільше значення, але це працює для мене. Сподіваємось, є кращий спосіб роботи з мітками часу, systemctl showніж awk - не вдалося зрозуміти, як контролювати формат часових міток.

unit=foo.service

ts=$(systemctl show -p ActiveEnterTimestamp $unit)

echo $ts
ActiveEnterTimestamp=Fri 2016-11-11 12:30:01 MST

journalctl -u $unit --since "$(echo $ts | awk '{print $2 $3}')"

На всякий випадок, коли комусь це потрібно як однолінійний: journalctl --since " systemctl show -p ActiveEnterTimestamp thermo.service | awk '{print $2 \" \" $3}'" -fu thermo.service | менше
DimanNe

Ви також можете використовувати systemctl show -p ActiveEnterTimestamp --value $unit, так що немає необхідності в додаткових
розбудках

4

Ви можете використовувати прапор завантаження для отримання лише журналів із цього завантаження. наприклад

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

2
Це схоже на те, що я хочу, але воно не працює в таких ситуаціях, як: 1) якщо машина була перезавантажена з моменту останнього запуску служби, або 2) якщо служба запускалася кілька разів з моменту останнього завантаження.
Джек О'Коннор

Я не впевнений, чому це не працює для першого випадку. Якщо він був перезавантажений, заповіт також буде перезавантажений. Вам просто потрібно перейти до конкретного завантаження та отримати інформацію. Щодо другого ... ти маєш рацію. Журнали шуму залежать від кількості перезавантажених послуг. Але як тільки ви помітили службовий під, ви можете його відфільтрувати за допомогою аргументу _PID = XXX. Шанси повторного використання того ж під-сервісу для однієї і тієї ж послуги на одному циклі завантаження є ..... поняття не маю ... але, скоріше, близько до неможливого.
Ніколаїдіс Фотіс

Мені цікаво обробляти служби, які не обов'язково запускаються під час завантаження, або тому, що вони працюють на таймерах, або тому, що вони є разовими командами.
Джек О'Коннор

4

Вони можуть вам допомогти:

  • journalctl -u foo.service | хвіст -n 2

    або замініть 2 на очікувану кількість рядків

  • journalctl -u foo.service --since = ' 2016-04-11 13:00:00 '

Ви можете також комбінувати їх, щоб отримати спочатку останню часову позначку часу запуску, а потім використовувати цю мітку за допомогою перемикача --since.


Це здається, що вирішення подібне до підходу PID, але це дуже ручно. Якщо мій сервіс працює протягом багатьох секунд і виплюває багато ліній журналу, мені доведеться шукати перший рядок із початковою міткою, про яку я дбаю. Це не буде добре працювати в сценарії.
Джек О'Коннор

3

Можна використовувати фільтри поля з Journalctl. Напр

journalctl _PID=1234

Отримайте список усіх доступних полів, використовуючи:

journalctl --fields --unit kubelet

Одне доступне поле є _PID.

Ви можете отримати PID запущеного процесу, використовуючи pidofабоsystemctl show --property MainPID <SERVICE_NAME>

Ось ось як я отримую журнали з поточного процесу кубелету Kubernetes:

# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head

А тепер скажіть мені, чому мені так важко встановити Kubernetes :-(


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.