Jak odróżnić awarię od ponownego uruchomienia na RHEL7?

10

Czy istnieje sposób ustalenia, czy serwer RHEL7 został ponownie uruchomiony za pomocą systemctl (lub aliasów restartu / zamknięcia), czy też serwer się zawiesił? Wstępnie zaprogramowane było to dość łatwe do ustalenia last -x runlevel, ale z RHEL7 nie jest to takie jasne.

kwb
źródło

Odpowiedzi:

4

Jest na to więcej niż jeden sposób, ale omówię 4 najlepsze, jakie mogę wymyślić. (EDYCJA: Opublikowałem oczyszczoną wersję tego jako publiczny artykuł na redhat.com. Zobacz: Jak odróżnić awarię od płynnego restartu w RHEL 7 ).

(1) zrewidowane dzienniki

Audyt jest niesamowity. Możesz sprawdzić wszystkie różne zdarzenia, które rejestruje, sprawdzając ausearch -m. Oprócz tego problemu rejestruje zamknięcie systemu i uruchomienie systemu, dzięki czemu można użyć polecenia ausearch -i -m system_boot,system_shutdown | tail -4. Jeśli zgłasza to SYSTEM_SHUTDOWN, a następnie SYSTEM_BOOT , wszystko jest w porządku; jeśli jednak zgłasza 2 wiersze SYSTEM_BOOT z rzędu, to najwyraźniej system nie zamknął się płynnie, jak w poniższym przykładzie:

[root@a72 ~]# ausearch -i -m system_boot,system_shutdown | tail -4
----
type=SYSTEM_BOOT msg=audit(09/20/2016 01:10:32.392:7) : pid=657 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg=' comm=systemd-update-utmp exe=/usr/lib/systemd/systemd-update-utmp hostname=? addr=? terminal=? res=success' 
----
type=SYSTEM_BOOT msg=audit(09/20/2016 01:11:41.134:7) : pid=656 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg=' comm=systemd-update-utmp exe=/usr/lib/systemd/systemd-update-utmp hostname=? addr=? terminal=? res=success' 

(2) ostatnie -x

Tak jak powyżej, ale za pomocą prostego last -n2 -x shutdown rebootpolecenia. Przykład awarii systemu:

[root@a72 ~]# last -n2 -x shutdown reboot
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:11 - 01:20  (00:08)    
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:10 - 01:20  (00:09)    

Lub gdzie system miał wdzięczny restart:

[root@a72 ~]# last -n2 -x shutdown reboot
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:21 - 01:21  (00:00)    
shutdown system down  3.10.0-327.el7.x Tue Sep 20 01:21 - 01:21  (00:00)    

(3) utwórz własną jednostkę serwisową

Jest to najlepsze podejście IMHO, ponieważ możesz je dostosować do wszystkiego, co chcesz. Jest na to milion sposobów. Oto jeden, który właśnie wymyśliłem. Ta następna usługa działa tylko przy wyłączaniu.

[root@a72 ~]# cat /etc/systemd/system/set_gracefulshutdown.service
[Unit]
Description=Set flag for graceful shutdown
DefaultDependencies=no
RefuseManualStart=true
Before=shutdown.target

[Service]
Type=oneshot
ExecStart=/bin/touch /root/graceful_shutdown

[Install]
WantedBy=shutdown.target
[root@a72 ~]# systemctl enable set_gracefulshutdown.service 
Created symlink from /etc/systemd/system/shutdown.target.wants/set_gracefulshutdown.service to /etc/systemd/system/set_gracefulshutdown.service.

Następnie, gdy system zostanie uruchomiony, następna usługa uruchomi się tylko wtedy, gdy istnieje plik utworzony przez powyższą usługę zamykania.

[root@a72 ~]# cat /etc/systemd/system/check_graceful.service 
[Unit]
Description=Check if system booted after a graceful shutdown
ConditionPathExists=/root/graceful_shutdown
RefuseManualStart=true
RefuseManualStop=true

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/rm /root/graceful_shutdown

[Install]
WantedBy=multi-user.target
[root@a72 ~]# systemctl enable check_graceful
Created symlink from /etc/systemd/system/multi-user.target.wants/check_graceful.service to /etc/systemd/system/check_graceful.service.

Więc w dowolnym momencie mogę sprawdzić, czy poprzednie uruchomienie zostało wykonane po płynnym wyłączeniu, wykonując systemctl is-active check_gracefulnp .:

[root@a72 ~]# systemctl is-active check_graceful && echo YAY || echo OH NOES
active
YAY
[root@a72 ~]# systemctl status check_graceful
● check_graceful.service - Check if system booted after a graceful shutdown
   Loaded: loaded (/etc/systemd/system/check_graceful.service; enabled; vendor preset: disabled)
   Active: active (exited) since Tue 2016-09-20 01:10:32 EDT; 20s ago
  Process: 669 ExecStart=/bin/rm /root/graceful_shutdown (code=exited, status=0/SUCCESS)
 Main PID: 669 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/check_graceful.service

Sep 20 01:10:32 a72.example.com systemd[1]: Starting Check if system booted after a graceful shutdown...
Sep 20 01:10:32 a72.example.com systemd[1]: Started Check if system booted after a graceful shutdown.

Albo oto po niecodziennym zamknięciu:

[root@a72 ~]# systemctl is-active check_graceful && echo YAY || echo OH NOES
inactive
OH NOES
[root@a72 ~]# systemctl status check_graceful
● check_graceful.service - Check if system booted after a graceful shutdown
   Loaded: loaded (/etc/systemd/system/check_graceful.service; enabled; vendor preset: disabled)
   Active: inactive (dead)
Condition: start condition failed at Tue 2016-09-20 01:11:41 EDT; 16s ago
           ConditionPathExists=/root/graceful_shutdown was not met

Sep 20 01:11:41 a72.example.com systemd[1]: Started Check if system booted after a graceful shutdown.

(4) dziennik

Warto wspomnieć, że jeśli skonfigurujesz systemd-journaldutrzymywanie trwałego dziennika, możesz następnie użyć, journalctl -b -1 -naby spojrzeć na kilka ostatnich (10 domyślnie) wierszy poprzedniego rozruchu ( -b -2jest to rozruch itp.). Przykład, w którym system uruchomił się z wdziękiem:

[root@a72 ~]# mkdir /var/log/journal
[root@a72 ~]# systemctl -s SIGUSR1 kill systemd-journald
[root@a72 ~]# reboot
...
[root@a72 ~]# journalctl -b -1 -n
-- Logs begin at Tue 2016-09-20 01:01:15 EDT, end at Tue 2016-09-20 01:21:33 EDT. --
Sep 20 01:21:19 a72.example.com systemd[1]: Stopped Create Static Device Nodes in /dev.
Sep 20 01:21:19 a72.example.com systemd[1]: Stopping Create Static Device Nodes in /dev...
Sep 20 01:21:19 a72.example.com systemd[1]: Reached target Shutdown.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Shutdown.
Sep 20 01:21:19 a72.example.com systemd[1]: Reached target Final Step.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Final Step.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Reboot...
Sep 20 01:21:19 a72.example.com systemd[1]: Shutting down.
Sep 20 01:21:19 a72.example.com systemd-shutdown[1]: Sending SIGTERM to remaining processes...
Sep 20 01:21:19 a72.example.com systemd-journal[483]: Journal stopped

Jeśli uzyskasz dobrą wydajność, system najwyraźniej został zamknięty z wdziękiem. To powiedziawszy, z mojego doświadczenia nie jest zbyt niezawodne, gdy zdarzają się złe rzeczy (awaria systemu). Czasami indeksowanie staje się dziwne.

rsaw
źródło
8

Zabawne, właśnie zdarzyło mi się zrestartować system CentOS 7 zeszłej nocy, więc mam fajny dziennik tego do obejrzenia.

W przypadku awarii najwyraźniej nic nie jest rejestrowane między czasem awarii a ponownym uruchomieniem systemu.

W przypadku restartu jest to dość oczywiste, ponieważ otrzymujesz dziennik (prawie) wszystkiego, co systemd robi, aby zamknąć system.

Jednym z takich wpisów w dzienniku, których prawdopodobnie nie zobaczysz, poza zamknięciem lub przejściem do trybu jednego użytkownika jest:

Jul 13 01:27:55 yaungol systemd: Stopped target Multi-User System.

Możesz zrestartować własny system, aby zobaczyć, co faktycznie zostanie zarejestrowane.

Michael Hampton
źródło
1
Czy uwierzysz, że CentOS 7 rejestruje to, a RHEL 7 nie? Takie było nasze początkowe podejście oparte na tym, co widzieliśmy w logach CentOS (i Fedory). Kiedy testowaliśmy na RHEL7, brak kości.
kwb
1
@kwb Po przyjrzeniu się systemowi RHEL 7.2 tak, wierzę w to. W rzeczywistości wydaje się, że wiele rzeczy, które powinny być rejestrowane, nie są rejestrowane. Mogę tylko powiedzieć: WTF?
Michael Hampton
Nie jestem pewien, o czym mówicie. systemd w RHEL 7.0-7.2 generuje komunikaty Stopping Multi-User Systemi Stopped target Multi-User System.
rsaw
@rsaw Jesteśmy świadomi, że wiadomości są generowane. Problem polega na tym, że nie pojawiają się w czasopiśmie.
Michael Hampton,
@MichaelHampton dziennik nie jest domyślnie trwały. Można zobaczyć tylko logi z bieżącego rozruchu, chyba że mkdir /var/log/journalalbo jawnie ustawić Storage=persistentw /etc/systemd/journald.conf. Opublikowałem osobną odpowiedź.
rsaw
5

Nie podoba mi się szczególnie odpowiedź, ale jest to odpowiedź, którą otrzymaliśmy od RH. Zamieszczam go tutaj na wypadek, gdyby pomógł komuś innemu.

Jednym z możliwych sposobów jest grep dla rsyslogdw /var/log/messages. Byłoby pełne wdzięku wyłączenie exiting on signal 15. Awaria nie.

tac /var/log/messages | grep 'rsyslogd.*start\|rsyslogd.*exit'

Dwie kolejne startlinie mogą oznaczać awarię. A startpo nim exitmoże oznaczać ponowne uruchomienie.

Niestety może również dać złe wyniki, jeśli rsyslogd ulegnie awarii lub zostanie zrestartowany poza restartem / awarią.

kwb
źródło
Zła gra w Red Hat. Istnieją inne zachowania, które spowodują to samo exiting on signal 15oprócz ponownego uruchomienia. Normalny service rsyslog restartpowoduje również wyświetlenie exiting on signal 15komunikatu.
Stefan Lasiewski
To prawidłowa odpowiedź, ale jako ktoś, kto pracuje w dziale wsparcia technicznego Red Hat, to nie jest to, z czym bym poszedł. Zobacz moją odpowiedź.
rsaw
1

To wydaje się działać konsekwentnie do wdzięcznych „postojów” ( shutdown, reboot, systemctl) jak również „wypadków” (wyłączenia zasilania, reset echo c > /proc/sysrq-trigger):

last -x | grep 'reboot\|shutdown'

rebootLinia następuje shutdownlinii sygnalizuje wyłączenie „wdzięku”. Dwie rebootlinie oznaczają „awarię”.

kwb
źródło