-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathtimer.go
96 lines (84 loc) · 2.22 KB
/
timer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright (C) 2016 Space Monkey, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package monkit
import (
"sync"
"time"
"github.com/spacemonkeygo/monkit/v3/monotime"
)
// Timer is a threadsafe convenience wrapper around a DurationDist. You should
// construct with NewTimer(), though the expected usage is from a Scope like
// so:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// timer := mon.Timer("event")
// // perform event
// timer.Stop()
// ...
// }
//
// Timers implement StatSource.
type Timer struct {
mtx sync.Mutex
times *DurationDist
}
// NewTimer constructs a new Timer.
func NewTimer(key SeriesKey) *Timer {
return &Timer{times: NewDurationDist(key)}
}
// Start constructs a RunningTimer
func (t *Timer) Start() *RunningTimer {
return &RunningTimer{
start: monotime.Now(),
t: t}
}
// RunningTimer should be constructed from a Timer.
type RunningTimer struct {
start time.Time
t *Timer
stopped bool
}
// Elapsed just returns the amount of time since the timer started
func (r *RunningTimer) Elapsed() time.Duration {
return time.Since(r.start)
}
// Stop stops the timer, adds the duration to the statistics information, and
// returns the elapsed time.
func (r *RunningTimer) Stop() time.Duration {
elapsed := r.Elapsed()
r.t.mtx.Lock()
if !r.stopped {
r.t.times.Insert(elapsed)
r.stopped = true
}
r.t.mtx.Unlock()
return elapsed
}
// Values returns the main timer values
func (t *Timer) Values() *DurationDist {
t.mtx.Lock()
rv := t.times.Copy()
t.mtx.Unlock()
return rv
}
// Stats implements the StatSource interface
func (t *Timer) Stats(cb func(key SeriesKey, field string, val float64)) {
t.mtx.Lock()
times := t.times.Copy()
t.mtx.Unlock()
times.Stats(cb)
}