github.com/best4tires/kit@v1.0.5/srv/timing.go (about) 1 package srv 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 "time" 8 ) 9 10 type timingItem struct { 11 name string 12 start time.Time 13 duration time.Duration 14 } 15 16 type Timing struct { 17 curr *timingItem 18 currAgg *timingItem 19 items []*timingItem 20 aggItems map[string]time.Duration 21 } 22 23 func NewTiming() *Timing { 24 return &Timing{ 25 aggItems: map[string]time.Duration{}, 26 } 27 } 28 29 func (t *Timing) Start(name string) { 30 now := time.Now() 31 if t.curr != nil { 32 t.curr.duration = now.Sub(t.curr.start) 33 t.items = append(t.items, t.curr) 34 } 35 t.curr = &timingItem{ 36 name: name, 37 start: now, 38 } 39 } 40 41 func (t *Timing) StartAgg(name string) { 42 now := time.Now() 43 if t.currAgg != nil { 44 t.currAgg.duration = now.Sub(t.currAgg.start) 45 t.aggItems[t.currAgg.name] += t.currAgg.duration 46 } 47 t.currAgg = &timingItem{ 48 name: name, 49 start: now, 50 } 51 } 52 53 func (t *Timing) StopCurrAgg() { 54 if t.currAgg != nil { 55 now := time.Now() 56 t.currAgg.duration = now.Sub(t.currAgg.start) 57 t.aggItems[t.currAgg.name] += t.currAgg.duration 58 t.currAgg = nil 59 } 60 } 61 62 func (t *Timing) Write(w http.ResponseWriter) { 63 now := time.Now() 64 if t.curr != nil { 65 t.curr.duration = now.Sub(t.curr.start) 66 t.items = append(t.items, t.curr) 67 t.curr = nil 68 } 69 var sl []string 70 for _, item := range t.items { 71 sl = append(sl, fmt.Sprintf("%s;dur=%d", item.name, item.duration.Milliseconds())) 72 } 73 t.StopCurrAgg() 74 for name, dur := range t.aggItems { 75 sl = append(sl, fmt.Sprintf("%s;dur=%d", name, dur.Milliseconds())) 76 } 77 w.Header().Add("Server-Timing", strings.Join(sl, ", ")) 78 }