Зберігати вихід команди в буфер кільця


16

У мене є давно запущена команда, яка генерує багато результатів у stdout. Мені б хотілося зберегти, наприклад, лише останні три дні або останній гібібайт (уникаючи ріжучих ліній посередині), і, якщо можливо, у кусках файлів розміром не більше 20 Мб. Кожен фрагмент файлу називається числовим суфіксом або часовою позначкою.

Щось на зразок:

my-cmd | magic-command --output-file-template=my-cmd-%t \
                       --keep-bytes=1G \
                       --keep-time=3d \
                       --max-chunk-size=20M \
                       --compress=xz

Написав би:

my-cmd-2014-09-05T10:04:23Z

Коли він досягне 20М, він би стискав його та відкривав новий і так далі, і через деякий час він почне видаляти найстаріші файли.

Чи існує така команда?

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


Що таке "гібібайт"?
Пітер Мортенсен

@PeterMortensen Wikipedia: Gibibyte
jw013

Відповіді:


6

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

spewstuff | pipelog spew.log -p /tmp/spewpipe.pid -x "gzip spew.log.1"

Потім ви можете отримати pid /tmp/spewpipe.pidі:

kill -s USR1 $(</tmp/spewpipe.pid)

Але це вам доведеться налаштувати за допомогою cron чи чогось іншого. Але в цьому є одна уловка. Примітка I gzip spew.log.1- це тому, що -xкоманда виконується після обертання журналу. Отже, у вас виникає подальша проблема перезапису spew.log.1.gzкожного разу, якщо ви не пишете короткий скрипт, щоб виконати gzip і перемістити файл згодом і не використовувати його як -xкоманду.

Повне розкриття: я написав це, тому це, звичайно, працює чудово . ;) Я матиму на увазі варіант стиснення, або щось, що полегшує його, для версії 0.2 (цільове призначення -xдещо інше, але воно буде працювати як вище). Також автоматизований перекидання - це гарна ідея ... перша версія навмисно мінімальна, оскільки я протистояв спокусі додати функції, які були не потрібні (врешті-решт, це не так складно налаштувати завдання для крон).

Зауважте, що він призначений для виведення тексту ; якщо є потенційні нульові байти, слід використовувати -z- який замінює нуль чимось іншим. Це було компромісом для спрощення впровадження.


Спасибі. Я з нетерпінням чекаю pipelog-0.3;-). Я також натрапив на metacpan.org/release/File-Write-Rotate . Зауважте, що завдання Cron не дуже допоможуть для обертання залежно від розміру файлу.
Стефан Шазелас

Обертання залежно від розміру!?! Він зберігає вимивання результатів, тож ви можете статистувати файл з інтервалом ...
goldilocks

Ви не змогли надійно зберегти розмір менше 20 М (як у моїх запитаннях).
Стефан Шазелас

Інша справа, що це досить багато тексту (я додав остаточний абзац про це).
goldilocks

4

Dan Бернштейна Multilog , по- видимому це зробити - чи , можливо , більшість з них, забезпечуючи при цьому вихід через дескриптори файлів для процесора! Щоб компенсувати різницю , як вам подобається - хоча розмір специфікації 20M / 1G може зайняти деякий finagling , як це здається 16М є його зовнішній ліміт на журнал. Далі, здебільшого, є вибір копії та вставлення із вищезазначеного посилання, хоча посилання також детально описує інші параметри, такі як часова мітка на рядок, зберігаючи [an] інший файл (и), що містить лише останню модель узгодження рядків та ін. .

Інтерфейс

 multilog script

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

Вибір ліній

Кожний рядок вибирається спочатку. Дія...

-pattern

... знімає вибір лінії, якщо шаблон відповідає лінії. Дія...

+pattern

вибирає лінію, якщо шаблон відповідає лінії.

... візерунок - це рядок зірок та незір. Він відповідає будь-якому об'єднанню рядків, зіставленим всіма зірками та незірками в одному порядку. Незірка відповідає собі. Зірка перед кінцем шаблону відповідає будь-якій рядку, яка не включає наступний символ у шаблоні. Зірка в кінці шаблону відповідає будь-якій струні.

Автоматично обертові журнали

Якщо dir починається з крапки або косою рискою, тоді дія ...

 dir

... додає кожен обраний рядок до журналу з назвою dir . Якщо dir не існує, multilogстворює його.

Формат журналу такий:

  1. dir - це каталог, який містить деяку кількість старих файлів журналу, файл журналу з назвою поточний та інші файли для multilogвідстеження його дій.

  2. Кожен старий файл журналу має ім'я, що починається з @ , продовжуючи точною міткою часу, що показує, коли файл закінчено, і закінчуючи одним із наступних кодів:

    • .s : Цей файл повністю оброблений і безпечно записаний на диск.
    • .u : Цей файл створювався в момент відключення. Можливо, він був усічений. Він не оброблявся.

Дія...

 ssize

... встановлює максимальний розмір файлу для наступних дій dir . multilogвирішить, що струм досить великий, якщо поточний має розмір байтів. ( multilogтакож вирішить, що поточний досить великий, якщо він бачить новий рядок у межах 2000 байт максимального розміру файлу; він намагається закінчити файли журналів на межі рядків.) Розмір повинен бути між 4096 та 16777215. Максимальний розмір файлу за замовчуванням - 99999.

У версії 0.75 і вище: Якщо multilogотримує ALRM сигнал, він відразу вирішує , що струм є досить великим, якщо струм не порожньо.

(Примітка. Я підозрюю, що zsh scheduleвбудований файл може бути легко переконаний надсилати через ALRMвизначені інтервали, якщо це необхідно.)

Дія...

 nnum

... встановлює кількість файлів журналів для наступних дій dir . Після перейменування струму , якщо multilogбачить Num або більш старі файли журналів, він видаляє старий файл журналу з найменшим міткою часу. число повинно бути не менше 2. За замовчуванням кількість файлів журналу - 10.

Дія...

 !processor

... встановлює процесор для наступних дій dir . multilogподаватиме струм через процесор і зберігатиме висновок як старий файл журналу замість поточного . multilogтакож збереже будь-який вихід, який процесор записує в дескриптор 5, і зробить цей вихід читабельним на дескрипторі 4, коли він запускає процесор у наступному файлі журналу. Для надійності процесор повинен вийти з нуля, якщо у нього виникли проблеми зі створенням його виводу; multilogпотім запустить його знову. Зауважте, що запущений процесор може блокувати введення будь-якої програми multilog.


2

Найкраще, що я міг знайти, як наближення, яке не передбачає написання величезних фрагментів коду, це цей zshкод:

autoload zmv
mycmd |
  while head -c20M > mycmd.log && [ -s mycmd.log ]; do
    zmv -f '(mycmd.log)(|.(<->))(|.gz)(#qnOn)' '$1.$(($3+1))$4'
    {rm -f mycmd.log.1 mycmd.log.50.gz; (gzip&) > mycmd.log.1.gz} < mycmd.log.1
  done

Тут розбиваються і перетворюються на щонайбільше 51 великий 20 Мбіт файлів.


можливо ... петлі? btrfsможе також монтуватися за допомогою compress-force=zlib.
mikeserv

2

Ось зламаний сценарій пітона, щоб зробити щось подібне до того, що ви запитуєте:

#!/bin/sh
''':'
exec python "$0" "$@"
'''

KEEP = 10
MAX_SIZE = 1024 # bytes
LOG_BASE_NAME = 'log'

from sys import stdin
from subprocess import call

log_num = 0
log_size = 0
log_name = LOG_BASE_NAME + '.' + str(log_num)
log_fh = open(log_name, 'w', 1)

while True:
        line = stdin.readline()
        if len(line) == 0:
                log_fh.close()
                call(['gzip', '-f', log_name])
                break
        log_fh.write(line)
        log_size += len(line)
        if log_size >= MAX_SIZE:
                log_fh.close()
                call(['gzip', '-f', log_name])
                if log_num < KEEP:
                        log_num += 1
                else:
                        log_num = 0
                log_size = 0
                log_name = LOG_BASE_NAME + '.' + str(log_num)
                log_fh = open(log_name, 'w', 1)

1
Чи є причина, щоб він був як скрипт оболонки, який є execpython як перше, а не використовувати pythonабо env pythonhashbang?
peterph
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.