Видаліть перші N рядків з активного файлу журналу


26

Чи є спосіб видалити перші Nрядки з журналу, який активно додається додатком?

Відповіді:


10

Ні, такі операційні системи, як Linux, і це файлові системи, не передбачають видалення даних із початку файлу. Іншими словами, початкова точка зберігання для файлу фіксована.

Видалення рядків із початку файлу зазвичай виконується шляхом запису решти даних у новий файл та видалення старого. Якщо програма має відкритий старий файл для запису, видалення цього файлу відкладається, поки програма не закриє файл.


Як зазначали коментатори, з причин, наведених у моєму попередньому реченні, зазвичай потрібно узгодити обрізку журналів з програмами, які пишуть журнали. Як саме ви це зробите, залежить від програм. Деякі програми закриють і знову відкриють свої логіни, коли ви надсилаєте їм сигнал (наприклад, HUP), і це може бути використано для запобігання запису журналів до журналу "видалених", не порушуючи послуги.

Існує безліч утиліт для управління розміром файлів журналів, наприклад, logrotate

Деякі програми мають власні утиліти. Наприклад, веб-сервер Apache включає в себе утиліту rotatelogs .


3
Але ви не повинні робити цього, поки щось файл все ще відкритий і все ще додається до нього, оскільки він запише до тепер видаленого файлу, і ви втратите ці повідомлення журналу.
Тарнай Калман

Правда. Навіть якщо ви використовували те саме ім’я файлу.
Геннес

занадто погано, що ОС не дозволяє вам, що було б зручно для ротаторів журналу, щоб не довелося перезавантажувати процеси після обертання: |
rogerdpack

25

Я думаю, що це завдання можна досягти за допомогою sed

sed -i '1,10d' myfile

буде видалено рядки з 1- го по 10- й рядок, що формує файл.

Я думаю, що кожен повинен хоча б придивитись до цього 1-го лайнера .

Зауважте, що це не працює для журналів, до яких активно додається додаток (як зазначено в запитанні).

sed -iстворить новий файл і 'видалить' файл, до якого записується. Більшість додатків продовжуватимуть записувати записи в журнал до видаленого файлу журналу і надалі заповнюватимуть місце на диску. До нового, усіченого файлу журналу не додаватимуться. Це припиняється лише при перезапуску програми або іншому сигналі про закриття та повторне відкриття файлів журналу. Після цього у новому файлі журналу буде розрив (відсутні записи журналів), якщо між використанням sed та перезавантаженням програми було здійснено будь-яку активність для реєстрації.

Безпечним способом зробити це було б зупинити додаток, використовувати sed для обрізання журналу, а потім перезапустити програму. Такий підхід може бути неприйнятним для деяких служб (наприклад, веб-сервер з високою пропускною спроможністю та високими вимогами до безперервності обслуговування)


2
Чи знаєте ви, що відбувається з додатками, які додаються?
Адам Матан

1
Припустимо, звичайний обробник відкритого файлу, який час від часу додає рядки та промиває.
Адам Матан

1
Я знаю, як подорожувати sed, а витяг рядків до нового файлу - це не-мозкове слово з sed. Проблеми полягають у тому, щоб зберігати все в одному файлі.
Адам Матан

10
Ні, це не повинно працювати. sed -iстворює новий файл із відредагованим вмістом, а старий видаляється, щоб ви не редагували активний файл: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Перевірте, як sed -iпрацює. Чому ця неправильна відповідь має стільки відгуків?
пабук

1
У запитанні зазначено "з журналу, який активно додається додатком". Оперативне слово - «активно». Можливо, це уточнення було додане після того, як з’явилася ваша відповідь. Але, як випливає, читачі, які тяжіють до "більшості грошей", будуть введені в оману. Я міг лише спростувати один раз.
Скотт-Прі

5

Ні. Рішенням цієї загальної проблеми росту файлів журналу є обертання журналу. Це передбачає регулярне (як правило, щотижневе або щотижневе) переміщення існуючого файлу журналу на якесь інше ім'я файлу та початок нового із порожнього файлу журналу. Після закінчення періоду старі файли журналів викидаються.

Дивіться: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm


2

Це відповідь , а не рішення. Немає вирішення питання. Запитувач чітко зазначає: "з журналу, який активно додається додатком". Ви можете прочитати далі, щоб зрозуміти більше, і пропустити до кінця пропозицію, яку я висловлюю, виходячи з своєї презумпції, чому цей код не дотримується найкращих методів ведення журналу.

Щоб було зрозуміло: інші "відповіді" тут пропонують помилкову обіцянку . Жодна кількість перейменувань не призведе до того, що додаток використає новий файл. Найбільш корисна інформація похована у коментарях до цих невірних відповідей.

Файли ACTIVE - це не якийсь контейнер, у який ви просто вводите дані. Ім'я файлу вказує на ONE inode (початок файлу), і кожен inode має вказівник на інший inode (якщо є більше даних). Це означає, що у файл, що постійно записується, до нього додається постійний потік входів, і те, що ви думаєте про "файл", - це насправді послідовність журналів вводів.

Уявіть, що ви відстежували когось на Картах Google, і ця людина в будь-який час могла телепортуватися в будь-яку точку світу, і ви намагалися підключити ці точки.

Інструмент Linux "усікати" може відкинути дані в кінці файлу, просто перемістившись по дереву inode (і за вказаним місцеположенням / розміром) він відкине всі наступні покажчики в стеку. Зробити зворотний - відкинути дані на початку файлу - було б таким жахливо складним і ризикованим процесом переписування дерева inode в режимі реального часу, що ніхто не пише таких інструментів для публіки, оскільки вони часто не дають змоги і призведуть до втрата даних. У Inodes вікі коротка , але пояснює деякі з цих понять.

** Моя порада: розгорніть цю проблему - ЧОМУ ця програма поводиться так? Існує багато найкращих практик ведення журналів, але часто вони пов'язані з тим, що насправді є вашою системою ведення журналів (syslog тощо). В основі програми, як очікується, "випустить" свою обробку до файлу, тому logrotate (тощо) може обробляти подальшу обробку старих даних.

Щоразу, коли я чую "до АКТИВНОГО журналу", я негайно прошу цю особу розповісти мені "спеціальну історію" за цією програмою. Зазвичай це "розробник вийшов, і ми не можемо змінити код. Це насправді зворотна безпека, є власний набір ризиків. Але я отримую, що вам потрібно рішення, яке дозволяє уникати торкання вихідного коду. Якщо це випадку, потрібне більш конкретне питання.


0

Відкриття в піднесеному тексті Видалення рядків і збереження файлу спрацьовує якось, навіть якщо файл додається, але я прийшов сюди, щоб шукати рішення для рішення командного рядка, тому я просто залишив тут це робоче, але марне рішення !!


-1

Можливо, скопіюйте, усікайте, поверніть копію на розмір = 0 усічення та видаліть копію?

Краще все-таки від хвоста до копії, обрізання оригіналу, лаконічної копії хвоста на оригіналі.

Ви отримуєте рядки в журналі на довжину хвоста так краще, ніж обмеження довжини байтів.

Внесення змін до коментарів:

Спочатку ми маємо скрипт реєстратора в Python3, що завгодно

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)

Тоді ми маємо наш магістраль

#!/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 показує від 80 до 89

журнал показує 90 до кінця

У будь-якому випадку, де є воля, є спосіб.

Багато складніших прикладів консолідаторів і того, як відкривається чи закривається потік запису, може знадобитися коригування на одне ядро ​​процесора і т. Д. Просто призупиніть написання та чергу, якщо ви можете у своєму реєстраторі процесу реєстрації тощо.


"з журналу, який активно додається додатком". Проблема, яку вирішує ваше рішення, полягає в тому, що файл журналу "постійно" використовується додатком, тобто вкладення файлу журналу залишається в грі. Ваше рішення "створює резервну копію" даних журнальних файлів, які можуть використовуватись поза цим питанням.
Скотт Прів

Дякуємо за ваш коментар та голосування проти Я змінив швидкий дешевий приклад як їжу для думки, вам доведеться подумати глибше про свою ситуацію, але там, де є воля, є спосіб.
Майстер Джеймс

Не думаю, що це було моїм голосуванням, але я думаю, що справа зауважена в коментарях іншої відповіді: Якщо ви скопіюєте файл журналу, то це вже не активний файл журналу ... незалежно від того, що ви робите. Файловий файл програми завжди буде вказувати на вкладення вихідного журналу. Подумайте про це так: у вас є програма, яка використовує нестандартні функції ведення журналу, і постійно додає байти до відкритого файлу.
Скотт-Прі

1
Правильно шкода зробити висновок. Так, inode повинен залишатися тим самим, тому в наведеному прикладі / доказі використовується скорочення, і знову це залежить від ситуації (параметри для всіх, мабуть, ховаються на простому сайті).
Майстер Джеймс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.