Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/minimal/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func ComputeThing(ctx context.Context, arg1, arg2 int) (res int, err error) {
mon.Event("hit 3")
}

mon.RawVal("raw").Observe(1.0)
mon.RawValk(monkit.NewSeriesKey("rawk").WithTag("foo", "bar"), monkit.Sum, monkit.Count).Observe(1.0)
mon.BoolVal("was-4").Observe(res == 4)
mon.IntVal("res").Observe(int64(res))
mon.DurationVal("took").Observe(time.Second + time.Duration(rand.Intn(int(10*time.Second))))
Expand Down
23 changes: 23 additions & 0 deletions scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,29 @@ func (s *Scope) DurationVal(name string, tags ...SeriesTag) *DurationVal {
return m
}

// RawValk retrieves or creates a RawVal with a given key and aggregations.
func (s *Scope) RawValk(key SeriesKey, aggregations ...Aggregate) *RawVal {
source := s.newSource(key.String(), func() StatSource {
return NewRawVal(key, aggregations...)
})
m, ok := source.(*RawVal)
if !ok {
panic(fmt.Sprintf("%s already used for another stats source: %#v", key, source))
}
return m
}

// RawVal retrieves or creates a RawVal after the given name and tags.
func (s *Scope) RawVal(name string, tags ...SeriesTag) *RawVal {
return s.RawValk(NewSeriesKey(name).WithTags(tags...))
}

// RawValf retrieves or creates a RawVal after the given printf-formatted
// name.
func (s *Scope) RawValf(template string, args ...interface{}) *RawVal {
return s.RawVal(fmt.Sprintf(template, args...))
}

// Timer retrieves or creates a Timer after the given name.
func (s *Scope) Timer(name string, tags ...SeriesTag) *Timer {
source := s.newSource(sourceName("", name, tags), func() StatSource {
Expand Down
81 changes: 81 additions & 0 deletions val.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,84 @@ func (v *DurationVal) Quantile(quantile float64) (rv time.Duration) {
v.mtx.Unlock()
return rv
}

// Aggregate can implement additional aggregation for collected values.
type Aggregate func() (observe func(val float64), stat func() (field string, val float64))

// RawVal is a simple wrapper around a float64 value without any aggregation
// (histogram, sum, etc). Constructed using NewRawVal, though its expected usage is like:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// mon.RawVal("value").Observe(val)
// ...
// }
type RawVal struct {
mtx sync.Mutex
value float64
key SeriesKey
stats []func() (field string, val float64)
observers []func(val float64)
}

// NewRawVal creates a RawVal
func NewRawVal(key SeriesKey, aggregations ...Aggregate) *RawVal {
val := &RawVal{key: key}
for _, agg := range aggregations {
observe, stat := agg()
val.stats = append(val.stats, stat)
val.observers = append(val.observers, observe)
}
return val
}

// Observe sets the current value
func (v *RawVal) Observe(val float64) {
v.mtx.Lock()
v.value = val
for _, o := range v.observers {
o(val)
}
v.mtx.Unlock()
}

// Stats implements the StatSource interface.
func (v *RawVal) Stats(cb func(key SeriesKey, field string, val float64)) {
v.mtx.Lock()
cb(v.key, "recent", v.value)
v.mtx.Unlock()
for _, s := range v.stats {
field, value := s()
cb(v.key, field, value)
}
}

// Get returns the current value
func (v *RawVal) Get() float64 {
v.mtx.Lock()
value := v.value
v.mtx.Unlock()
return value
}

// Count is a value aggregator that counts the number of times the value is measured.
func Count() (observe func(val float64), stat func() (field string, val float64)) {
var counter int
return func(val float64) {
counter++
}, func() (field string, val float64) {
return "count", float64(counter)
}
}

// Sum is a value aggregator that summarizes the values measured.
func Sum() (observe func(val float64), stat func() (field string, val float64)) {
var sum int
return func(val float64) {
sum += int(val)
}, func() (field string, val float64) {
return "sum", float64(sum)
}
}