Przekształcanie pliku dziennika w rodzaj bufora cyklicznego

22

Ludzie, czy istnieje rozwiązanie * nix, które sprawiłoby, że plik dziennika działałby jak bufor cykliczny? Na przykład chciałbym, aby pliki dziennika przechowywały maksymalnie 1 GB danych i odrzucały starsze wpisy po osiągnięciu limitu.

Czy to w ogóle możliwe? Uważam, że aby to osiągnąć, plik dziennika powinien zostać przekształcony w jakieś specjalne urządzenie ...

PS Zdaję sobie sprawę z różnych narzędzi do logrotowania, ale nie tego potrzebuję. Logrotowanie wymaga wielu operacji wejścia / wyjścia, zwykle dzieje się to raz dziennie, podczas gdy potrzebuję rozwiązania „runtime”.

pachanga
źródło
3
Nie jestem pewien, dlaczego według ciebie rotacja logów wymagałaby wielu operacji wejścia / wyjścia. Obracanie 10 plików dziennika to 10 operacji zmiany nazwy i HUP usługi. Nie do końca mordercza operacja ... I to jest standardowe rozwiązanie twojego problemu :)
Pehrs
2
Można uruchomić skrypt / plik wykonywalny, który nie działa dobrze z HUP.
Scott,
1
Ma to na celu zapewnienie kolejnego przypadku użycia pytania. Mam demonizowany odtwarzacz muzyki. Chcę dziennik długości tylko kilku linii, aby móc zobaczyć, co gra i co grało wcześniej. tail -f somefileZrobiłby tego. Właśnie próbowałem z obróconymi dziennikami i tail -fnie działa z nimi.
Vorac,

Odpowiedzi:

14

Linux ma bufor pierścieniowy jądra. Możesz go użyć dmesgdo wyświetlenia .

Lub tutaj jest moduł jądra Linuksa, który wydaje się robić to, co chcesz.

Co to jest emlog?

emlog to moduł jądra systemu Linux, który ułatwia dostęp do najnowszych (i tylko najnowszych) danych wyjściowych z procesu. Działa podobnie jak „tail -f” w pliku dziennika, z tym wyjątkiem, że wymagana pamięć nigdy nie rośnie. Może to być przydatne w systemach osadzonych, w których nie ma wystarczającej ilości pamięci lub miejsca na dysku do przechowywania pełnych plików dziennika, ale czasem są potrzebne najnowsze komunikaty debugowania (np. Po zaobserwowaniu błędu).

Moduł jądra emlog implementuje prosty sterownik urządzenia znakowego. Sterownik działa jak nazwany potok, który ma skończony, okrągły bufor. Rozmiar bufora można łatwo skonfigurować. W miarę zapisywania większej ilości danych w buforze najstarsze dane są odrzucane. Proces, który czyta z urządzenia emlog, najpierw przeczyta istniejący bufor, a następnie zobaczy nowy tekst podczas pisania, podobnie jak monitorowanie pliku dziennika za pomocą „tail -f”. (Odczyty nieblokujące są również obsługiwane, jeśli proces musi uzyskać bieżącą zawartość dziennika bez blokowania w celu oczekiwania na nowe dane).

Wstrzymano do odwołania.
źródło
1
Dzięki za link! BTW, strona główna emlog zawiera link do ulogbufd, co jest prawdopodobnie dla mnie jeszcze bardziej odpowiednim rozwiązaniem.
pachanga
Emlog jądro moduł jest teraz utrzymywana na github: github.com/nicupavel/emlog
dbernard
4

Najbliższa rzecz, o której mogę myśleć, to RRDTools, ale prawdopodobnie nie jest to, czego szukasz. Innym rozwiązaniem byłoby monitorowanie pliku dziennika (powiedz co sekundę lub w systemie Linux z inotify), np. Piszesz skrypt taki jak:

while :; do
  if [[ $(stat -c %s $FILE) -gt 10000 ]]; then
    # rotate the log
  fi
  sleep 1
done

z inotify:

while :; do
  if inotifywait [some options] $FILE; then
    # check size and rotate the file
  fi
done
Dan Andreatta
źródło
+1 za wzmiankę o RRDtool, prawdziwym przykładzie rejestrowania struktury danych pierścienia.
Cory J
Dzięki, na przykład, za pokazanie użycia polecenia powłoki inotifywait
pachanga
4

Można użyć multilog z daemontools DJB za. Pipujesz do niego dane wyjściowe z dziennika . Tak, to rotacja logów, ale rotacje to po prostu:

ln current $tai64nlocaltimestamp

Co w prawie każdym nowoczesnym systemie plików linux jest super szybką operacją. Możesz określić, ile chcesz plików dziennika, jak duże chcesz. zrób 10 x 1024mb plików, a będziesz miał swój bufor 1GB.

Zauważ, że z powodu automatycznego obracania jest to jedno źródło na instancję multiloga. Możesz jednak obejść ten problem, pisząc proste opakowanie za pomocą netcata lub ręcznie.

Jason
źródło
Dzięki za wskazówkę! Na pewno też będę miał multilog.
pachanga
1

Możesz utworzyć potok FIFO, a następnie odczytać go za pomocą skryptu wstawionego do bazy danych. Gdy licznik osiągnie 1000, zrestartuj numer identyfikacyjny wstawiany do bazy danych. Oczywiście nie działałoby to dla wielkości, ale wykorzystałeś to jako przykład, więc zakładam, że jest to pytanie teoretyczne.

grzeszący
źródło
1

Interesujące pytanie; zwykle nie widzisz tego jako projektu. Mam program, który używa nieco podobnej techniki do zapisywania historii, ale używa formatu binarnego. „Plik dziennika” składa się z czterech części, wszystkie ułożone w formacie niezależnym od maszyny:

  1. Nagłówek zawierający magiczną liczbę i (maksymalną) liczbę wpisów na używanej liście i liście wolnej, numer sekwencyjny następnego wpisu historii, faktyczna liczba wpisów na liście używanych, rzeczywista liczba wpisów na liście swobodnej oraz długość pliku (z których każdy ma 4 bajty).
  2. Użyta lista, każda pozycja podaje przesunięcie i długość (4 bajty dla każdej części każdej pozycji).
  3. Darmowa lista, każda pozycja podobna do używanej pozycji listy.
  4. Główne dane, każdy rekord historii składający się z ciągłego zestawu bajtów zakończonych bajtem z zerowym terminatorem.

Przydzielenie nowego rekordu, jeśli na wolnej liście jest miejsce, oznacza to, że nadpisuje tam wpis (niekoniecznie wykorzystując wszystko - w takim przypadku fragment pozostaje na wolnej liście). Jeśli na liście wolnych nie ma miejsca, na końcu przydzielane jest nowe miejsce. Kiedy stary rekord się obraca, jego miejsce jest przenoszone do wolnej listy i łączone z dowolnymi sąsiednimi wolnymi rekordami. Jest przeznaczony do obsługi instrukcji SQL, dzięki czemu rekordy można rozłożyć na wiele wierszy. Ten kod działa na określonej liczbie rekordów. Nie ogranicza rozmiaru pliku jako takiego (choć nie byłoby to trudne).

Główny kod historii kodu znajduje się w dwóch plikach, history.c i history.h, dostępnych ze źródła dla programu SQLCMD (moja wersja, nie Microsoft; moja istniała dziesięć lat lub dłużej przed Microsoft), którą można pobrać z archiwum oprogramowania International Informix User Group . Istnieje również program zrzutu pliku historii (histdump.c) i tester historii (histtest.ec - twierdzi, że jest to ESQL / C, ale sam w sobie jest kodem C; jedna z funkcji pomocniczych, które wywołuje, używa niektórych Informix ESQL / C funkcje biblioteki). Skontaktuj się ze mną, jeśli chcesz eksperymentować bez używania Informix ESQL / C - zobacz mój profil. Istnieją pewne trywialne zmiany, aby kompilować histstest poza środowiskiem projektowym, a ponadto potrzebujesz makefile.

Jonathan Leffler
źródło
0

Zgadzam się z komentarzem pehrsa do twojego pytania. Rotacja kłód nie jest taka trudna. Możesz skonfigurować program logrotate lub inny skrypt, aby okresowo sprawdzał plik dziennika, nawet tak często, jak co minutę, jeśli chcesz. Gdy wykryje, że Twój plik osiąga rozmiar 1 GB, po prostu wykonuje zmianę nazwy, która nie ma prawie żadnego wejścia / wyjścia. Podczas zmiany nazwy proces kontynuuje zapisywanie pliku dziennika. Rotator dziennika można następnie wysłać HUP do demona syslog (demon jest zalogowaniu przez syslog, prawda? Jeśli nie, należy go obsługiwać sygnał HUP, czy to dobrze napisane ...), aby go ponownie otworzyć oryginalną ścieżkę . W tym momencie rozpocznie zapisywanie do nowego pliku na oryginalnej ścieżce i możesz usunąć obróconą wersję.

Kamil Kisiel
źródło