|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/jordanorelli/serve/termcolors"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type logWrapper struct {
|
|
|
|
http.Handler
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *logWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.URL.Path == "/favicon.ico" {
|
|
|
|
l.Handler.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
id := newRequestId()
|
|
|
|
if IsTerminal(os.Stdout.Fd()) {
|
|
|
|
log.Println(termcolors.WrapString(termcolors.Magenta, id.String()), r.Method, r.URL)
|
|
|
|
} else {
|
|
|
|
log.Println(id, r.Method, r.URL)
|
|
|
|
}
|
|
|
|
statsThing := &writerWatcher{ResponseWriter: w}
|
|
|
|
start := time.Now()
|
|
|
|
l.Handler.ServeHTTP(statsThing, r)
|
|
|
|
log.Println(id, statsThing.PrettyStatus(), statsThing.written, time.Since(start))
|
|
|
|
}
|
|
|
|
|
|
|
|
type writerWatcher struct {
|
|
|
|
http.ResponseWriter
|
|
|
|
written int
|
|
|
|
headerWritten int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *writerWatcher) Write(b []byte) (int, error) {
|
|
|
|
n, err := w.ResponseWriter.Write(b)
|
|
|
|
w.written += n
|
|
|
|
return n, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *writerWatcher) WriteHeader(status int) {
|
|
|
|
if w.headerWritten != 0 {
|
|
|
|
log.Println("somehow we wrote two headers.")
|
|
|
|
}
|
|
|
|
w.headerWritten = status
|
|
|
|
w.ResponseWriter.WriteHeader(status)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *writerWatcher) PrettyStatus() string {
|
|
|
|
s := strconv.Itoa(w.headerWritten)
|
|
|
|
if !IsTerminal(os.Stdout.Fd()) {
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
switch {
|
|
|
|
case w.headerWritten == 0:
|
|
|
|
return termcolors.WrapString(termcolors.Green, "200")
|
|
|
|
case w.headerWritten < 200:
|
|
|
|
return termcolors.WrapString(termcolors.White, s)
|
|
|
|
case w.headerWritten < 300:
|
|
|
|
return termcolors.WrapString(termcolors.Green, s)
|
|
|
|
case w.headerWritten < 400:
|
|
|
|
return termcolors.WrapString(termcolors.White, s)
|
|
|
|
case w.headerWritten < 500:
|
|
|
|
return termcolors.WrapString(termcolors.Yellow, s)
|
|
|
|
default:
|
|
|
|
return termcolors.WrapString(termcolors.Red, s)
|
|
|
|
}
|
|
|
|
}
|