2 |
- |
1 |
#include <u.h>
|
|
|
2 |
#include <libc.h>
|
|
|
3 |
#include "httpd.h"
|
|
|
4 |
#include "httpsrv.h"
|
|
|
5 |
|
|
|
6 |
int logall[3]; /* logall[2] is in "Common Log Format" */
|
|
|
7 |
|
|
|
8 |
static char *
|
|
|
9 |
monname[12] =
|
|
|
10 |
{
|
|
|
11 |
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
|
12 |
};
|
|
|
13 |
|
|
|
14 |
void
|
|
|
15 |
logit(HConnect *c, char *fmt, ...)
|
|
|
16 |
{
|
|
|
17 |
char buf[4096];
|
|
|
18 |
va_list arg;
|
|
|
19 |
HSPriv *p;
|
|
|
20 |
|
|
|
21 |
va_start(arg, fmt);
|
|
|
22 |
vseprint(buf, buf+sizeof(buf), fmt, arg);
|
|
|
23 |
va_end(arg);
|
|
|
24 |
p = nil;
|
|
|
25 |
if(c != nil)
|
|
|
26 |
p = c->private;
|
|
|
27 |
if(p != nil && p->remotesys != nil)
|
|
|
28 |
syslog(0, HTTPLOG, "%s %s", p->remotesys, buf);
|
|
|
29 |
else
|
|
|
30 |
syslog(0, HTTPLOG, "%s", buf);
|
|
|
31 |
}
|
|
|
32 |
|
|
|
33 |
void
|
|
|
34 |
writelog(HConnect *c, char *fmt, ...)
|
|
|
35 |
{
|
|
|
36 |
HSPriv *p;
|
|
|
37 |
char buf[HBufSize+500], *bufp, *bufe;
|
|
|
38 |
char statuscode[4];
|
|
|
39 |
vlong objectsize;
|
|
|
40 |
ulong now, today;
|
|
|
41 |
int logfd;
|
|
|
42 |
va_list arg;
|
|
|
43 |
Tm *tm;
|
|
|
44 |
|
|
|
45 |
if(c == nil)
|
|
|
46 |
return;
|
|
|
47 |
p = c->private;
|
|
|
48 |
bufe = buf + sizeof(buf);
|
|
|
49 |
now = time(nil);
|
|
|
50 |
tm = gmtime(now);
|
|
|
51 |
today = now / (24*60*60);
|
|
|
52 |
|
|
|
53 |
/* verbose logfile, for research on web traffic */
|
|
|
54 |
logfd = logall[today & 1];
|
|
|
55 |
if(logfd > 0){
|
|
|
56 |
if(c->hstop == c->header || c->hstop[-1] != '\n')
|
|
|
57 |
*c->hstop = '\n';
|
|
|
58 |
*c->hstop = '\0';
|
|
|
59 |
bufp = seprint(buf, bufe, "==========\n");
|
|
|
60 |
bufp = seprint(bufp, bufe, "LogTime: %D\n", now);
|
|
|
61 |
bufp = seprint(bufp, bufe, "ConnTime: %D\n", c->reqtime);
|
|
|
62 |
bufp = seprint(bufp, bufe, "RemoteIP: %s\n", p->remotesys);
|
|
|
63 |
bufp = seprint(bufp, bufe, "Port: %s\n", p->remoteserv);
|
|
|
64 |
va_start(arg, fmt);
|
|
|
65 |
bufp = vseprint(bufp, bufe, fmt, arg);
|
|
|
66 |
va_end(arg);
|
|
|
67 |
if(c->req.uri != nil && c->req.uri[0] != 0)
|
|
|
68 |
bufp = seprint(bufp, bufe, "FinalURI: %s\n", c->req.uri);
|
|
|
69 |
bufp = seprint(bufp, bufe, "----------\n%s\n", (char*)c->header);
|
|
|
70 |
write(logfd, buf, bufp-buf); /* append-only file */
|
|
|
71 |
}
|
|
|
72 |
|
|
|
73 |
/* another log, with less information but formatted for common analysis tools */
|
|
|
74 |
if(logall[2] > 0 && strncmp(fmt, "Reply: ", 7) == 0){
|
|
|
75 |
objectsize = 0;
|
|
|
76 |
strecpy(statuscode, statuscode+4, fmt+7);
|
|
|
77 |
if( fmt[7] == '%'){
|
|
|
78 |
va_start(arg, fmt);
|
|
|
79 |
vseprint(statuscode, statuscode+4, fmt+7, arg);
|
|
|
80 |
va_end(arg);
|
|
|
81 |
}else if(
|
|
|
82 |
strcmp(fmt+7, "200 file %lld %lld\n") == 0 ||
|
|
|
83 |
strcmp(fmt+7, "206 partial content %lld %lld\n") == 0 ||
|
|
|
84 |
strcmp(fmt+7, "206 partial content, early termination %lld %lld\n") == 0){
|
|
|
85 |
va_start(arg, fmt);
|
|
|
86 |
objectsize = va_arg(arg, vlong); /* length in sendfd.c */
|
|
|
87 |
USED(objectsize);
|
|
|
88 |
objectsize = va_arg(arg, vlong); /* wrote in sendfd.c */
|
|
|
89 |
va_end(arg);
|
|
|
90 |
}
|
|
|
91 |
bufp = seprint(buf, bufe, "%s - -", p->remotesys);
|
|
|
92 |
bufp = seprint(bufp, bufe, " [%.2d/%s/%d:%.2d:%.2d:%.2d +0000]", tm->mday, monname[tm->mon], tm->year+1900, tm->hour, tm->min, tm->sec);
|
|
|
93 |
if(c->req.uri == nil || c->req.uri[0] == 0){
|
|
|
94 |
bufp = seprint(bufp, bufe, " \"%.*s\"",
|
|
|
95 |
(int)utfnlen((char*)c->header, strcspn((char*)c->header, "\r\n")),
|
|
|
96 |
(char*)c->header);
|
|
|
97 |
}else{
|
|
|
98 |
/* use more canonical form of URI, if available */
|
|
|
99 |
bufp = seprint(bufp, bufe, " \"%s %s HTTP/%d.%d\"", c->req.meth, c->req.uri, c->req.vermaj, c->req.vermin);
|
|
|
100 |
}
|
|
|
101 |
bufp = seprint(bufp, bufe, " %s %lld\n", statuscode, objectsize);
|
|
|
102 |
write(logall[2], buf, bufp-buf); /* append-only file */
|
|
|
103 |
}
|
|
|
104 |
}
|