Jak kontynuować przekierowywanie standardowego pliku do pliku po przeniesieniu go przez Logrotate?

22

Mam prosty skrypt, który wyświetla kilka dzienników na ekranie, i przesłałem STDOUT do pliku w celu przechowywania dzienników. Ponieważ ten skrypt działa od dawna, musiałem obracać pliki dziennika, aby były one podzielone na mniejsze, łatwiejsze do zarządzania.

Problem, z którym się spotkałem, polegał na tym, że po logrotateprzeniesieniu bieżącego pliku dziennika do nowego, nowo utworzony plik dziennika nie jest już zapełniany dziennikami. Wygląda na to, że po usunięciu oryginalnego pliku dziennika jego program obsługi plików zostanie utracony, a przekierowanie nie będzie działać.

Znalazłem również ten post, który miał ten sam problem co ja i twierdzi, że można go naprawić, używając >>zamiast >przekierować wyjście. Przetestowałem jego rozwiązanie, ale nie zadziałało. Czy ktoś ma pomysł, jak utrzymać przekierowanie?

Mehran
źródło
4
Nadal zalecam, w twoim przypadku, użycie „>>” zamiast „>”, jeśli zamierzasz napisać do pliku obciętego: gdy „>>” otworzy się w trybie dołączania, będzie szukał do końca pliku za każdym razem, gdy pisze. W ten sposób, po obcięciu pliku (powodując, że przechodzi on z XXXX bajtów do 0 bajtów), będzie „szukał do końca”, więc będzie wiedział, że teraz musi pisać po bajcie 0. W przeciwnym razie może pisać po bajcie XXXX, a zatem utwórz rzadki plik z XXXX pustymi bajtami przed nim (tzn. kiedy „>”, fd może po prostu zapamiętać, gdzie był w tym pliku i pisać stamtąd, nie zdając sobie sprawy ze zmniejszonego rozmiaru pliku!)
Olivier Dulac

Odpowiedzi:

25

Należy użyć dyrektywy copytruncate w konfiguracji logrotate dla tego pliku dziennika.

copytruncate Obetnij oryginalny plik dziennika po utworzeniu kopii, zamiast przenosić stary plik dziennika i opcjonalnie utworzyć nowy. Można go użyć, gdy nie można nakazać programowi, aby zamknął swój plik dziennika, a zatem może kontynuować zapisywanie (dołączanie) do poprzedniego pliku dziennika na zawsze. Zauważ, że pomiędzy kopiowaniem pliku a obcięciem jest bardzo krótki przedział czasu, więc niektóre dane rejestrowania mogą zostać utracone. Gdy ta opcja jest używana, opcja tworzenia nie przyniesie żadnego efektu, ponieważ stary plik dziennika pozostaje na swoim miejscu

user9517 obsługuje GoFundMonica
źródło
2
Warto wspomnieć: przez krótki czas, przed compressoperacją, dane są duplikowane. To raz sprawiło nam problem, ale to było nasze złe, ponieważ nie powinniśmy być tak blisko lvlimitu przestrzeni. Ponadto, jak stwierdzono we manfragmencie, możesz stracić niektóre dane dziennika między operacjami kopiowania i obcinania.
Belmin Fernandez
6

Alternatywnie możesz również:

  • użyj narzędzia rejestrującego w skrypcie zamiast potokowania, z dedykowanym narzędziem (np. local5), na przykład:

    logger -p local5.info -t myscriptname "this is some log data"

  • skonfiguruj syslog, aby zapisywał tę funkcję w pożądanym pliku dziennika, przykład (rsyslog.conf):

    local5.* /var/log/mylogfile

  • ustaw regułę logrotate dla tego dziennika.

tonioc
źródło
Działa to tylko wtedy, gdy masz jawne polecenia wyjściowe, takie jak echo. Dane wyjściowe narzędzi innych firm, które są wywoływane ze skryptu, a także wypisują coś, nie mogą być w ten sposób przekierowane do rejestratora
Daniel Alder
4

Inną alternatywą dla rozwiązania Iain jest użycie postrotateskryptu do ponownego uruchomienia skryptu po zakończeniu rotacji. Odbywa się to dla wielu demonów (zrestartuj lub ponownie załaduj demona), ale nie znając twojego skryptu Nie wiem, czy to rozwiązanie ci się spodoba, czy nie (czy twój skrypt zależy od jakiegoś stanu wygenerowanego jakiś czas temu?).

Zawartość /etc/logrotate.d/your-script-name:

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}
Carlos Campderrós
źródło
0

Możesz potokować stdout do „split” (część coreutils w Linuksie). Umożliwia dzielenie pliku / standardowego pliku na kawałki na podstawie rozmiaru, liczby linii itp. Gdy już zostanie podzielony na fragmenty, możesz w razie potrzeby zarządzać nim za pomocą programu logrotate.

Nazar
źródło