Logrotate Pomyślny, oryginalny plik powraca do oryginalnego rozmiaru


11

Czy ktoś miał jakieś problemy z Logrotate, które spowodowały obrót pliku dziennika, a następnie powrót do tego samego rozmiaru, w jakim był pierwotnie? Oto moje ustalenia:

Skrypt Logrotate:

/var/log/mylogfile.log {
    obróć 7
    codziennie
    Kompresja
    olddir / log_archives
    missingok
    notifempty
    copytruncate
}

Pełne wyjście z Logrotate:

kopiowanie /var/log/mylogfile.log do /log_archives/mylogfile.log.1
obcinanie /var/log/mylogfile.log
kompresowanie dziennika za pomocą: / bin / gzip
usuwanie starego dziennika /log_archives/mylogfile.log.8.gz

Plik dziennika po obcięciu

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 część 1 część 1 0 11 stycznia 17:32 /var/log/mylogfile.log

Dosłownie kilka sekund później:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 part1 part1 3.5G 11 stycznia 17:32 /var/log/mylogfile.log

Wersja RHEL:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES wydanie 4 (Nahant Update 4)

Wersja Logrotate:

[root @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

Kilka uwag:

  • Usługi nie można ponownie uruchomić w locie, dlatego używam copytruncate
  • Dzienniki obracają się każdej nocy, zgodnie z olddirkatalogiem, w którym znajdują się pliki dzienników z każdej nocy.

Odpowiedzi:


18

Jest to prawdopodobnie spowodowane tym, że nawet jeśli plik zostanie obcięty, proces zapisywania do pliku będzie kontynuował zapisywanie w dowolnym momencie przesunięcia. Więc dzieje się tak, że logrotate obcina plik, rozmiar wynosi zero, proces ponownie zapisuje do pliku, kontynuując z przesuniętą przerwą, a teraz masz plik z bajtami NULL aż do momentu, w którym go obcięto plus nowy wpisy zapisane w dzienniku.

od -c po obcinaniu + nagłym wzroście, generowana produkcja według linii:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

To oznacza, że ​​od przesunięcia 0 do 33255657600 plik składa się z bajtów zerowych, a następnie czytelnych danych. Osiągnięcie tego stanu nie zajmuje tyle samo czasu, ile zajęłoby napisanie wszystkich tych bajtów zerowych. Systemy plików ext {2,3,4} obsługują coś, co nazywa się plikami rzadkimi, więc jeśli przeszukujesz region pliku, który niczego nie zawiera, zakłada się, że region ten zawiera puste bajty i nie zajmie miejsca na dysku. Te bajty zerowe w rzeczywistości nie zostaną zapisane, po prostu zakładają, że tam są, dlatego czas potrzebny na przejście od 0 do 3,5 GB nie zajmuje dużo czasu. (Możesz przetestować czas potrzebny do zrobienia czegoś takiego: dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1powinno to wygenerować plik ponad 3 GB w ciągu kilku milisekund).

Jeśli uruchomisz ls -lspliki dziennika po ich obcięciu i nagłym wzroście, powinien teraz zgłosić liczbę na początku wiersza reprezentującą rzeczywisty rozmiar (w blokach zajmowanych na dysku), który prawdopodobnie jest rzędem wielkości mniejszy niż rozmiar zgłoszony przez just ls -l.


Nie sądzę - w ciągu kilku sekund plik dziennika zmienia się z 0 bajtów na 3,5 GB. Całkowity czas potrzebny do ukończenia programu Logrotate wynosi około 5 minut. Pliki dziennika nie są zapisywane tak szybko ORAZ rozmiar jest zawsze pierwotny, co wydaje się zbyt przypadkowe.
drewrockshard 12.01.11

Powinien istnieć łatwy sposób na sprawdzenie tego, sprawdzenie pliku i sprawdzenie, czy coś w nim jest. Zacznij od uruchomienia od -c nazwa_pliku | head -n 100. Możliwe, że w kilku wierszach powie Ci, że jest mnóstwo pustych bajtów plus najnowsze wpisy do dziennika.
Kjetil Joergensen

Jeśli tak jest, to czy możemy przetestować, czy cat / dev / null> /var/log/mylogfile.log obcina plik w sposób, który rozwiązuje ten problem, zamiast używać logrotate wbudowanego w copytruncate?
mtinberg,

2
Problem nie dotyczy sposobu, w jaki plik jest obcinany, problem polega na tym, jak program zapisuje plik dziennika. Aby obcinanie pliku dziennika było realnym podejściem, musisz zmusić program do zapisywania pliku dziennika w jakiś sposób do pozycji 0. Możliwe jest, że system plików, który nie obsługuje plików rzadkich, nie miałby tej proble, chociaż nie nie ma w tej chwili możliwości przetestowania tego.
Kjetil Joergensen,

1
Ta ostateczna odpowiedź rzeczywiście miała większy sens, a poprawka prawdopodobnie zakończy się ponownie uruchomieniem aplikacji.
drewrockshard 12.01.11

2

Jestem bardzo pewien, że Kjetil go trafił. Drew, może jeszcze nie przekonuje cię jego wyjaśnienie, ale zachęcam do uważnego przeczytania tego, co powiedział.

Jeśli ją zaakceptujesz, rozwiązaniem może być zatrzymanie i ponowne uruchomienie aplikacji po obróceniu dzienników lub użycie narzędzia takiego jak „rotatelogi” Apache, w którym dane wyjściowe dziennika są podawane do narzędzia za pomocą rury, a narzędzie zajmuje się co jakiś czas obracając plik dziennika. Na przykład jeden z moich dzienników instancji apache z

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

co powoduje wiele plików dziennika o nazwach takich jak

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

pojawiać się bez restartowania apache; Następnie mogę skompresować je ręcznie po fakcie. Zwróć uwagę, w jaki sposób rotacja odbywa się co tydzień, czyli co 604800 sekund, do którego przekazywany jest argument rotatelogs.

Jeśli nie możesz zatrzymać i zrestartować aplikacji i nie można zalogować się za pomocą potoku, to myślę, że masz prawdziwy problem. Być może inni będą mieli sugestie.


0

byłoby naprawdę wspaniale, gdybyś mógł wysłać cały logrotate.

Po co próbować używać kill -HUP? Metoda (klasyczne ponowne ładowanie nie restartuje się ).

Również ... sprawdź, lsof kto ma dostęp do pliku.


Nie można używać, kill -HUPponieważ tej aplikacji nie można w żaden sposób dotknąć - jest to wrażliwa aplikacja, której nie posiadam (nawet jej nie zarządzam - zarządzam tylko stroną systemu operacyjnego), więc muszę mieć możliwość przeprowadzania logrotacji tego droga.
drewrockshard 12.01.11

1
Przepraszam, oryginalna wiadomość została przesłana wcześnie, oto pozostała część mojej oryginalnej wiadomości: zalogowałem się dziś rano do systemu, a plik został przywrócony do normy po /etc/cron.dailyzainicjowaniu zaplanowanego programu logrotate . Pytanie do wszystkich: Czy jest coś, co skrypt logrotate robi inaczej niż ręczne uruchamianie logrotate? Mój skrypt logrotate wygląda dosłownie /usr/sbin/logrotate /etc/logrotate.conf. To dość zaskakujące.
drewrockshard 12.01.11

-1

Wystarczy użyć „>>”, co oznacza dopisanie zamiast „>”, co oznacza tworzenie ze skryptów zapisujących w tym pliku. Miałem dokładnie ten sam problem i naprawiłem go za pomocą append w moim skrypcie.

SomeScript.sh >> output.txt

Nadzieja, która jest wyraźniejsza.


Nic nie wskazuje na to, że zapis do pliku dziennika odbywa się przy użyciu >skryptu. Co więcej, ta odpowiedź jest myląca, ponieważ istnieje duża różnica między skryptami >i pomiędzy nimi >( ). Na koniec, jeśli kod piszący zostanie zaktualizowany, byłoby znacznie lepiej, gdyby po prostu zaczął pisać do nowego pliku dziennika po logrotatewykonaniu tej czynności.
kasperd

Edytuję swoją odpowiedź, aby była bardziej przejrzysta.
user578558,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.