I'd like to monitor arbitrary method calls and I am interested in 3 metrics of the method call:
In Java, I can define an annotation which inject the metrics initialization and calculating before and after the method call. For instance:
@Monitor
public void foo() {
// do some stuff...
}
And this @Monitor
annotation will inject some codes before and after the foo
to generate the metrics for it.
Is there a similar way to achieve this in Go?
Check Aspect-Oriented Programming framework for Go and this.
And see How to write benchmarks in Go - Dave Cheney
You may use a proxy function to do this:
total time: 1.002061047s
total number of requests: 10
number of errors: 0
Proxy function:
func (p *metrics) proxy(user func() error) func() error {
return func() error {
p.nCalls++
t0 := time.Now()
err := user()
t := time.Since(t0)
// p.d = append(p.d, t)
p.total += t
if err != nil {
p.nErrs++
}
return err
}
}
All:
package main
import (
"fmt"
"time"
)
func main() {
m := new(metrics)
f := m.proxy(user)
for i := 0; i < 10; i++ {
f()
}
m.show()
}
func user() error {
time.Sleep(100 * time.Millisecond)
return nil
}
type metrics struct {
nCalls, nErrs int
total time.Duration
// d []time.Duration
}
func (p *metrics) proxy(user func() error) func() error {
return func() error {
p.nCalls++
t0 := time.Now()
err := user()
t := time.Since(t0)
// p.d = append(p.d, t)
p.total += t
if err != nil {
p.nErrs++
}
return err
}
}
func (p *metrics) show() {
fmt.Println("total time:", p.total)
fmt.Println("total number of requests:", p.nCalls)
fmt.Println("number of errors:", p.nErrs)
}