Skip to content

Commit 8a0fc47

Browse files
committed
Use log format parsing to check if standard input matches the log format
1 parent 290415e commit 8a0fc47

File tree

6 files changed

+134
-76
lines changed

6 files changed

+134
-76
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CC = gcc
22
CFLAGS = -Wall -Werror -std=c99 -pedantic -Os
33
LDFLAGS =
44

5-
SOURCES = log_main.c log_format.c
5+
SOURCES = log_main.c log_format.c log_read.c
66
OBJECTS = $(SOURCES:.c=.o)
77
EXE = logtastic
88

log_format.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static struct format_token * parse_format_token_variable (char **input) {
9090
return token;
9191
}
9292

93-
struct format_token * parse_format_token (char **input) {
93+
static struct format_token * parse_format_token (char **input) {
9494
struct format_token *token = NULL;
9595

9696
if (input && *input) {
@@ -107,3 +107,22 @@ struct format_token * parse_format_token (char **input) {
107107

108108
return token;
109109
}
110+
111+
112+
struct format_token * parse_log_format (char *format) {
113+
struct format_token *head = NULL;
114+
struct format_token *tail = NULL;
115+
struct format_token *item = NULL;
116+
117+
while ((item = parse_format_token (&format))) {
118+
if (!head) {
119+
head = item;
120+
} else {
121+
tail->next = item;
122+
}
123+
tail = item;
124+
}
125+
126+
return head;
127+
}
128+

log_format.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ struct format_token {
2727
struct format_token *next;
2828
};
2929

30-
struct format_token * parse_format_token (char **input);
30+
struct format_token * parse_log_format (char *format);
3131

3232
#endif

log_main.c

Lines changed: 47 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,68 @@
1+
#include <glib.h>
12
#include <stdio.h>
23
#include <stdlib.h>
34
#include <string.h>
45

6+
#include "log_read.h"
57
#include "log_format.h"
68

7-
/*
8-
68.104.1.129 - - [16/Aug/2012:12:30:02 -0700] "GET /testing/finder/FileModel.php?action=read&path=%2Ffiles%2Fsource%2Fcoreutils-7.4%2Fsrc&start=128 HTTP/1.1" 200 99 "http://eboyjr.oftn.org:8080/files/source/coreutils-7.4/src/?pp=tail.c" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.77 Safari/537.1"
9-
*/
9+
static void check_log_message (char *buffer, void *data) {
10+
struct format_token *format = data;
11+
_Bool matches = 1;
1012

11-
#define BUFFER_SIZE (4096)
13+
char *line = buffer;
1214

13-
struct format_token * parse_log_format (char *format) {
14-
struct format_token *head = NULL;
15-
struct format_token *tail = NULL;
16-
struct format_token *item = NULL;
15+
if (buffer && format) {
16+
while (format && *line) {
17+
if (format->type == T_VARIABLE) {
18+
char ending = '\0';
19+
if (format->next->type != T_CHARACTER) {
20+
matches = 0;
21+
fprintf (stderr, "Can't have consecutive variables!\n");
22+
break;
23+
}
24+
ending = format->next->data.ch;
1725

18-
while ((item = parse_format_token (&format))) {
19-
if (!head) {
20-
head = item;
21-
} else {
22-
tail->next = item;
26+
char *begin = line;
27+
size_t length = 0;
28+
while (*line != ending && *line != '\0') {
29+
length++;
30+
line++;
31+
}
32+
33+
char *copy = g_strndup (begin, length);
34+
printf ("\033[33m%d -> %s\033[0m\n", format->data.var, copy);
35+
g_free (copy);
36+
} else {
37+
if (*line != format->data.ch) {
38+
matches = 0;
39+
break;
40+
}
41+
line++;
42+
}
43+
format = format->next;
2344
}
24-
tail = item;
25-
}
2645

27-
item = head;
28-
while (item) {
29-
switch (item->type) {
30-
case T_CHARACTER:
31-
putchar (item->data.ch);
32-
break;
33-
case T_VARIABLE:
34-
printf ("\x1b\x5b\x33\x35\x6d${%d}\x1b\x5b\x33\x39\x6d", item->data.var);
35-
break;
46+
if (format) {
47+
matches = 0;
3648
}
37-
item = item->next;
49+
50+
printf ("Line[%s]: %s\n\n",
51+
matches ? "\033[32m OK \033[39m" : "\033[31mFAIL\033[39m",
52+
buffer);
3853
}
39-
putchar ('\n');
4054

41-
return head;
55+
free (buffer);
4256
}
4357

44-
void readlines (FILE *input, void (*emit)(char *)) {
45-
int ch;
46-
47-
char *buffer = NULL;
48-
size_t cursor = 0;
49-
size_t length = 0;
50-
51-
setvbuf (input, NULL, _IOLBF, BUFFER_SIZE);
52-
53-
while ((ch = fgetc (input)) != EOF) {
54-
55-
if (!buffer) {
56-
buffer = malloc (BUFFER_SIZE);
57-
if (!buffer) {
58-
return;
59-
}
60-
61-
cursor = 0;
62-
length = BUFFER_SIZE;
63-
memset (buffer, '\0', length);
64-
}
65-
66-
if (ch == '\n') {
67-
(*emit) (buffer);
68-
buffer = NULL;
69-
} else {
70-
buffer[cursor++] = ch;
71-
72-
if (cursor >= length) {
73-
char *tmp = NULL;
74-
size_t increase = length;
75-
76-
length = length + increase;
58+
int main(void) {
59+
struct format_token *item = NULL;
7760

78-
tmp = realloc (buffer, length);
79-
if (!tmp) {
80-
free (buffer);
81-
return;
82-
}
61+
char *format = "$remote_addr - $remote_user [$time_local] \"$request\" "
62+
"$status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"";
8363

84-
buffer = tmp;
85-
memset (buffer + increase, '\0', increase);
86-
}
87-
}
88-
}
89-
}
64+
item = parse_log_format (format);
65+
log_read_lines (stdin, check_log_message, (void *) item);
9066

91-
int main(void) {
92-
parse_log_format ("$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"");
9367
return 0;
9468
}

log_read.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
#include "log_read.h"
6+
7+
8+
void log_read_lines (FILE *input, void (*emit)(char *, void *), void *data) {
9+
int ch;
10+
11+
char *buffer = NULL;
12+
size_t cursor = 0;
13+
size_t length = 0;
14+
15+
#define BUFFER_SIZE (4096)
16+
17+
setvbuf (input, NULL, _IOLBF, BUFFER_SIZE);
18+
19+
while ((ch = fgetc (input)) != EOF) {
20+
21+
if (!buffer) {
22+
buffer = malloc (BUFFER_SIZE);
23+
if (!buffer) {
24+
return;
25+
}
26+
27+
cursor = 0;
28+
length = BUFFER_SIZE;
29+
memset (buffer, '\0', length);
30+
}
31+
32+
if (ch == '\n') {
33+
(*emit) (buffer, data);
34+
buffer = NULL;
35+
} else {
36+
buffer[cursor++] = ch;
37+
38+
if (cursor >= length) {
39+
char *tmp = NULL;
40+
size_t increase = length;
41+
42+
length = length + increase;
43+
44+
tmp = realloc (buffer, length);
45+
if (!tmp) {
46+
free (buffer);
47+
return;
48+
}
49+
50+
buffer = tmp;
51+
memset (buffer + increase, '\0', increase);
52+
}
53+
}
54+
}
55+
56+
#undef BUFFER_SIZE
57+
58+
}
59+

log_read.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef LOG_READ_H
2+
#define LOG_READ_H
3+
4+
void log_read_lines (FILE *input, void (*emit)(char *, void *), void *data);
5+
6+
#endif

0 commit comments

Comments
 (0)