Skip to content

Commit

Permalink
feat: serve log
Browse files Browse the repository at this point in the history
  • Loading branch information
luopengift committed Jul 6, 2024
1 parent 5031232 commit 8bdbcea
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
4 changes: 3 additions & 1 deletion options.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ func RoundTripper(tr http.RoundTripper) Option {
// Logf print log
func Logf(f func(ctx context.Context, stat *Stat)) Option {
return func(o *Options) {
o.HttpRoundTripper = append(o.HttpRoundTripper, fprintf(f))
o.HttpRoundTripper = append(o.HttpRoundTripper, printRoundTripper(f))
o.HttpHandler = append(o.HttpHandler, printHandler(f))

}
}
5 changes: 5 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/golang-io/requests"
"io"
"log"
"net/http"
"testing"
"time"
Expand Down Expand Up @@ -40,6 +41,9 @@ func Test_Use(t *testing.T) {

r := requests.NewServeMux(
requests.Use(use("step1"), use("step2")),
requests.Logf(func(ctx context.Context, stat *requests.Stat) {
log.Printf("%s", stat.Print())
}),
)

r.Route("/echo", func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -70,6 +74,7 @@ func Test_Use(t *testing.T) {
_, _ = sess.DoRequest(context.Background(), requests.Path("/echo"), requests.Body("12345"), requests.Logf(LogS), requests.Method("GET"))
//sess.DoRequest(context.Background(), Path("/ping"), Logf(LogS))
//sess.DoRequest(context.Background(), Path("/1234"), Logf(LogS))
select {}

}

Expand Down
46 changes: 46 additions & 0 deletions stat.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package requests

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)

Expand Down Expand Up @@ -47,6 +49,14 @@ func (stat *Stat) String() string {
return string(b)
}

// PrintStat is used for server side
func (stat *Stat) Print() string {
return fmt.Sprintf("%s %s \"%s -> %s%s\" - %d %dB in %dms",
stat.StartAt, stat.Request.Method,
stat.Request.RemoteAddr, stat.Response.URL, stat.Request.URL,
stat.Response.StatusCode, stat.Response.ContentLength, stat.Cost)
}

// statLoad stat.
func responseLoad(resp *Response) *Stat {
stat := &Stat{
Expand Down Expand Up @@ -114,3 +124,39 @@ func responseLoad(resp *Response) *Stat {
}
return stat
}

func serveLoad(w *ResponseWriter, r *http.Request, start time.Time, buf *bytes.Buffer) *Stat {
stat := &Stat{
StartAt: start.Format("2006-01-02 15:04:05.000"),
Cost: time.Since(start).Milliseconds(),
}
stat.Request.RemoteAddr = r.RemoteAddr
stat.Request.Method = r.Method
stat.Request.Header = make(map[string]string)
for k, v := range r.Header {
stat.Request.Header[k] = v[0]
}
stat.Request.URL = r.URL.String()

if buf != nil {
m := make(map[string]any)
if err := json.Unmarshal(buf.Bytes(), &m); err != nil {
stat.Request.Body = buf.String()
} else {
stat.Request.Body = m
}
}
scheme := "http://"
if r.TLS != nil {
scheme = "https://"
}
stat.Response.URL = scheme + r.Host
stat.Response.StatusCode = w.StatusCode
stat.Response.ContentLength = int64(len(w.Content))
stat.Response.Header = make(map[string]string)
for k, v := range r.Header {
stat.Response.Header[k] = v[0]
}
stat.Response.Body = string(w.Content)
return stat
}
17 changes: 16 additions & 1 deletion transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (fn RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
}

// Stream 和Log不能共用
func fprintf(f func(ctx context.Context, stat *Stat)) func(http.RoundTripper) http.RoundTripper {
func printRoundTripper(f func(ctx context.Context, stat *Stat)) func(http.RoundTripper) http.RoundTripper {
resp := newResponse()
return func(next http.RoundTripper) http.RoundTripper {
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
Expand All @@ -42,6 +42,21 @@ func fprintf(f func(ctx context.Context, stat *Stat)) func(http.RoundTripper) ht
}
}

func printHandler(f func(ctx context.Context, stat *Stat)) func(handler http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := &ResponseWriter{ResponseWriter: w}
buf, body, _ := CopyBody(r.Body)
r.Body = body
defer func() {
f(r.Context(), serveLoad(ww, r, start, buf))
}()
next.ServeHTTP(ww, r)
})
}
}

type Transport struct {
opts []Option
*http.Transport
Expand Down

0 comments on commit 8bdbcea

Please sign in to comment.