Merge pull request #1283 from letsencrypt/metrics_scope
add metrics.Scope
This commit is contained in:
commit
26b51e7a90
|
|
@ -0,0 +1,138 @@
|
|||
// Automatically generated by MockGen. DO NOT EDIT!
|
||||
// Source: github.com/cactus/go-statsd-client/statsd (interfaces: Statter)
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
gomock "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/golang/mock/gomock"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Mock of Statter interface
|
||||
type MockStatter struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *_MockStatterRecorder
|
||||
}
|
||||
|
||||
// Recorder for MockStatter (not exported)
|
||||
type _MockStatterRecorder struct {
|
||||
mock *MockStatter
|
||||
}
|
||||
|
||||
func NewMockStatter(ctrl *gomock.Controller) *MockStatter {
|
||||
mock := &MockStatter{ctrl: ctrl}
|
||||
mock.recorder = &_MockStatterRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (_m *MockStatter) EXPECT() *_MockStatterRecorder {
|
||||
return _m.recorder
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Close() error {
|
||||
ret := _m.ctrl.Call(_m, "Close")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Close() *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Close")
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Dec(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Dec", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Dec(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Dec", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Gauge(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Gauge", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Gauge(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Gauge", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) GaugeDelta(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "GaugeDelta", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) GaugeDelta(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "GaugeDelta", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Inc(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Inc", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Inc(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Inc", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Raw(_param0 string, _param1 string, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Raw", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Raw(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Raw", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Set(_param0 string, _param1 string, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Set", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Set(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Set", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) SetInt(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "SetInt", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) SetInt(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "SetInt", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) SetPrefix(_param0 string) {
|
||||
_m.ctrl.Call(_m, "SetPrefix", _param0)
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) SetPrefix(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "SetPrefix", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) Timing(_param0 string, _param1 int64, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "Timing", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) Timing(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Timing", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
func (_m *MockStatter) TimingDuration(_param0 string, _param1 time.Duration, _param2 float32) error {
|
||||
ret := _m.ctrl.Call(_m, "TimingDuration", _param0, _param1, _param2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockStatterRecorder) TimingDuration(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "TimingDuration", arg0, arg1, arg2)
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright 2015 ISRG. All rights reserved
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:generate sh -c "mockgen -package metrics github.com/cactus/go-statsd-client/statsd Statter > ./mock_statsd_test.go && sed -i '' -e 's:github.com/golang/mock/gomock:github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/golang/mock/gomock:' ./mock_statsd_test.go"
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
||||
)
|
||||
|
||||
// Scope is a stats collector that will prefix the name the stats it
|
||||
// collects.
|
||||
type Scope interface {
|
||||
NewScope(scopes ...string) Scope
|
||||
Scope() string
|
||||
|
||||
Inc(stat string, value int64) error
|
||||
Dec(stat string, value int64) error
|
||||
Gauge(stat string, value int64) error
|
||||
GaugeDelta(stat string, value int64) error
|
||||
Timing(stat string, delta int64) error
|
||||
TimingDuration(stat string, delta time.Duration) error
|
||||
Set(stat string, value string) error
|
||||
SetInt(stat string, value int64) error
|
||||
Raw(stat string, value string) error
|
||||
}
|
||||
|
||||
// StatsdScope is a Scope that sends data to statsd with a prefix added to the
|
||||
// stat names.
|
||||
type StatsdScope struct {
|
||||
prefix string
|
||||
statter statsd.Statter
|
||||
}
|
||||
|
||||
var _ Scope = &StatsdScope{}
|
||||
|
||||
// NewStatsdScope returns a StatsdScope that prefixes stats it collections with
|
||||
// the scopes given joined together by periods
|
||||
func NewStatsdScope(statter statsd.Statter, scopes ...string) *StatsdScope {
|
||||
return &StatsdScope{
|
||||
prefix: strings.Join(scopes, ".") + ".",
|
||||
statter: statter,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNoopScope returns a Scope that won't collect anything
|
||||
func NewNoopScope() Scope {
|
||||
c, _ := statsd.NewNoopClient()
|
||||
return NewStatsdScope(c, "noop")
|
||||
}
|
||||
|
||||
// NewScope generates a new Scope prefixed by this Scope's prefix plus the
|
||||
// prefixes given joined by periods
|
||||
func (s *StatsdScope) NewScope(scopes ...string) Scope {
|
||||
scope := strings.Join(scopes, ".")
|
||||
return NewStatsdScope(s.statter, s.prefix+scope)
|
||||
}
|
||||
|
||||
// Scope returns the current string prefix (except for the final period) that
|
||||
// stats will receive
|
||||
func (s *StatsdScope) Scope() string {
|
||||
return s.prefix[:len(s.prefix)-1]
|
||||
}
|
||||
|
||||
// Inc increments the given stat and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) Inc(stat string, value int64) error {
|
||||
return s.statter.Inc(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// Dec decrements the given stat and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) Dec(stat string, value int64) error {
|
||||
return s.statter.Dec(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// Gauge sends a gauge stat and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) Gauge(stat string, value int64) error {
|
||||
return s.statter.Gauge(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// GaugeDelta sends the change in a gauge stat and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) GaugeDelta(stat string, value int64) error {
|
||||
return s.statter.GaugeDelta(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// Timing sends a latency stat and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) Timing(stat string, delta int64) error {
|
||||
return s.statter.Timing(s.prefix+stat, delta, 1.0)
|
||||
}
|
||||
|
||||
// TimingDuration sends a latency stat as a time.Duration and adds the Scope's
|
||||
// prefix to the name
|
||||
func (s *StatsdScope) TimingDuration(stat string, delta time.Duration) error {
|
||||
return s.statter.TimingDuration(s.prefix+stat, delta, 1.0)
|
||||
}
|
||||
|
||||
// Set sets a stat's new value and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) Set(stat string, value string) error {
|
||||
return s.statter.Set(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// SetInt sets a stat's integer value and adds the Scope's prefix to the name
|
||||
func (s *StatsdScope) SetInt(stat string, value int64) error {
|
||||
return s.statter.SetInt(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
||||
// Raw sends a stat value without interpretation and adds the Scope's prefix to
|
||||
// the name
|
||||
func (s *StatsdScope) Raw(stat string, value string) error {
|
||||
return s.statter.Raw(s.prefix+stat, value, 1.0)
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2015 ISRG. All rights reserved
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
func TestScopedStatsStatsd(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
statter := NewMockStatter(ctrl)
|
||||
stats := NewStatsdScope(statter, "fake")
|
||||
statter.EXPECT().Inc("fake.counter", int64(2), float32(1.0)).Return(nil)
|
||||
stats.Inc("counter", 2)
|
||||
|
||||
statter.EXPECT().Dec("fake.counter", int64(2), float32(1.0)).Return(nil)
|
||||
stats.Dec("counter", 2)
|
||||
|
||||
statter.EXPECT().Gauge("fake.gauge", int64(2), float32(1.0)).Return(nil)
|
||||
stats.Gauge("gauge", 2)
|
||||
statter.EXPECT().GaugeDelta("fake.delta", int64(2), float32(1.0)).Return(nil)
|
||||
stats.GaugeDelta("delta", 2)
|
||||
statter.EXPECT().Timing("fake.latency", int64(2), float32(1.0)).Return(nil)
|
||||
stats.Timing("latency", 2)
|
||||
statter.EXPECT().TimingDuration("fake.latency", 2*time.Second, float32(1.0)).Return(nil)
|
||||
stats.TimingDuration("latency", 2*time.Second)
|
||||
statter.EXPECT().Set("fake.something", "value", float32(1.0)).Return(nil)
|
||||
stats.Set("something", "value")
|
||||
statter.EXPECT().SetInt("fake.someint", int64(10), float32(1.0)).Return(nil)
|
||||
stats.SetInt("someint", 10)
|
||||
statter.EXPECT().Raw("fake.raw", "raw value", float32(1.0)).Return(nil)
|
||||
stats.Raw("raw", "raw value")
|
||||
|
||||
s := stats.NewScope("foobar")
|
||||
statter.EXPECT().Inc("fake.foobar.counter", int64(3), float32(1.0)).Return(nil)
|
||||
s.Inc("counter", 3)
|
||||
ss := stats.NewScope("another", "level")
|
||||
statter.EXPECT().Inc("fake.foobar.counter", int64(4), float32(1.0)).Return(nil)
|
||||
s.Inc("counter", 4)
|
||||
|
||||
if stats.Scope() != "fake" {
|
||||
t.Errorf(`expected "fake", got %#v`, stats.Scope())
|
||||
}
|
||||
if s.Scope() != "fake.foobar" {
|
||||
t.Errorf(`expected "fake.foobar", got %#v`, s.Scope())
|
||||
}
|
||||
if ss.Scope() != "fake.another.level" {
|
||||
t.Errorf(`expected "fake.foobar", got %#v`, s.Scope())
|
||||
}
|
||||
|
||||
twoScope := NewStatsdScope(statter, "fake", "bang")
|
||||
statter.EXPECT().Inc("fake.bang.counter", int64(7), float32(1.0)).Return(nil)
|
||||
twoScope.Inc("counter", 7)
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue