123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- // Package stats defines a lightweight interface for collecting statistics. It
- // doesn't provide an implementation, just the shared interface.
- package stats
-
- // Client provides methods to collection statistics.
- type Client interface {
- // BumpAvg bumps the average for the given key.
- BumpAvg(key string, val float64)
-
- // BumpSum bumps the sum for the given key.
- BumpSum(key string, val float64)
-
- // BumpHistogram bumps the histogram for the given key.
- BumpHistogram(key string, val float64)
-
- // BumpTime is a special version of BumpHistogram which is specialized for
- // timers. Calling it starts the timer, and it returns a value on which End()
- // can be called to indicate finishing the timer. A convenient way of
- // recording the duration of a function is calling it like such at the top of
- // the function:
- //
- // defer s.BumpTime("my.function").End()
- BumpTime(key string) interface {
- End()
- }
- }
-
- // PrefixClient adds multiple keys for the same value, with each prefix
- // added to the key and calls the underlying client.
- func PrefixClient(prefixes []string, client Client) Client {
- return &prefixClient{
- Prefixes: prefixes,
- Client: client,
- }
- }
-
- type prefixClient struct {
- Prefixes []string
- Client Client
- }
-
- func (p *prefixClient) BumpAvg(key string, val float64) {
- for _, prefix := range p.Prefixes {
- p.Client.BumpAvg(prefix+key, val)
- }
- }
-
- func (p *prefixClient) BumpSum(key string, val float64) {
- for _, prefix := range p.Prefixes {
- p.Client.BumpSum(prefix+key, val)
- }
- }
-
- func (p *prefixClient) BumpHistogram(key string, val float64) {
- for _, prefix := range p.Prefixes {
- p.Client.BumpHistogram(prefix+key, val)
- }
- }
-
- func (p *prefixClient) BumpTime(key string) interface {
- End()
- } {
- var m multiEnder
- for _, prefix := range p.Prefixes {
- m = append(m, p.Client.BumpTime(prefix+key))
- }
- return m
- }
-
- // multiEnder combines many enders together.
- type multiEnder []interface {
- End()
- }
-
- func (m multiEnder) End() {
- for _, e := range m {
- e.End()
- }
- }
-
- // HookClient is useful for testing. It provides optional hooks for each
- // expected method in the interface, which if provided will be called. If a
- // hook is not provided, it will be ignored.
- type HookClient struct {
- BumpAvgHook func(key string, val float64)
- BumpSumHook func(key string, val float64)
- BumpHistogramHook func(key string, val float64)
- BumpTimeHook func(key string) interface {
- End()
- }
- }
-
- // BumpAvg will call BumpAvgHook if defined.
- func (c *HookClient) BumpAvg(key string, val float64) {
- if c.BumpAvgHook != nil {
- c.BumpAvgHook(key, val)
- }
- }
-
- // BumpSum will call BumpSumHook if defined.
- func (c *HookClient) BumpSum(key string, val float64) {
- if c.BumpSumHook != nil {
- c.BumpSumHook(key, val)
- }
- }
-
- // BumpHistogram will call BumpHistogramHook if defined.
- func (c *HookClient) BumpHistogram(key string, val float64) {
- if c.BumpHistogramHook != nil {
- c.BumpHistogramHook(key, val)
- }
- }
-
- // BumpTime will call BumpTimeHook if defined.
- func (c *HookClient) BumpTime(key string) interface {
- End()
- } {
- if c.BumpTimeHook != nil {
- return c.BumpTimeHook(key)
- }
- return NoOpEnd
- }
-
- type noOpEnd struct{}
-
- func (n noOpEnd) End() {}
-
- // NoOpEnd provides a dummy value for use in tests as valid return value for
- // BumpTime().
- var NoOpEnd = noOpEnd{}
-
- // BumpAvg calls BumpAvg on the Client if it isn't nil. This is useful when a
- // component has an optional stats.Client.
- func BumpAvg(c Client, key string, val float64) {
- if c != nil {
- c.BumpAvg(key, val)
- }
- }
-
- // BumpSum calls BumpSum on the Client if it isn't nil. This is useful when a
- // component has an optional stats.Client.
- func BumpSum(c Client, key string, val float64) {
- if c != nil {
- c.BumpSum(key, val)
- }
- }
-
- // BumpHistogram calls BumpHistogram on the Client if it isn't nil. This is
- // useful when a component has an optional stats.Client.
- func BumpHistogram(c Client, key string, val float64) {
- if c != nil {
- c.BumpHistogram(key, val)
- }
- }
-
- // BumpTime calls BumpTime on the Client if it isn't nil. If the Client is nil
- // it still returns a valid return value which will be a no-op. This is useful
- // when a component has an optional stats.Client.
- func BumpTime(c Client, key string) interface {
- End()
- } {
- if c != nil {
- return c.BumpTime(key)
- }
- return NoOpEnd
- }
|