Usuń pierwsze N ​​wierszy z aktywnego pliku dziennika

26

Czy istnieje sposób na usunięcie pierwszych Nwierszy z dziennika, który jest aktywnie dołączany przez aplikację?

Adam Matan
źródło

Odpowiedzi:

10

Nie, systemy operacyjne takie jak Linux i jego systemy plików nie przewidują usuwania danych z początku pliku. Innymi słowy, punkt początkowy przechowywania pliku jest ustalony.

Usuwanie wierszy z początku pliku jest zwykle realizowane przez zapisanie pozostałych danych w nowym pliku i usunięcie starego. Jeśli program ma stary plik otwarty do zapisu, usunięcie tego pliku jest odraczane do momentu zamknięcia pliku przez aplikację.


Jak zauważyli komentatorzy, z powodów podanych w poprzednim zdaniu zazwyczaj musisz koordynować czyszczenie plików dziennika z programami, które zapisują dzienniki. Dokładnie jak to zrobisz, zależy od programów. Niektóre programy zamykają i ponownie otwierają swoje pliki dziennika, gdy wyślesz im sygnał (np. HUP), co może być użyte, aby zapobiec zapisywaniu zapisów dziennika w „usuniętym” pliku dziennika, bez zakłócania usługi.

Istnieje wiele narzędzi do zarządzania rozmiarem plików dziennika, na przykład logrotate

Niektóre programy mają własne narzędzia. Na przykład serwer Apache zawiera narzędzie rotatelogs .

RedGrittyBrick
źródło
3
Ale nie powinieneś tego robić, dopóki coś jest nadal otwarte i nadal się do niego dołącza, ponieważ zapisałoby to w teraz usuniętym pliku i straciłbyś te wiadomości z dziennika.
Tarnay Kálmán
Prawdziwe. Nawet jeśli użyłeś tej samej nazwy pliku.
Hennes,
szkoda, że ​​systemy operacyjne nie pozwalają, na pewno byłoby to wygodne dla rotaterów logów, aby nie musieli ponownie ładować procesów po rotacji: |
rogerdpack,
25

Myślę, że to zadanie można osiągnąć sed

sed -i '1,10d' myfile

usunie linie od 1 st do 10 th postaci linii pliku.

Myślę, że każdy powinien przynajmniej rzucić okiem na te wkładki sed 1 .

Pamiętaj, że nie działa to w przypadku plików dziennika, do których aplikacja jest aktywnie dołączana (jak podano w pytaniu).

sed -iutworzy nowy plik i „usunie” zapisywany plik. Większość aplikacji będzie nadal zapisywać zapisy dziennika w usuniętym pliku dziennika i będzie nadal wypełniać miejsce na dysku. Nowy, obcięty plik dziennika nie zostanie dołączony. Spowoduje to ustanie dopiero po ponownym uruchomieniu aplikacji lub w inny sposób zostanie zasygnalizowane zamknięcie i ponowne otwarcie plików dziennika. W tym momencie w nowym pliku dziennika pojawi się luka (brakujące zapisy dziennika), jeśli między użyciem sed a restartem aplikacji wystąpi jakakolwiek rejestrowalna aktywność.

Bezpiecznym sposobem na to byłoby zatrzymanie aplikacji, użycie sed do obcięcia dziennika, a następnie ponowne uruchomienie aplikacji. Takie podejście może być nieakceptowalne w przypadku niektórych usług (np. Serwer WWW o wysokiej przepustowości i wysokich wymaganiach dotyczących ciągłości usług)

IZard
źródło
2
Czy wiesz, co dzieje się z dołączanymi aplikacjami?
Adam Matan
1
Załóżmy normalną otwartą procedurę obsługi plików, która od czasu do czasu dołącza linie i opróżnia.
Adam Matan
1
Wiem, jak sobie radzić z sedem, a wyodrębnianie wierszy do nowego pliku nie wymaga myślenia z sed. Problem polega na tym, aby utrzymać to wszystko w tym samym pliku.
Adam Matan
10
Nie, to nie powinno działać. sed -itworzy nowy plik z edytowaną treścią, a stary jest usuwany, więc nie edytujesz aktywnego pliku: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Sprawdź, jak sed -idziała. Dlaczego ta zła odpowiedź ma tak wiele pozytywnych opinii?
pabouk
1
Pytanie brzmi „z dziennika, który jest aktywnie dołączany przez aplikację”. Słowo operacyjne brzmi „aktywnie”. Być może to wyjaśnienie zostało dodane po pojawieniu się twojej odpowiedzi. Ale w tej chwili czytelnicy, którzy skłaniają się ku „najbardziej pozytywnym opiniom”, będą wprowadzani w błąd. Mogłem głosować tylko raz.
Scott Prive
5

Nie. Rozwiązaniem tego ogólnego problemu wzrostu pliku dziennika jest rotacja dziennika. Obejmuje to regularne (zwykle co tydzień lub co tydzień) przenoszenie istniejącego pliku dziennika do innej nazwy pliku i rozpoczynanie od nowa z pustym plikiem dziennika. Po pewnym czasie stare pliki dziennika są wyrzucane.

Zobacz: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm

Tarnay Kálmán
źródło
2

To jest odpowiedź , a nie rozwiązanie. Nie ma rozwiązania tego pytania. Pytający wyraźnie stwierdza: „z dziennika, który jest aktywnie dołączany przez aplikację”. Możesz przeczytać dalej, aby zrozumieć więcej, i przejść do końca, aby uzyskać sugestię na podstawie mojego domniemania, dlaczego ten kod nie przestrzega najlepszych praktyk w zakresie rejestrowania.

Żeby było jasne: inne „odpowiedzi” tutaj oferują fałszywą obietnicę . Żadna zmiana nazwy nie zmusi aplikacji do korzystania z nowego pliku. Najbardziej przydatne informacje są ukryte w komentarzach do tych nieprawidłowych odpowiedzi.

Pliki AKTYWNE nie są rodzajem kontenera, w którym po prostu umieszczasz dane. Nazwa pliku wskazuje JEDEN i-węzeł (początek pliku), a każdy i-węzeł ma wskaźnik do innego i-węzła (jeśli jest więcej danych). Oznacza to, że ciągły zapis do pliku zawiera ciągły strumień i-węzłów, a to, co myślisz o „pliku”, jest w rzeczywistości sekwencją logów i-węzłów.

Wyobraź sobie, że śledzisz kogoś w Mapach Google, a ta osoba może się teleportować w dowolnym miejscu na świecie, w dowolnym momencie, i próbujesz połączyć te kropki.

Narzędzie „obcinaj” w systemie Linux może odrzucić dane na końcu pliku, po prostu idąc po drzewie i-węzłów i (w wyznaczonym miejscu / rozmiarze) odrzuci wszystkie kolejne wskaźniki na stosie. Wykonanie operacji odwrotnej - odrzucenie danych na początku pliku - byłoby tak strasznie złożonym i ryzykownym procesem przepisywania drzewa i- węzłów w czasie rzeczywistym, że nikt nie napisze takich narzędzi dla społeczeństwa, ponieważ często zawodziły i prowadziły do utrata danych. W inodes wiki jest krótki, ale wyjaśnia niektóre z tych pojęć.

** Moja rada: odwróć ten problem - DLACZEGO ta aplikacja zachowuje się w ten sposób? Istnieje wiele sprawdzonych metod rejestrowania, ale często są one powiązane z tym, czym faktycznie jest system rejestrowania (syslog itp.). Zasadniczo aplikacja powinna „zwolnić” swój uchwyt do pliku, więc logrotate (itp.) Może obsłużyć dalsze przetwarzanie starych danych.

Ilekroć słyszę „do AKTYWNEGO pliku dziennika”, natychmiast proszę tę osobę, aby opowiedziała mi „specjalną historię” kryjącą się za tą aplikacją. Zwykle jest to „rezygnacja programisty i nie możemy zmienić kodu. To faktycznie jest odwrotność bezpieczeństwa, ma swój własny zestaw ryzyk. Ale dostaję rozwiązanie, które pozwala uniknąć dotykania kodu źródłowego. Jeśli to jest W takim przypadku potrzebne jest bardziej szczegółowe pytanie.

Scott Prive
źródło
0

Otwieranie w wysublimowanym tekście Usuwanie wierszy i zapisywanie pliku działa jakoś, nawet jeśli plik jest dołączany, ale przyszedłem tutaj, aby poszukać rozwiązania dla wiersza polecenia, więc zostawię to działające, ale bezużyteczne rozwiązanie tutaj !!

Ashok Kumar Sahoo
źródło
-1

Może skopiuj, obetnij, przywróć kopię do rozmiaru = 0 obcięcia i usuń kopię?

Lepiej jeszcze od ogona do kopiowania ogona, obcinania oryginału, konkatowania kopiowania ogona na oryginał.

Otrzymujesz linie w dzienniku na długości ogona, więc lepiej niż limit długości bajtów.

Zmiana szczegółów z komentarza:

Najpierw mamy skrypt logujący w Python3, co tylko chcesz

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

Następnie mamy nasz obcinacz

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.log pokazuje od 80 do 89

log pokazuje 90 do końca

W każdym razie, gdzie jest wola, istnieje sposób.

Wiele bardziej skomplikowanych przykładów konsolidatorów oraz tego, jak strumień zapisu jest otwierany lub zamykany, może wymagać dostosowania na rdzeń procesora itp. Po prostu wstrzymaj pisanie i ustaw kolejkę, jeśli możesz w rejestratorze procesu rejestrowania itp.

Mistrzu Jamesie
źródło
„z dziennika, który jest aktywnie dołączany przez aplikację”. Problem przeoczony przez twoje rozwiązanie polega na tym, że plik dziennika jest „na stałe” używany przez aplikację - co oznacza, że ​​i-węzeł pliku dziennika pozostaje w grze. Twoje rozwiązanie „tworzy kopię zapasową” danych z pliku dziennika, które mogą mieć zastosowania poza tym pytaniem.
Scott Prive
Dzięki za komentarz i głosowanie w dół? Zmieniłem szybki, tani przykład jako jedzenie, które trzeba przemyśleć głębiej, ale gdzie jest wola, jest na to sposób.
Mistrz James
Nie sądzę, że to był mój głos negatywny, ale myślę, że o co chodzi w komentarzach drugiej odpowiedzi: JEŻELI skopiujesz plik dziennika, to nie będzie to już aktywny plik dziennika ... bez względu na to, co robisz. Uchwyt pliku aplikacji będzie zawsze wskazywał i-węzeł oryginalnego pliku dziennika. Pomyśl o tym w ten sposób: masz aplikację, która używa niestandardowych funkcji rejestrowania i stale dodaje bajty do pliku, który otwiera.
Scott Prive
1
Racja, przepraszam, żeby wnioskować. Tak, i-węzeł musi pozostać taki sam, dlatego podany przykład / dowód używa obcięcia, i znowu zależy to od sytuacji (opcje dla wszystkich najwyraźniej chowają się w zwykłej witrynie).
Mistrz James