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.
drawrockshard
źródło

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.

Kjetil Joergensen
źródło
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.

Szalony Kapelusznik
źródło
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.

Nikolaidis Fotis
źródło
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.

użytkownik578558
źródło
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,