github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/httplogger/log.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package httplogger 6 7 import ( 8 "fmt" 9 "net/http" 10 "strings" 11 "sync" 12 "time" 13 ) 14 15 func New(t http.RoundTripper) http.RoundTripper { 16 return &loggingTransport{transport: t} 17 } 18 19 type loggingTransport struct { 20 transport http.RoundTripper 21 mu sync.Mutex 22 active []byte 23 } 24 25 func (t *loggingTransport) RoundTrip(r *http.Request) (*http.Response, error) { 26 t.mu.Lock() 27 index := len(t.active) 28 start := time.Now() 29 fmt.Printf("HTTP: %s %s+ %s\n", timeFormat(start), t.active, r.URL) 30 t.active = append(t.active, '|') 31 t.mu.Unlock() 32 33 resp, err := t.transport.RoundTrip(r) 34 35 last := r.URL.Path 36 if i := strings.LastIndex(last, "/"); i >= 0 { 37 last = last[i:] 38 } 39 display := last 40 if resp != nil { 41 display += " " + resp.Status 42 } 43 if err != nil { 44 display += " error: " + err.Error() 45 } 46 now := time.Now() 47 48 t.mu.Lock() 49 t.active[index] = '-' 50 fmt.Printf("HTTP: %s %s %s (%.3fs)\n", timeFormat(now), t.active, display, now.Sub(start).Seconds()) 51 t.active[index] = ' ' 52 n := len(t.active) 53 for n%4 == 0 && n >= 4 && t.active[n-1] == ' ' && t.active[n-2] == ' ' && t.active[n-3] == ' ' && t.active[n-4] == ' ' { 54 t.active = t.active[:n-4] 55 n -= 4 56 } 57 t.mu.Unlock() 58 59 return resp, err 60 } 61 62 func timeFormat(t time.Time) string { 63 return t.Format("15:04:05.000") 64 }