github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/events/metrics.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package events 16 17 import ( 18 "sync/atomic" 19 "time" 20 21 "github.com/golang/protobuf/ptypes" 22 23 eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1" 24 ) 25 26 // EventMetric is an interface for getting the eventsapi.ClientEventMetric encoding of a metric 27 type EventMetric interface { 28 // AsClientEventMetrics gets the eventsapi.ClientEventMetric encoding of a metric 29 AsClientEventMetric() *eventsapi.ClientEventMetric 30 } 31 32 // Counter is a metric for counting 33 type Counter struct { 34 val int32 35 metricID eventsapi.MetricID 36 } 37 38 // NewCounter creates a new counter 39 func NewCounter(metricID eventsapi.MetricID) *Counter { 40 return &Counter{0, metricID} 41 } 42 43 // Inc incements a counter. This method happens atomically. 44 func (c *Counter) Inc() { 45 c.Add(1) 46 } 47 48 // Dec decrements a counter. This method happens atomically. 49 func (c *Counter) Dec() { 50 c.Add(-1) 51 } 52 53 // Add a positive or negative value to the current count. 54 func (c *Counter) Add(addend int32) { 55 atomic.AddInt32(&c.val, addend) 56 } 57 58 // AsClientEventMetrics gets the eventsapi.ClientEventMetric encoding of a metric 59 func (c *Counter) AsClientEventMetric() *eventsapi.ClientEventMetric { 60 return &eventsapi.ClientEventMetric{ 61 MetricId: c.metricID, 62 MetricOneof: &eventsapi.ClientEventMetric_Count{Count: c.val}, 63 } 64 } 65 66 // Timer a timer is used to time how long something ran for. 67 type Timer struct { 68 start time.Time 69 stop time.Time 70 metricID eventsapi.MetricID 71 } 72 73 // NewTimer creates a new timer and records the start time using the EventNowFunc 74 func NewTimer(metricID eventsapi.MetricID) *Timer { 75 return &Timer{EventNowFunc(), time.Time{}, metricID} 76 } 77 78 // Restart clears the timers end time and sets a new start time using the EventNowFunc 79 func (t *Timer) Restart() { 80 t.start = EventNowFunc() 81 t.stop = time.Time{} 82 } 83 84 // Stop sets the end time using the EventNowFunc 85 func (t *Timer) Stop() *Timer { 86 t.stop = EventNowFunc() 87 return t 88 } 89 90 // AsClientEventMetrics gets the eventsapi.ClientEventMetric encoding of a metric 91 func (t *Timer) AsClientEventMetric() *eventsapi.ClientEventMetric { 92 if t.stop.Equal(time.Time{}) { 93 panic("timer should be stopped before being added as a metric") 94 } 95 96 delta := t.stop.Sub(t.start) 97 d := ptypes.DurationProto(delta) 98 99 return &eventsapi.ClientEventMetric{ 100 MetricId: t.metricID, 101 MetricOneof: &eventsapi.ClientEventMetric_Duration{Duration: d}, 102 } 103 }