LINUX.ORG.RU

Нужно запилить ztail

 


0

2

Я видел множество раз запросы вида «мне нужна идея что написать». Вот вот - нужен ztail. Который tail, но чтобы работало со сжатыми файлами. Да, нужно. У нас пачка nginx пишут сжатые логи, которые мне хотелось бы смотреть В РЕАЛЬНОМ ВРЕМЕНИ.

Спасибо.

Перемещено hobbit из general

★★★★★

Обязательно добавь в задачу, что реализация должна быть на rust

cobold ★★★★★
()

Насколько я знаю, начать распаковывать gz с середины штатно нельзя. То есть ztail должен будет пробежать по всему файлу с его начала (но не показывать), что явно не то, что ждут от такой утилиты. Но если надо то это примерно zcat | tail, разве что zcat придётся подправить чтобы он при EOF не падал а ждал продолжения.

Надо будет менять формат: паковать например по 1 мбайту и записывать «пакетами» в выходной файл. Если не дописывать туда никаких метаданных для быстрой перемотки - его даже gunzip продолжит понимать. Но дописывать придётся.

У нас пачка nginx пишут сжатые логи

Это как?

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

Попробуй


The Logfile Navigator, lnav, is a log file viewer for the terminal.


он вроде умеет


Given a set of files/directories, lnav will:

  • decompress as needed;
  • detect their format;

alx777 ★★
()
Ответ на: комментарий от yars068

Ну как же, есть zcat, zgrep и др., а ztail – нет, из общей картины выбивается :)

И всех их сложить в один .deb пакет, как suckless-tools :)

alx777 ★★
()
Ответ на: комментарий от dataman

Увы, Haskell я совсем не знаю, даже приблизительно не понимаю, что там делается.

Chiffchaff
()
Ответ на: комментарий от madcore

С gzip’ом должна быть возможность сделать иначе. Он реализует потоковое сжатие, не блочное, что позволяет сжимать и разжимать потоки. Собственно говоря, сервер, который пишет логи, явно не сжимает каждый раз файл заново - это было бы слишком дорого и долго.

Возможно, просто, что потоковое разжатие никому до сих пор не требовалось, потому и не реализовано.

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

хз как там организовать навигацию по сжатому, поток же нельзя разжимать не с начала
а так, проще такое хранить на фс со сжатием

madcore ★★★★★
()
Ответ на: комментарий от madcore

А… Я больше сконцентрировался на функционале tail -f. Который, наверное, можно реализовать, без того, чтобы разжимать файл постоянно.

Для реализации tail без опций наверное не страшно расшифровать файл с начала, если это не требуется делать постоянно.

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

С gzip’ом должна быть возможность сделать иначе.

Поэтому, наверное, и написали https://github.com/circulosmeos/gztool:

GZIP files indexer, compressor and data retriever. Create small indexes for gzipped files and use them for quick and random data extraction. No more waiting when the end of a 10 GiB gzip is needed!

dataman ★★★★★
()

Зачем нужен ztail, если есть zcat file |tail?

bryak ★★★★
()
Ответ на: комментарий от targitaj

кажется, я понял, что на самом деле тебе нужно, невнимательно прочитал
только я хз как как обычный гзип к концу перемотать

Машины вообще-то под нагрузкой.

тогда и распаковывать лучше уже на своей машине, что-то типа такого

ssh nginxhost 'tail -c+0 -f /var/log/nginx/XXX.log.gz'|gzip -d

madcore ★★★★★
()

У нас пачка nginx пишут сжатые логи, которые мне хотелось бы смотреть В РЕАЛЬНОМ ВРЕМЕНИ.

Разве писать в конец gzip, не трогая начало, теоретически возможно?

Если нет, то тогда смысл tail -f пропадает.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)

Проблема решается по-другому. Нужно с другого сервера (без нагрузки) примонтировать фс с логами и локальными ресурсами разжимать файлы.

kaldeon
()
Ответ на: комментарий от kaldeon

писать можно в конец, пока не пришел конечный блок с црц и размером, читать - нет, заголовок-то в начале и дальше нужно последовательно прочесть все данные

madcore ★★★★★
()
Ответ на: комментарий от madcore

Мне кажется, со всеми словарными способами сжатия не выйдет. Там же фишка в чем – словарь строится на лету. Поэтому не получится разжать файл с его середины, поскольку будут встречаться индексы из словаря, которых пока нет.

Если немного модифицировать алгоритм словарного сжатия, чтобы сохранил словарь отдельно. Тогда бы можно было прочитав отдельно словарь, разжать файл из любой его точки.

hibou ★★★★★
()
Ответ на: комментарий от kaldeon

Разве писать в конец gzip, не трогая начало, теоретически возможно?

Можно распаковывать «склеенные» gzip-файлы:

(echo abc | gzip; echo 123 | gzip) | gzip -d
No ★★
()

логи, которые мне хотелось бы смотреть В РЕАЛЬНОМ ВРЕМЕНИ.

Отчего бы не перестать страдать фигнёй и поставить Opensearch?

ugoday ★★★★★
()
Ответ на: комментарий от hibou

либо резать поток на законченные блоки, через эн чего-то завершать и начинать снова
тогда можно будет поймать заголовок гзипа рано или поздно, не распаковывая целиком
но с произвольной навигацией по строкам это сильно поможет

madcore ★★★★★
()
Ответ на: комментарий от madcore

Кстати, одна из проблем словарных методов сжатия – размеры словаря при больших файлах. Решают эту проблему все форматы по-разному. Один из способов решения – как раз таки сброс словаря каждые N килобайт. Вот надо узнать как поступает gz. Может быть это получится использовать?

hibou ★★★★★
()
Ответ на: комментарий от hibou

Вроде нет там никакого сброса. Единственный вариант это построить индекс и потом при наличии этого индекса можно делать быстрый seek.

Но вообще надо смотреть на конкретный софт, который этот gzip формирует. Так-то можно тупо сделать cat file1.gz file2.gz > file3.gz и это будет работать. Если конкретный софт формирует конечный gzip путем таких конкатенаций независимых кусков, тогда можно попробовать.

А вообще есть прекрасный формат xz который позволяет делать произвольные seek-и. Не знаю, написал ли кто-то xztail, но формат это точно позволяет.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от hibou

есть возможность
например, если сделать gzip *.log -c >xxx.log.gz, то для каждого файла будет новый заголовок и, соответственно, словарь

с сжатыми логами nginx не работал, но он тоже умеет вставлять заголовок, через сколько он будет зависит от параметра buffer=size(возможно, ещё потребуется flush=...) в access_log

если я правильно понял задачу ТС, надо просто дождаться пока не появится очередной заголовок, либо поискать ближайший от конца файла и начать тайлить оттуда

madcore ★★★★★
()

щас поковырялся, обнаружил некоторое странное поведение у штатного gzip(по крайней мере который у меня 1.14)
при работе с пайпами/стдин, если долго нет данных он будто отваливается и молча ничего не делает
лень с этим разбираться, такой вот скриптец пока накидал:

#!/usr/bin/env perl
use warnings;
use strict;

my @zsig = ("\x1f", "\x8b", "\x08", "\xff");
my ($ii, $zh, $zproc) = 0;

while (my $ch = getc or !eof(STDIN)) {
    if ($ch eq $zsig[$ii++] and $zh .= $ch) {
        if ($ii == 3) {
            $zproc->close() if $zproc;
            open($zproc, "|-", "gzip -cd") or die("wtf: $!");
        }
    } else {
        $zproc->print($zh . $ch) if $zproc;
        $ii = 0; $zh = '';
    }
}
$zproc->close() if $zproc;


пользоваться совместно с обычным tail, например, примерно так в простейшем случае:
tail -zf /var/log/nginx/xxx-access.log.gz | zfollow.pl

либо с удалённо:
ssh nginxhost 'tail -zf /var/log/nginx/xxx-access.log.gz | zfollow.pl'

чтобы видеть на лету изменения с конца
для более сложных ситуаций tail ес-но построчную нафигацию по бинарному файлу не очень умеет, можно с параметром -с прикидывать на глаз нужное место в байтах)

как часто что-то будет выплёвываться завит от настроек логов nginx, параметров gzip=ratio, buffer=size, flush=time, и, конечно, кол-ва запросов
можно и полноценный аналог ztail запилить, но не уверен, что он такой в принципе может быть нужен

madcore ★★★★★
()
Ответ на: комментарий от madcore

Спасибо. Тут есть нюансы. По какой-то причине, они не стали выделять суффиксом в имени пожатые логи. То есть, я делаю tail /var/log/nginx/*log -f и получаю частично мусор... И zcat и zgrep умеют понимать пожат файл или нет.

То есть, пилить нужно так, чтобы я мог делать ztail /var/log/nginx/*log -f и оно само разбирало пожат лог или нет.

targitaj ★★★★★
() автор топика
Последнее исправление: targitaj (всего исправлений: 1)
Ответ на: комментарий от targitaj

а какой именно функционал нужен, тупо аналог «tail -f» или прям все плюшки с перемещениями в нужную строку итп?
а то, есть, например, в природе подобные штуки https://github.com/circulosmeos/gztool с индексированием и прочими блекджеками

madcore ★★★★★
()
Ответ на: комментарий от targitaj

И zcat и zgrep умеют понимать пожат файл или нет.

zcat только ошибку выдавать умеет, если не пожат

madcore ★★★★★
()

Универсальную программу, которая бы делала со всеми архивами что хочется в посте, кажется нельзя. Для какого-то частного случая или случаев наверное можно, но чаще всего будет что-то похожее на однострочник предложенный @TPPPbIHDELj, просто не в виде однострочника, а более «солидно».

Ели же взять более узкую идею, то в теории можно для nginx вклинить между ним и его логирующей системой нечто, что будет тем или иным образом делить поток логов на два, один в архивирование, второй на некий (любой) интерфейс к которому можно в любой момент подключится и сразу видеть текущие лог записи, без предыдущей истории, только то что прямо сейчас в лог летит.

Или же, иной подход который опять же будет требовать залезать в nginx это запись лога текстом, до определённого момента, размера, затем оно блочно жмётся и конкатенируется к основному архиву, таким образом можно будет просто текстом всегда иметь прямой доступ к срезу логов за последние например N часов, а всё что было до лежит в архиве.

Просто мысли в слух.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

У вас немцев в роду не было? Тевтонским духом сквозит от вашего подхода:

  1. что-то плохое произошло на этапе планирования;

  2. задача поставлена вообще криво и поперёк реальности;

  3. предельными трудозатратами и гениальным оверинженирингом проблема решается. Все счастливы, шнапс пьют, карривурстом закусывают.

С Русской точки зрения исправлять нужно первый шаг. Как вы вообще очутились в положении, когда такая ерунда бредовая понадобилась? Правильный ответ я уже сказа выше — Opensearch. Если это вдруг слишком сложно (а Opensearch это ни разу про «само работает»), то nginx умеет писать в удалённый syslog от зари времён. А уж rsyslogd элементарно настраивается и вообще ресурсов не жрёт.

ugoday ★★★★★
()
Ответ на: комментарий от madcore

тупо аналог «tail -f»

вроде достаточно

targitaj ★★★★★
() автор топика
Ответ на: комментарий от yars068

наверное, потому что ты не можешь распаковать только хвост файла, не? ну, во всяком случае, в обычных форматах архивации.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.