如何监控一个日志文件并验证,用tail的原理实现

最近在做网页爬虫的测试,需要通过apache的access-log来验证爬虫的行为,就想到了用类似linux的tail命令实现方式来实现。这里先把代码贴出来:

#include <stdio.h>
#include 
<stdlib.h>
#include 
<unistd.h>
#include 
<malloc.h>
#include 
<sys/stat.h>

static size_t filesize(const char *filename) {
    
struct stat sb;

    
if (!stat(filename, &sb))
        
return sb.st_size;
    
return 0;
}

static void tailf(const char *filename, int lines) {
    
char **buffer;
    
int head = 0;
    
int tail = 0;
    FILE 
*str;
    
int i;

    
if (!(str = fopen(filename, "r"))) {
        fprintf(stderr, 
"Cannot open \"%s\" for read\n", filename);
        perror(
"");
        exit(
1);
    }

    buffer 
= (char **) malloc(lines * sizeof(*buffer));
    
for (i = 0; i < lines; i++)
        buffer[i] 
= (char *) malloc(BUFSIZ + 1);

    
while (fgets(buffer[tail], BUFSIZ, str)) {
        
if (++tail >= lines) {
            tail 
= 0;
            head 
= 1;
        }
    }

    
//the method here is very smart, if variable head is set, that is to say the file is longer than 10 lines,
    
//and the first line of the last 10 lines is start from the index tail, and the last line is at index tail-1

    
if (head) {
        
for (i = tail; i < lines; i++)
            fputs(buffer[i], stdout);
        
for (i = 0; i < tail; i++)
            fputs(buffer[i], stdout);
    } 
else {
        
for (i = head; i < tail; i++)
            fputs(buffer[i], stdout);
    }
    fflush(stdout);

    
for (i = 0; i < lines; i++)
        free(buffer[i]);
    free(buffer);
}

int main(int argc, char **argv) {
    
char buffer[BUFSIZ];
    size_t osize, nsize;
    FILE 
*str;
    
const char *filename;
    
int count;

    
if (argc != 2) {
        fprintf(stderr, 
"Usage: tailf logfile\n");
        exit(
1);
    }

    filename 
= argv[1];

    tailf(filename, 
10);

    
for (osize = filesize(filename);;) {
        nsize 
= filesize(filename);
        
if (nsize != osize) {
            
if (!(str = fopen(filename, "r"))) {
                fprintf(stderr, 
"Cannot open \"%s\" for read\n", filename);
                perror(argv[
0]);
                exit(
1);
            }
            
if (!fseek(str, osize, SEEK_SET))
                
while ((count = fread(buffer, 1sizeof(buffer), str)) > 0)
                    fwrite(buffer, 
1, count, stdout);
            fflush(stdout);
            fclose(str);
            osize 
= nsize;
        }
        usleep(
250000); /* 250mS */
    }
    
return 0;

} 

原文地址:https://www.cnblogs.com/welkinwalker/p/2088403.html