Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions internal/uplog/request_uplog.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (uplog *RequestUplog) Intercept(req *http.Request, handler clientv2.Handler
},
GotFirstResponseByte: func() {
if !wroteRequestTime.IsZero() {
uplog.WaitElapsedTime = getElapsedTime(wroteRequestTime)
atomic.StoreUint64(&uplog.WaitElapsedTime, getElapsedTime(wroteRequestTime))
}
gotFirstResponseByteTime = time.Now()
},
Expand All @@ -143,31 +143,31 @@ func (uplog *RequestUplog) Intercept(req *http.Request, handler clientv2.Handler
},
DNSDone: func(info httptrace.DNSDoneInfo) {
if !dnsStartTime.IsZero() {
uplog.DNSElapsedTime = getElapsedTime(dnsStartTime)
atomic.StoreUint64(&uplog.DNSElapsedTime, getElapsedTime(dnsStartTime))
}
},
ConnectStart: func(network string, addr string) {
connectStartTime = time.Now()
},
ConnectDone: func(network string, addr string, err error) {
if !connectStartTime.IsZero() {
uplog.ConnectElapsedTime = getElapsedTime(connectStartTime)
atomic.StoreUint64(&uplog.ConnectElapsedTime, getElapsedTime(connectStartTime))
}
},
TLSHandshakeStart: func() {
tlsHandshakeStartTime = time.Now()
},
TLSHandshakeDone: func(tls.ConnectionState, error) {
if !tlsHandshakeStartTime.IsZero() {
uplog.TLSConnectElapsedTime = getElapsedTime(tlsHandshakeStartTime)
atomic.StoreUint64(&uplog.TLSConnectElapsedTime, getElapsedTime(tlsHandshakeStartTime))
}
},
WroteHeaders: func() {
wroteHeadersTime = time.Now()
},
WroteRequest: func(info httptrace.WroteRequestInfo) {
if !wroteHeadersTime.IsZero() {
uplog.RequestElapsedTime = getElapsedTime(wroteHeadersTime)
atomic.StoreUint64(&uplog.RequestElapsedTime, getElapsedTime(wroteHeadersTime))
}
wroteRequestTime = time.Now()
},
Expand All @@ -177,9 +177,9 @@ func (uplog *RequestUplog) Intercept(req *http.Request, handler clientv2.Handler
uplog.UpTime = beginAt.Unix()
resp, err = handler(req)
if !gotFirstResponseByteTime.IsZero() {
uplog.ResponseElapsedTime = getElapsedTime(gotFirstResponseByteTime)
atomic.StoreUint64(&uplog.ResponseElapsedTime, getElapsedTime(gotFirstResponseByteTime))
}
uplog.TotalElapsedTime = getElapsedTime(beginAt)
atomic.StoreUint64(&uplog.TotalElapsedTime, getElapsedTime(beginAt))
if err != nil {
uplog.ErrorType, uplog.ErrorDescription = uplog.detect(resp, err)
uplog.ErrorDescription = truncate(uplog.ErrorDescription, maxFieldValueLength)
Expand Down Expand Up @@ -208,19 +208,37 @@ func (uplog *RequestUplog) Intercept(req *http.Request, handler clientv2.Handler
}
}
}
if uplog.TotalElapsedTime > 0 {
totalElapsedTime := atomic.LoadUint64(&uplog.TotalElapsedTime)
if totalElapsedTime > 0 {
if uplog.BytesSent > uplog.BytesReceived {
uplog.PerceptiveSpeed = uplog.BytesSent * 1000 / int64(uplog.TotalElapsedTime)
uplog.PerceptiveSpeed = uplog.BytesSent * 1000 / int64(totalElapsedTime)
} else {
uplog.PerceptiveSpeed = uplog.BytesReceived * 1000 / int64(uplog.TotalElapsedTime)
uplog.PerceptiveSpeed = uplog.BytesReceived * 1000 / int64(totalElapsedTime)
}
}
if uplogBytes, jsonError := json.Marshal(uplog); jsonError == nil {
if uplogBytes, jsonError := json.Marshal(uplog.atomicSnapshot()); jsonError == nil {
uplogChan <- uplogSerializedEntry{serializedUplog: uplogBytes, getUpToken: uplog.getUpToken}
}
return
}

// atomicSnapshot creates a thread-safe copy of the RequestUplog struct by
// atomically reading the timing fields that may be concurrently modified
func (uplog *RequestUplog) atomicSnapshot() RequestUplog {
snapshot := *uplog // Copy all fields first

// Atomically read the timing fields that are modified concurrently
snapshot.TotalElapsedTime = atomic.LoadUint64(&uplog.TotalElapsedTime)
snapshot.DNSElapsedTime = atomic.LoadUint64(&uplog.DNSElapsedTime)
snapshot.ConnectElapsedTime = atomic.LoadUint64(&uplog.ConnectElapsedTime)
snapshot.TLSConnectElapsedTime = atomic.LoadUint64(&uplog.TLSConnectElapsedTime)
snapshot.RequestElapsedTime = atomic.LoadUint64(&uplog.RequestElapsedTime)
snapshot.WaitElapsedTime = atomic.LoadUint64(&uplog.WaitElapsedTime)
snapshot.ResponseElapsedTime = atomic.LoadUint64(&uplog.ResponseElapsedTime)

return snapshot
}

func (uplog *RequestUplog) detect(response *http.Response, err error) (errorType ErrorType, errorDescription string) {
if err == nil {
if response.StatusCode >= 300 {
Expand Down
Loading