journalctlに「前回foo.serviceが実行されたとき」のログを表示させる方法はありますか?


15

タイマーで実行されるoneshotサービスの出力を確認するために、これに特に興味があります。--unitフラグが近いですが、それは一緒にサービスのすべての実行を連結します。私が考えることができる最も明白な方法は、PIDでフィルタリングすることですが、それはPIDの再利用/分岐するサービスを心配させ、最後のPIDを取得することはかなり不便です。ログのフィルタリングに使用できるサービスの単一の実行に対応する他の識別子はありますか?

編集:それが本当の答えである場合、私は喜んで信頼できる「いいえ」を受け入れます。

回答:


6

systemdversion 以降232、呼び出しIDの概念があります。ユニットが実行されるたびに、ユニットは一意の128ビットの呼び出しIDを持ちます。MainPIDどちらをリサイクルできるか、またはActiveEnterTimestamp解決に問題がある可能性があるのとは異なり、特定のsystemdユニット呼び出しのすべてのログを取得するフェイルセーフな方法です。

ユニットの最新の呼び出しIDを取得するには

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

たとえば、openipmi失敗したかどうかに関係なく、最新の呼び出しのジャーナルを取得するには、1つのライナーを使用できます

$ 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.

--valuesystemd 230、より古いから利用可能ですInvocationID


誰かがこれを調査しようとしている場合:journalctl --user -u UNITFILE -f -o json-pretty役に立つかもしれません。MESSAGE特にフィールドを探しています。必要な場合もあることがわかりました。USER_INVOCATION_IDまた、一部のメッセージには呼び出しIDが添付されていないため、このメカニズムでフィルタリングすることはできません。わからない多分私のロギングが間違って設定されている理由..
karlicoss

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ため、余分なawkは必要ありません
karlicoss

4

ブートフラグを使用して、そのブートからログのみを取得できます。例えば

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

2
これは私が望むものに似ていますが、1)サービスが最後に実行されてからマシンが再起動された場合、または2)最後のブート以降にサービスが複数回実行された場合などの状況では機能しません。
ジャックオコナー

最初のケースでなぜ機能しないのかわかりません。再起動されている場合は、再起動されます。その特定のブートに行って情報を取得するだけです。第二に関して...あなたは正しい。ノイズログは、サービスが再起動された回数に依存します。ただし、サービスpidを見つけたら、_PID = XXX引数を使用してフィルタリングできます。同じブートサイクルで同じサービスに同じpidを再利用する可能性は.....わからない...ではなく、ほぼ不可能です。
ニコライディスフォティス

タイマーを使用しているため、または1回限りのコマンドであるため、ブート時に必ずしも実行されないサービスの処理に興味があります。
ジャックオコナー

3

これらはあなたを助けるかもしれません:

  • 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

1つの使用可能なフィールドは_PIDです。

を使用して、実行中のプロセスのPIDを取得できます。 pidofまたはsystemctl show --property MainPID <SERVICE_NAME>

そこで、現在のKubernetes kubeletプロセスからログを取得する方法を次に示します。

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

Kubernetesのインストールが非常に難しい理由を教えてください:-(


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.