180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include "httpd.h"
480ee5cbfSDavid du Colombier #include "httpsrv.h"
580ee5cbfSDavid du Colombier
6499069deSDavid du Colombier int logall[3]; /* logall[2] is in "Common Log Format" */
7499069deSDavid du Colombier
8499069deSDavid du Colombier static char *
9499069deSDavid du Colombier monname[12] =
10499069deSDavid du Colombier {
11499069deSDavid du Colombier "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
12499069deSDavid du Colombier };
1380ee5cbfSDavid du Colombier
1480ee5cbfSDavid du Colombier void
logit(HConnect * c,char * fmt,...)1580ee5cbfSDavid du Colombier logit(HConnect *c, char *fmt, ...)
1680ee5cbfSDavid du Colombier {
1780ee5cbfSDavid du Colombier char buf[4096];
1880ee5cbfSDavid du Colombier va_list arg;
1980ee5cbfSDavid du Colombier HSPriv *p;
2080ee5cbfSDavid du Colombier
2180ee5cbfSDavid du Colombier va_start(arg, fmt);
229a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
2380ee5cbfSDavid du Colombier va_end(arg);
2480ee5cbfSDavid du Colombier p = nil;
2580ee5cbfSDavid du Colombier if(c != nil)
2680ee5cbfSDavid du Colombier p = c->private;
2780ee5cbfSDavid du Colombier if(p != nil && p->remotesys != nil)
2880ee5cbfSDavid du Colombier syslog(0, HTTPLOG, "%s %s", p->remotesys, buf);
2980ee5cbfSDavid du Colombier else
3080ee5cbfSDavid du Colombier syslog(0, HTTPLOG, "%s", buf);
3180ee5cbfSDavid du Colombier }
3280ee5cbfSDavid du Colombier
3380ee5cbfSDavid du Colombier void
writelog(HConnect * c,char * fmt,...)3480ee5cbfSDavid du Colombier writelog(HConnect *c, char *fmt, ...)
3580ee5cbfSDavid du Colombier {
3680ee5cbfSDavid du Colombier HSPriv *p;
3780ee5cbfSDavid du Colombier char buf[HBufSize+500], *bufp, *bufe;
38499069deSDavid du Colombier char statuscode[4];
39499069deSDavid du Colombier vlong objectsize;
4080ee5cbfSDavid du Colombier ulong now, today;
4180ee5cbfSDavid du Colombier int logfd;
4280ee5cbfSDavid du Colombier va_list arg;
43499069deSDavid du Colombier Tm *tm;
4480ee5cbfSDavid du Colombier
45499069deSDavid du Colombier if(c == nil)
46499069deSDavid du Colombier return;
47108f07eeSDavid du Colombier p = c->private;
4880ee5cbfSDavid du Colombier bufe = buf + sizeof(buf);
4980ee5cbfSDavid du Colombier now = time(nil);
50499069deSDavid du Colombier tm = gmtime(now);
5180ee5cbfSDavid du Colombier today = now / (24*60*60);
52499069deSDavid du Colombier
53499069deSDavid du Colombier /* verbose logfile, for research on web traffic */
5480ee5cbfSDavid du Colombier logfd = logall[today & 1];
55499069deSDavid du Colombier if(logfd > 0){
5680ee5cbfSDavid du Colombier if(c->hstop == c->header || c->hstop[-1] != '\n')
5780ee5cbfSDavid du Colombier *c->hstop = '\n';
5880ee5cbfSDavid du Colombier *c->hstop = '\0';
5980ee5cbfSDavid du Colombier bufp = seprint(buf, bufe, "==========\n");
6080ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "LogTime: %D\n", now);
6180ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "ConnTime: %D\n", c->reqtime);
6280ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "RemoteIP: %s\n", p->remotesys);
6380ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "Port: %s\n", p->remoteserv);
6480ee5cbfSDavid du Colombier va_start(arg, fmt);
659a747e4fSDavid du Colombier bufp = vseprint(bufp, bufe, fmt, arg);
6680ee5cbfSDavid du Colombier va_end(arg);
6780ee5cbfSDavid du Colombier if(c->req.uri != nil && c->req.uri[0] != 0)
6880ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "FinalURI: %s\n", c->req.uri);
6980ee5cbfSDavid du Colombier bufp = seprint(bufp, bufe, "----------\n%s\n", (char*)c->header);
7080ee5cbfSDavid du Colombier write(logfd, buf, bufp-buf); /* append-only file */
7180ee5cbfSDavid du Colombier }
72499069deSDavid du Colombier
73499069deSDavid du Colombier /* another log, with less information but formatted for common analysis tools */
74499069deSDavid du Colombier if(logall[2] > 0 && strncmp(fmt, "Reply: ", 7) == 0){
75499069deSDavid du Colombier objectsize = 0;
76499069deSDavid du Colombier strecpy(statuscode, statuscode+4, fmt+7);
77499069deSDavid du Colombier if( fmt[7] == '%'){
78499069deSDavid du Colombier va_start(arg, fmt);
79499069deSDavid du Colombier vseprint(statuscode, statuscode+4, fmt+7, arg);
80499069deSDavid du Colombier va_end(arg);
81499069deSDavid du Colombier }else if(
82499069deSDavid du Colombier strcmp(fmt+7, "200 file %lld %lld\n") == 0 ||
83499069deSDavid du Colombier strcmp(fmt+7, "206 partial content %lld %lld\n") == 0 ||
84499069deSDavid du Colombier strcmp(fmt+7, "206 partial content, early termination %lld %lld\n") == 0){
85499069deSDavid du Colombier va_start(arg, fmt);
86499069deSDavid du Colombier objectsize = va_arg(arg, vlong); /* length in sendfd.c */
87*b8914692SDavid du Colombier USED(objectsize);
88499069deSDavid du Colombier objectsize = va_arg(arg, vlong); /* wrote in sendfd.c */
89499069deSDavid du Colombier va_end(arg);
90499069deSDavid du Colombier }
91499069deSDavid du Colombier bufp = seprint(buf, bufe, "%s - -", p->remotesys);
92499069deSDavid du Colombier 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);
93499069deSDavid du Colombier if(c->req.uri == nil || c->req.uri[0] == 0){
94499069deSDavid du Colombier bufp = seprint(bufp, bufe, " \"%.*s\"",
95499069deSDavid du Colombier (int)utfnlen((char*)c->header, strcspn((char*)c->header, "\r\n")),
96499069deSDavid du Colombier (char*)c->header);
97499069deSDavid du Colombier }else{
98499069deSDavid du Colombier /* use more canonical form of URI, if available */
99499069deSDavid du Colombier bufp = seprint(bufp, bufe, " \"%s %s HTTP/%d.%d\"", c->req.meth, c->req.uri, c->req.vermaj, c->req.vermin);
100499069deSDavid du Colombier }
101499069deSDavid du Colombier bufp = seprint(bufp, bufe, " %s %lld\n", statuscode, objectsize);
102499069deSDavid du Colombier write(logall[2], buf, bufp-buf); /* append-only file */
103499069deSDavid du Colombier }
104499069deSDavid du Colombier }
105