Update dependencies
This commit is contained in:
147
vendor/github.com/tcnksm/go-httpstat/httpstat.go
generated
vendored
Normal file
147
vendor/github.com/tcnksm/go-httpstat/httpstat.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// Package httpstat traces HTTP latency infomation (DNSLookup, TCP Connection and so on) on any golang HTTP request.
|
||||
// It uses `httptrace` package. Just create `go-httpstat` powered `context.Context` and give it your `http.Request` (no big code modification is required).
|
||||
package httpstat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Result stores httpstat info.
|
||||
type Result struct {
|
||||
// The following are duration for each phase
|
||||
DNSLookup time.Duration
|
||||
TCPConnection time.Duration
|
||||
TLSHandshake time.Duration
|
||||
ServerProcessing time.Duration
|
||||
contentTransfer time.Duration
|
||||
|
||||
// The followings are timeline of request
|
||||
NameLookup time.Duration
|
||||
Connect time.Duration
|
||||
Pretransfer time.Duration
|
||||
StartTransfer time.Duration
|
||||
total time.Duration
|
||||
|
||||
t0 time.Time
|
||||
t1 time.Time
|
||||
t2 time.Time
|
||||
t3 time.Time
|
||||
t4 time.Time
|
||||
t5 time.Time // need to be provided from outside
|
||||
|
||||
dnsStart time.Time
|
||||
dnsDone time.Time
|
||||
tcpStart time.Time
|
||||
tcpDone time.Time
|
||||
tlsStart time.Time
|
||||
tlsDone time.Time
|
||||
serverStart time.Time
|
||||
serverDone time.Time
|
||||
transferStart time.Time
|
||||
trasferDone time.Time // need to be provided from outside
|
||||
|
||||
// isTLS is true when connection seems to use TLS
|
||||
isTLS bool
|
||||
|
||||
// isReused is true when connection is reused (keep-alive)
|
||||
isReused bool
|
||||
}
|
||||
|
||||
func (r *Result) durations() map[string]time.Duration {
|
||||
return map[string]time.Duration{
|
||||
"DNSLookup": r.DNSLookup,
|
||||
"TCPConnection": r.TCPConnection,
|
||||
"TLSHandshake": r.TLSHandshake,
|
||||
"ServerProcessing": r.ServerProcessing,
|
||||
"ContentTransfer": r.contentTransfer,
|
||||
|
||||
"NameLookup": r.NameLookup,
|
||||
"Connect": r.Connect,
|
||||
"Pretransfer": r.Connect,
|
||||
"StartTransfer": r.StartTransfer,
|
||||
"Total": r.total,
|
||||
}
|
||||
}
|
||||
|
||||
// ContentTransfer returns the duration of content transfer time.
|
||||
// It is from first response byte to the given time. The time must
|
||||
// be time after read body (go-httpstat can not detect that time).
|
||||
func (r *Result) ContentTransfer(t time.Time) time.Duration {
|
||||
return t.Sub(r.t4)
|
||||
}
|
||||
|
||||
// Total returns the duration of total http request.
|
||||
// It is from dns lookup start time to the given time. The
|
||||
// time must be time after read body (go-httpstat can not detect that time).
|
||||
func (r *Result) Total(t time.Time) time.Duration {
|
||||
return t.Sub(r.t0)
|
||||
}
|
||||
|
||||
// Format formats stats result.
|
||||
func (r Result) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
if s.Flag('+') {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "DNS lookup: %4d ms\n",
|
||||
int(r.DNSLookup/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "TCP connection: %4d ms\n",
|
||||
int(r.TCPConnection/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "TLS handshake: %4d ms\n",
|
||||
int(r.TLSHandshake/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "Server processing: %4d ms\n",
|
||||
int(r.ServerProcessing/time.Millisecond))
|
||||
|
||||
if !r.t5.IsZero() {
|
||||
fmt.Fprintf(&buf, "Content transfer: %4d ms\n\n",
|
||||
int(r.contentTransfer/time.Millisecond))
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "Content transfer: %4s ms\n\n", "-")
|
||||
}
|
||||
|
||||
fmt.Fprintf(&buf, "Name Lookup: %4d ms\n",
|
||||
int(r.NameLookup/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "Connect: %4d ms\n",
|
||||
int(r.Connect/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "Pre Transfer: %4d ms\n",
|
||||
int(r.Pretransfer/time.Millisecond))
|
||||
fmt.Fprintf(&buf, "Start Transfer: %4d ms\n",
|
||||
int(r.StartTransfer/time.Millisecond))
|
||||
|
||||
if !r.t5.IsZero() {
|
||||
fmt.Fprintf(&buf, "Total: %4d ms\n",
|
||||
int(r.total/time.Millisecond))
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "Total: %4s ms\n", "-")
|
||||
}
|
||||
io.WriteString(s, buf.String())
|
||||
return
|
||||
}
|
||||
|
||||
fallthrough
|
||||
case 's', 'q':
|
||||
d := r.durations()
|
||||
list := make([]string, 0, len(d))
|
||||
for k, v := range d {
|
||||
// Handle when End function is not called
|
||||
if (k == "ContentTransfer" || k == "Total") && r.t5.IsZero() {
|
||||
list = append(list, fmt.Sprintf("%s: - ms", k))
|
||||
continue
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s: %d ms", k, v/time.Millisecond))
|
||||
}
|
||||
io.WriteString(s, strings.Join(list, ", "))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// WithHTTPStat is a wrapper of httptrace.WithClientTrace. It records the
|
||||
// time of each httptrace hooks.
|
||||
func WithHTTPStat(ctx context.Context, r *Result) context.Context {
|
||||
return withClientTrace(ctx, r)
|
||||
}
|
||||
Reference in New Issue
Block a user