diff --git a/.gitignore b/.gitignore index 553b9d4a5..ad80fd9ea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ \#*\# .\#* .*.swp +logs diff --git a/website/camweb.go b/website/camweb.go index b54cca52f..1ca29df6e 100644 --- a/website/camweb.go +++ b/website/camweb.go @@ -40,7 +40,8 @@ var ( root = flag.String("root", "", "Website root (parent of 'static', 'content', and 'tmpl") gitwebScript = flag.String("gitwebscript", "/usr/lib/cgi-bin/gitweb.cgi", "Path to gitweb.cgi, or blank to disable.") gitwebFiles = flag.String("gitwebfiles", "/usr/share/gitweb", "Path to gitweb's static files.") - logDir = flag.String("logdir", "-", "Directory to write log files to (one per hour), \"-\" for stdout, or empty to not log.") + logDir = flag.String("logdir", "-", "Directory to write log files to (one per hour), or empty to not log.") + logStdout = flag.Bool("logstdout", true, "Write to stdout?") pageHtml, errorHtml *template.Template ) @@ -262,8 +263,8 @@ func main() { mux.HandleFunc("/", mainHandler) var handler http.Handler = &noWwwHandler{Handler: mux} - if *logDir != "" { - handler = NewLoggingHandler(handler, *logDir) + if *logDir != "" || *logStdout { + handler = NewLoggingHandler(handler, *logDir, *logStdout) } if err := http.ListenAndServe(*httpAddr, handler); err != nil { log.Exitf("ListenAndServe %s: %v", *httpAddr, err) diff --git a/website/logging.go b/website/logging.go index e4b5963fb..6819e6353 100644 --- a/website/logging.go +++ b/website/logging.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "io" + "log" "os" "http" "strings" @@ -23,15 +24,18 @@ type logRecord struct { type logHandler struct { ch chan *logRecord - dir string handler http.Handler + + dir string // or "" to not log + stdout bool } -func NewLoggingHandler(handler http.Handler, dir string) http.Handler { +func NewLoggingHandler(handler http.Handler, dir string, writeStdout bool) http.Handler { h := &logHandler{ ch: make(chan *logRecord, 1000), dir: dir, handler: handler, + stdout: writeStdout, } go h.logFromChannel() return h @@ -63,9 +67,10 @@ var monthAbbr = [12]string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"} func (h *logHandler) logFromChannel() { + lastFileName := "" + var logFile *os.File for { lr := <-h.ch - lr.rw = nil // [10/Oct/2000:13:55:36 -0700] dateString := fmt.Sprintf("%02d/%s/%04d:%02d:%02d:%02d -0000", @@ -74,6 +79,23 @@ func (h *logHandler) logFromChannel() { lr.time.Year, lr.time.Hour, lr.time.Minute, lr.time.Second) + if h.dir != "" { + fileName := fmt.Sprintf("%s/%04d-%02d-%02d%s%02d.log", h.dir, + lr.time.Year, lr.time.Month, lr.time.Day, "h", lr.time.Hour) + if fileName > lastFileName { + if logFile != nil { + logFile.Close() + } + var err os.Error + logFile, err = os.Open(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREAT, 0644) + if err != nil { + log.Printf("Error opening %q: %v", fileName, err) + continue + } + lastFileName = fileName + } + } + // Combined Log Format // http://httpd.apache.org/docs/1.3/logs.html#combined logLine := fmt.Sprintf("%s - - [%s] %q %d %d %q %q\n", @@ -85,9 +107,12 @@ func (h *logHandler) logFromChannel() { lr.referer, lr.userAgent, ) - if h.dir == "-" { + if h.stdout { os.Stdout.WriteString(logLine) } + if logFile != nil { + logFile.WriteString(logLine) + } } } diff --git a/website/run.sh b/website/run.sh index 9f4c0ebee..ddeeb3496 100755 --- a/website/run.sh +++ b/website/run.sh @@ -4,6 +4,10 @@ set -e Bin=$(dirname $( readlink -f $0)) +LOGDIR=$Bin/../logs +mkdir -p $LOGDIR + cd $Bin echo "Running camweb in $Bin" -../build.pl website && ./camweb --http=:8080 --root=$Bin +../build.pl website && ./camweb --http=:8080 --root=$Bin --logdir=$LOGDIR +