2015-03-28 3 views
0

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

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

Это, к сожалению, должно выполняться на Solaris 10.

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

1) Раствор не должен требовать супер доступа пользователей к каким-либо образом. Поскольку это производственная среда предприятия, в этой системе нет доступа суперпользователя, поэтому я не могу сделать что-то вроде установки драйвера.

2) Файл журнала будет очень большим. Размышление об этом полностью, неоднократно для новых изменений неприемлемо.

Мне кажется, что если я могу запустить tail -f как непривилегированный пользователь, я должен быть способен сделать то же самое программно, что и тот же пользователь. Я понимаю, что хороший хак будет заключаться в том, чтобы вывести выход из хвоста -f в мой процесс, хотя мне бы хотелось, чтобы что-то было чище.

+1

Почему бы не посмотреть исходный код 'tail'? –

+0

У меня на самом деле нет исходного кода, Solaris - закрытый источник. – Mike

+0

http://stackoverflow.com/questions/1439799/how-can-i-get-the-source-code-for-the-linux-utility-tail – selbie

ответ

2

Это очень просто - просто прочитайте, и если вы читаете нулевые байты, подождите определенное время. Просто для иллюстрации (откройте свои собственные файлы и улучшите буферизацию и обработку ошибок по вкусу). Я отредактировал это, чтобы показать, где должно выполняться обработка ошибок и поиск последних строк, и зафиксировать положение sleep(). Это далеко не полный пример, просто указание на то, как это можно сделать.

#include <unistd.h> 
#include <stdio.h> 

#define NBUF 1024 
int main() 
{ 
    char buf[NBUF]; 
    ssize_t rcount, wcount; 

    int fin = 0, fout = 1; /* Or use open. */ 
    /* Code to display the last 10 lines goes here. */ 
    while (1) 
    { 
     while ((rcount = read (fin, buf, NBUF)) > 0) 
    { 
     wcount = write (fout, buf, rcount); 
     if (wcount != rcount) 
     { 
      perror("write didn't work."); 
      /* Handle error here, exit() or whatever. */ 
     } 
    } 
     if (rcount == -1) 
     { 
      perror("Read didn_t work..."); 
      /* Handle error here, exit() or something else. */ 
     sleep (1); 
    } 
} 
+0

Здесь есть пара вопросов, AFAICS. (1) Вы отображаете весь входной сигнал, а не только последние десять строк, и (2) вы ждали секунду между операциями чтения, что отлично, если входной сигнал меньше одного буфера в секунду, но не так горячий если скорость ввода выше (и 1 KiB/s не является высокоскоростным входом). Я думаю, вы спите только если чтение возвращает 0 байт. Если сбой чтения ('rcount == -1'), вы должны, вероятно, выйти из цикла. Поведение «последних десяти строк» ​​является стандартом для «хвоста» и приводит к интересным обсуждениям, когда файл длиннее гигабайт. –

+2

@Johathan Leffler: Твой прав, это не полный пример, это просто показывает принцип, как показать трейлинг-выход. Я не хотел писать полную программу (1), которая доступна от GNU coreutils. –

Смежные вопросы