Возможно ли, чтобы "tail" испускал неполные строки? - PullRequest
0 голосов
/ 28 февраля 2012

Я использую tail -F log | python parse.py для отслеживания и анализа растущего файла журнала, но возникают некоторые ошибки синтаксического анализа, которые могут быть вызваны чтением неполных строк из файла журнала.

Возможно ли, что tail испускает неполные строки?

В парсере я читаю строки с кодом, подобным следующему:

import csv
import sys

reader = csv.reader(sys.stdin)
for row in reader
    # process

Ответы [ 2 ]

0 голосов
/ 28 февраля 2012

Так как вы изменили вопрос на меня .. новый ответ!: p

reader = csv.reader(sys.stdin)
for row in reader: 
    try:
        validate_row_data_somehow(row)
        do_things_with_valid_row(row)
    except:
        print "failed to process row", `row`
0 голосов
/ 28 февраля 2012

Возможно, что tail может выдавать «непарсируемые строки», но только если в файл записаны недопустимые строки.Вроде как круговой аргумент, но вот пример того, как это может произойти:

  • Вы указываете -f на / var / log / syslog

  • syslog-ng умирает в середине записи, охватывающей весь блок (сектора составляют 512 байт, размер блока вашей файловой системы, скорее всего, больше, хотя, вероятно, не намного больше, чем 4096), поэтому syslog имеет 9k данных, буферизованных дозаписать, он проходит через страницу размером 4 Кбайт, и прежде чем он сможет записать следующий системный журнал размером 4 КБ + 1 КБ. По крайней мере на ext2 это закончится как частичная запись даже после fsck. ext3? .. хе. Я былделать встроенные так долго, что я не могу вспомнить ... Но я бы не надеялся ... Но кто скажет, что данные, которые вы пишете, всегда будут правильными? Вы можете получить несимпатическую ошибку форматирования строкиэто не включает новую строку, которую вы ожидаете.

  • У вас будет частичная строка, которая не заканчивается новой строкой (или даже \ 0), ив следующий раз, когда системный журнал запускается и начинает добавляться, он будет просто добавлятьсяконец файла без понятия «действительные» записи.Таким образом, первая новая запись будет мусором, но следующая будет в порядке.

Это легко осуществить ..

В одном окне

tail -f SOMEFILE

В другом окне

echo FOO >>SOMEFILE
echo BAR >>SOMEFILE
printf NO_NEWLINE >>SOMEFILE
echo I_WILL_HAVE_THE_LAST_LINE_PREFIXED_TO_ME_CAUSING_NERD_RAGE >>SOMEFILE

Так как хвост Linux по умолчанию использует inotify, все, что читает, получит последнюю строку без новой строки и будет ждать, пока не появится следующая новая строка, добавляяNO_NEWLINE к началу того, что он считает «последней строкой».

Если вы хотите сделать это «питонским» способом, если вы используете Linux - используйте inotify, если вы используете OSX или BSDиспользуйте 'knotty' и отмените использование 'tail' в качестве входного канала и просто посмотрите файл самостоятельно.

Хвост может делать странные вещи, если вы также используете 'resync on truncate' - т.е. если файл обнуляется и перезапускается в середине чтения, вы можете получить какое-то странное количество данных при чтении, так как 'tail 'закроет ранее открытый дескриптор файла в обмен на новый.

...