URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1662
[ Назад ]

Исходное сообщение
"нужно програмно реализовать tail -f access.log"

Отправлено rey , 05-Май-03 10:53 
в реалтайме обнаруживать новые дозаписи в файл и реагировать.
как это лучше реализовать..?

Содержание

Сообщения в этом обсуждении
"нужно програмно реализовать tail -f access.log"
Отправлено Parish , 05-Май-03 14:41 
во FreeBSD man kqueue

"нужно програмно реализовать tail -f access.log"
Отправлено uldus , 05-Май-03 22:46 
>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>как это лучше реализовать..?

Если на перл то http://search.cpan.org на предмет ключа Tail.
В общем случае, если скорость реакции на обновление не сильно критична, можно сделать так:
Запоминаем позицию конца файла (tell()) и время изменения, между делом или периодически проверяем время модификации (stat()), если время больше запомненного - читаем данные от сохраненной позации (seek()), далее все сначала.
Если время реакции очень критично, то можно держать файл открытым и через select() улавливать приход новых данных, но дополнительно придется задуматься над тем что файл может быть удален или обрезан.


"нужно програмно реализовать tail -f access.log"
Отправлено rey , 06-Май-03 08:17 
>select() улавливать приход новых данных, но дополнительно придется задуматься над тем
>что файл может быть удален или обрезан.
отлично.
спасибо.


"нужно програмно реализовать tail -f access.log"
Отправлено NewComer , 06-Май-03 12:07 
>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>как это лучше реализовать..?

Можно на место файла трубу (pipe) поместить с тем же именем и просто читать из нее. При условии, что такой вариант уместен в вашем случае.

Я, например, так сделал редиректор access.log в постгресовую базу - реализовав тем самым функциональность небезызвестного SARG-a. Всего за пару часов.



"while(1) & select -> 98% занятось процессора"
Отправлено rey , 07-Май-03 08:08 
>>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>>как это лучше реализовать..?
>
>Можно на место файла трубу (pipe) поместить с тем же именем и
>просто читать из нее. При условии, что такой вариант уместен в
>вашем случае.
>
>Я, например, так сделал редиректор access.log в постгресовую базу - реализовав тем
>самым функциональность небезызвестного SARG-a. Всего за пару часов.


неподходит, ибо файл тоже нужен.

у меня другой вопрос появился
написал код с select()но грузит проц на 98%
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUFFSIZE 1024
#define LOGFILE "access.log"


void get_new_data (int stream, char *buffer, int size)
{
    int n = 1;
    
    memset (buffer, 0, size);
    
    do
    {
    n = read (stream, buffer, size);
    if (n > 0)
        printf ("%s", buffer);
    
    } while ( n > 0 );
    
}

int main (int argc, char **argv)
{
    char *buffer;
    
    int file;
    fd_set f;
    struct timeval tv;

    buffer = (char *) malloc (BUFFSIZE);

    file = open (LOGFILE, O_RDONLY);
    if (file < 0)
    {
    perror ("open");
    return 1;
    }
    
    get_new_data (file, buffer, BUFFSIZE);
    
    while (1)
    {
    FD_ZERO (&f);
    FD_SET (file, &f);
    tv.tv_sec = 5;
    tv.tv_sec = 0;
    
    if (select (FD_SETSIZE, NULL, NULL, NULL, &tv))
    {
        if (FD_ISSET (file, &f))
            get_new_data (file, buffer, BUFFSIZE);
        
    }
    
    }

    close(file);
    free (buffer);
}

как подправить?


"while(1) & select -> 98% занятось процессора"
Отправлено vnp , 07-Май-03 11:41 
>>>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>>>как это лучше реализовать..?
>>
>>Можно на место файла трубу (pipe) поместить с тем же именем и
>>просто читать из нее. При условии, что такой вариант уместен в
>>вашем случае.
[...]
>неподходит, ибо файл тоже нужен.
>
>у меня другой вопрос появился
>написал код с select()но грузит проц на 98%

Беда в том, что файл, как это ни печально, отличается от трубы. Именно в
данном случае. В трубе состояние "конец файла" возникает лишь когда
закроется пишущий конец; с файлом же это случается как только читатель
доходит до конца наличных данных. С этого момента select возвращается
сразу (т.е. можно читать без блокировки), после чего read -- сразу, без
блокировки! -- возврашается, прочтя 0 байт.

В последних версиях ядра (начиная с 2.4.?) есть fcntl F_NOTIFY, выставив
который, можно получать сигналы об изменениях в директории. Поднимите бит
DN_MODIFY и убеждайтесь (через [f]stat), что речь идет о нужном файле.

Единственный portable способ (как это сделано в gnu tail) -- убедившись,
что read вернул 0, поспать немножко.