Journalctl günlüklerini “foo.service'in son çalıştırılmasından” yapmanın bir yolu var mı?


16

Özellikle bir zamanlayıcı üzerinde çalışan oneshot hizmetlerinin çıktısına bakmakla ilgileniyorum. --unitBayrak yakın, ama birlikte hizmetin tüm koşular birleştirir. Düşünebileceğim en belirgin yol PID'yi filtrelemek olurdu, ancak bu beni PID'nin yeniden kullanımı / bu çatal hizmetleri hakkında endişeleniyor ve son PID'yi almak oldukça rahatsız edici. Günlükleri filtrelemek için kullanabileceğim bir hizmetin tek bir çalışmasına karşılık gelen başka bir tanımlayıcı var mı?

DÜZENLEME: Eğer gerçek cevap bu ise mutlu bir "hayır" kabul ediyorum.

Yanıtlar:


8

systemdVersiyondan beri 232invokasyon kimliği kavramımız var. Bir birim her çalıştırıldığında, benzersiz bir 128 bit çağrı kimliğine sahiptir. MainPIDHangisinin geri dönüştürülebileceği veya ActiveEnterTimestamphangisinin çözünürlük sorunları olabileceğinin aksine , belirli bir sistem birimi birimi çağrısının tüm günlüğünü almanın güvenli bir yoludur.

Birimin en son çağrı kimliğini almak için

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

Diyelim ki, openipmibaşarısız olup olmadığına dair en son çağrının günlüğünü almak için tek astarı kullanabilirsiniz

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

(Not bu --valueyana mevcuttur systemd 230, daha yaşlı InvocationID)


1
Birisi bunu araştırmaya çalışıyorsa: yardımcı journalctl --user -u UNITFILE -f -o json-prettyolabilir; MESSAGEözellikle alanlar arıyorsunuz . Ayrıca ihtiyacınız olabileceğini USER_INVOCATION_IDve bazı mesajların kendilerine eklenmiş bir çağrı kimliği olmadığını öğrendim , bu yüzden bu mekanizma ile filtrelenemez. Neden emin değilim, belki benim günlük yanlış yapılandırılmış ..
karlicoss

14

Hangi zaman damgasının en anlamlı olduğunu bilmiyorum ama bu benim için çalışıyor. Umarım zaman damgalarıyla çalışmanın systemctl showawk'den daha iyi bir yolu vardır - zaman damgalarının biçimini nasıl kontrol edeceğinizi anlayamadık.

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

Birisinin bir astar olarak ihtiyacı olması durumunda: journalctl --since " systemctl show -p ActiveEnterTimestamp thermo.service | awk '{print $2 \" \" $3}'" -fu thermo.service | daha az
DimanNe

Ayrıca kullanabilirsiniz systemctl show -p ActiveEnterTimestamp --value $unit, bu yüzden ekstra awk gerekmez
karlicoss

4

Önyükleme bayrağını, yalnızca bu önyüklemedeki günlükleri almak için kullanabilirsiniz. Örneğin

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

2
Bu istediğim şeye benziyor, ancak şu gibi durumlarda işe yaramaz: 1) makine servisin son çalıştırılmasından bu yana yeniden başlatıldıysa veya 2) servis son önyüklemeden bu yana birden çok kez çalıştırıldıysa.
Jack O'Connor

İlk dava için neden işe yaramadığından emin değilim. Yeniden başlatılmışsa, o da yeniden başlatılacaktır. Bu özel önyüklemeye gitmeniz ve bilgilerinizi almanız yeterlidir. İkincisi ile ilgili ... haklısın. Gürültü günlükleri, hizmetin kaç kez yeniden başlatıldığına bağlıdır. Ancak hizmet pid'inizi belirledikten sonra _PID = XXX bağımsız değişkenini kullanarak filtreleyebilirsiniz. Aynı hizmet için aynı pideyi aynı önyükleme döngüsünde yeniden kullanma şansı ..... hiçbir fikrim yok ... ama imkansıza yakın.
Nikolaidis Fotis

Zamanlayıcıda oldukları veya bir kerelik komutlar oldukları için önyüklemede çalışması gerekmeyen hizmetleri kullanmakla ilgileniyorum.
Jack O'Connor

4

Bunlar size yardımcı olabilir:

  • journalctl -u foo.service | kuyruk -n 2

    veya 2 değerini beklenen sayıda satırla değiştirin

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

Öncelikle son çalıştırma zamanı zaman damgasını almak için birleştirebilir ve ardından bu zaman damgasını --since anahtarıyla birlikte kullanabilirsiniz.


Bu, PID yaklaşımına benzer bir geçici çözüm gibi geliyor, ancak çok manuel. Hizmetim birkaç saniye içinde çalışıyorsa ve birçok günlük satırı tükürüyorsa, önemsediğim başlangıç ​​zaman damgasına sahip ilk satırı aramam gerekiyor. Bu bir senaryoda çok işe yaramaz.
Jack O'Connor

3

Journalctl ile alan filtrelerini kullanabilirsiniz. Örneğin

journalctl _PID=1234

Kullanılabilir tüm alanların listesini aşağıdakileri kullanarak alın:

journalctl --fields --unit kubelet

Bir kullanılabilir alan _PID.

Çalışan bir işlemin PID'sini pidofveya tuşunu kullanarak alabilirsiniz.systemctl show --property MainPID <SERVICE_NAME>

Günlükleri mevcut Kubernetes kubelet işleminden nasıl alacağım:

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

Şimdi söyle neden Kubernetes'i kurmak çok zor :-(


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.