Re: Variable-sized lines of text in linked list (long)
- From: Morris Dovey <mrdovey@xxxxxxxx>
- Date: Thu, 28 Feb 2008 18:30:55 -0500
My web site server log seemed horribly cluttered and 'hits' from
one site were mixed with those from other sites, so I read the
log a line at a time and made lists (and lists of lists) so I
could produce a report in which requests would be grouped
chronologically by requestor. For example:
25 216.185.230.83
| 02-26 16:45 301 /DeSoto
| 02-26 16:45 200 /DeSoto/
| 02-26 20:17 200 /DeSoto/solar.html
| 02-26 20:17 200 /DeSoto/SC_Madison/
| 02-27 15:03 200 /DeSoto/SC_Types.html
| 02-27 15:26 200 /DeSoto/
for three visits, which is incredibly easier for me to read.
The main() function is fairly simple:
int main (int argc,char **argv)
{ char *line,*s,*z;
unsigned have_page,is_image,line_count = 0,len;
FILE *fp;
user_e *q;
evnt_e *e;
/*
* Check parameters and open the log file
*/
if (argc < 2)
{ puts("Usage: logan <log file>\n");
exit(EXIT_FAILURE);
}
if (!(fp = fopen(argv[1],"r")))
{ puts("Error: can't open log file\n");
exit(EXIT_FAILURE);
}
/*
* Eat the file
*/
while ((line = getsm(fp)))
{ ++line_count;
if (strlen(line) > 256) line[255] = '\0';
process(line);
free(line);
}
/*
* Output the list of requestors and files requested
*/
for (q=user_list.head; q; q=q->next)
{ printf("\n%7u %s\n",q->count,q->user);
have_page = 0;
for (e=q->head; e; e=e->next)
{ s = e->evnt->page->page;
len = strlen(s);
z = s + len;
if (len > 4) is_image = (!strcmp(z-4,".gif") ||
!strcmp(z-4,".ico") ||
!strcmp(z-4,".jpg") ||
!strcmp(z-4,".png"));
else is_image = 0;
if (have_page && is_image) continue;
printf(" | %s %03u %s\n",
ptime(e->evnt->when),e->evnt->code,s);
if (!have_page && !is_image) have_page = 1;
}
}
printf("\nLines: %u\n\n",line_count);
return 0;
}
The process() function, which breaks the line into its
constituant parts, is a bit messier, but still isn't really
complex:
/*
* Extract data from a log record to a log element
*/
log_e *process(char *line)
{ char *p, *s;
char bbuf[256], cbuf[256], fbuf[256], pbuf[256], tbuf[256],
ubuf[256];
log_e *q = NULL;
/*
* Extract the requestor
*/
for (p = line,s = ubuf; *p; ++p)
{ if (*p <= ' ') break;
*s++ = *p;
}
if (*p) ++p;
*s = '\0';
for ( ; *p; ++p) if (*p == '[') break;
if (*p) ++p;
/*
* Extract the access date/time
*/
for (s = tbuf; *p; ++p)
{ if (*p == ']') break;
else *s++ = *p;
}
if (*p) ++p;
*s = '\0';
for ( ; *p; ++p) if (*p == '"') break;
if (*p) ++p;
/*
* Extract the web page URL
*/
if (!strncmp(p,"GET ",4)) p += 4;
for (s = pbuf; *p; ++p)
{ if ((*p == '"') || (*p == ' ')) break;
else *s++ = *p;
}
if (*p == ' ') for (; *p; ++p) if (*p == '"') break;
if (*p) ++p;
*s = '\0';
for ( ; *p; ++p) if (*p != ' ') break;
/*
* Extract the return code
*/
for (s = cbuf; *p; ++p)
{ if ((*p < '0') || (*p > '9')) break;
else *s++ = *p;
}
if (*p) ++p;
*s = '\0';
for ( ; *p; ++p) if (*p != ' ') break;
/*
* Extract the byte count
*/
for (s = bbuf; *p; ++p)
{ if ((*p < '0') || (*p > '9')) break;
else *s++ = *p;
}
if (*p) ++p;
*s = '\0';
for ( ; *p; ++p) if (*p == '"') break;
if (*p) ++p;
/*
* Extract the referring URL
*/
for (s = fbuf; *p; ++p)
{ if (*p == '"') break;
else *s++ = *p;
}
if (*p) ++p;
*s = '\0';
/*
* Add the log record info to the list
*/
if (!(q = malloc(sizeof(log_e))))
{ puts("Allocation failure");
return NULL;
}
q->next = NULL;
q->user = add_user(q,ubuf);
q->when = gtime(tbuf);
q->page = add_page(q,pbuf);
q->code = atoi(cbuf);
q->bcnt = atoi(bbuf);
q->from = add_from(q,fbuf);
if (log_list.head) log_list.tail->next = q;
else log_list.head = q;
log_list.tail = q;
return q;
}
And the remainder is basic stuff to add elements to lists and
convert/format time.
--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
.
- References:
- Variable-sized lines of text in linked list
- From: Scottman
- Re: Variable-sized lines of text in linked list
- From: Morris Dovey
- Variable-sized lines of text in linked list
- Prev by Date: Re: printf("%ls")
- Next by Date: Re: printf("%ls")
- Previous by thread: Re: Variable-sized lines of text in linked list
- Next by thread: Re: Variable-sized lines of text in linked list
- Index(es):
Relevant Pages
|