add request elapsed time
This commit is contained in:
parent
857808cd37
commit
d312f00d0d
16
capture.go
16
capture.go
|
@ -4,10 +4,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var captureID int
|
var captureID int
|
||||||
var captures CaptureList
|
|
||||||
|
|
||||||
// CaptureList stores all captures
|
// CaptureList stores all captures
|
||||||
type CaptureList struct {
|
type CaptureList struct {
|
||||||
|
@ -22,6 +22,9 @@ type Capture struct {
|
||||||
ID int
|
ID int
|
||||||
Req *http.Request
|
Req *http.Request
|
||||||
Res *http.Response
|
Res *http.Response
|
||||||
|
|
||||||
|
// Elapsed time of the request, in milliseconds
|
||||||
|
Elapsed time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureMetadata is the data for each list item in the dashboard
|
// CaptureMetadata is the data for each list item in the dashboard
|
||||||
|
@ -30,6 +33,8 @@ type CaptureMetadata struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
|
|
||||||
|
Elapsed time.Duration `json:"elapsed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureDump saves all the dumps shown in the dashboard
|
// CaptureDump saves all the dumps shown in the dashboard
|
||||||
|
@ -42,10 +47,11 @@ type CaptureDump struct {
|
||||||
// Metadata returns the metadada of a capture
|
// Metadata returns the metadada of a capture
|
||||||
func (c *Capture) Metadata() CaptureMetadata {
|
func (c *Capture) Metadata() CaptureMetadata {
|
||||||
return CaptureMetadata{
|
return CaptureMetadata{
|
||||||
ID: c.ID,
|
ID: c.ID,
|
||||||
Path: c.Req.URL.Path,
|
Path: c.Req.URL.Path,
|
||||||
Method: c.Req.Method,
|
Method: c.Req.Method,
|
||||||
Status: c.Res.StatusCode,
|
Status: c.Res.StatusCode,
|
||||||
|
Elapsed: c.Elapsed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ const dashboardHTML = `
|
||||||
--status-error: #e06c75;
|
--status-error: #e06c75;
|
||||||
--btn-bg: var(--list-item-bg);
|
--btn-bg: var(--list-item-bg);
|
||||||
--btn-hover: var(--list-item-sel-bg);
|
--btn-hover: var(--list-item-sel-bg);
|
||||||
|
--disabled: hsl(187, 5%, 50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
* { padding: 0; margin: 0; box-sizing: border-box }
|
* { padding: 0; margin: 0; box-sizing: border-box }
|
||||||
|
@ -104,6 +105,7 @@ const dashboardHTML = `
|
||||||
.method { font-size: 0.7em; margin-right: 1rem; padding: .25rem .5rem }
|
.method { font-size: 0.7em; margin-right: 1rem; padding: .25rem .5rem }
|
||||||
.status { font-size: 0.8em; padding-left: 1rem }
|
.status { font-size: 0.8em; padding-left: 1rem }
|
||||||
.path { font-size: 0.8em; flex: 1; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl }
|
.path { font-size: 0.8em; flex: 1; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl }
|
||||||
|
.time { font-size: 0.7em; padding-left: 1rem; color: var(--disabled) }
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -148,7 +150,7 @@ const dashboardHTML = `
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
button:disabled {
|
button:disabled {
|
||||||
color: hsl(187, 5%, 50%);
|
color: var(--disabled);
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
button:hover:enabled {
|
button:hover:enabled {
|
||||||
|
@ -190,6 +192,7 @@ const dashboardHTML = `
|
||||||
<span class="method" ng-class="item.method">{{item.method}}</span>
|
<span class="method" ng-class="item.method">{{item.method}}</span>
|
||||||
<span class="path">‎{{item.path}}‎</span>
|
<span class="path">‎{{item.path}}‎</span>
|
||||||
<span class="status" ng-class="statusColor(item)">{{item.status == 999 ? 'failed' : item.status}}</span>
|
<span class="status" ng-class="statusColor(item)">{{item.status == 999 ? 'failed' : item.status}}</span>
|
||||||
|
<span class="time">{{item.elapsed}}ms</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
7
main.go
7
main.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"plugin"
|
"plugin"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ofabricio/curl"
|
"github.com/ofabricio/curl"
|
||||||
)
|
)
|
||||||
|
@ -178,8 +179,12 @@ func NewRecorder(list *CaptureList, next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
next.ServeHTTP(rec, req)
|
next.ServeHTTP(rec, req)
|
||||||
|
|
||||||
|
elapsed := time.Since(start).Truncate(time.Millisecond) / time.Millisecond
|
||||||
|
|
||||||
// respond
|
// respond
|
||||||
for k, v := range rec.Header() {
|
for k, v := range rec.Header() {
|
||||||
rw.Header()[k] = v
|
rw.Header()[k] = v
|
||||||
|
@ -190,7 +195,7 @@ func NewRecorder(list *CaptureList, next http.HandlerFunc) http.HandlerFunc {
|
||||||
// record req and res
|
// record req and res
|
||||||
req.Body = ioutil.NopCloser(bytes.NewReader(reqBody))
|
req.Body = ioutil.NopCloser(bytes.NewReader(reqBody))
|
||||||
res := rec.Result()
|
res := rec.Result()
|
||||||
list.Insert(Capture{Req: req, Res: res})
|
list.Insert(Capture{Req: req, Res: res, Elapsed: elapsed})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue