如何 use/implement Go 中的纵横比?

How to use/implement aspect orientation in Go?

我想监控任意方法调用,我对方法调用的 3 个指标感兴趣:

  1. 总时间
  2. 请求总数
  3. 错误总数

在Java中,我可以定义一个注释,在方法调用前后注入指标初始化和计算。例如:

@Monitor
public void foo() {
   // do some stuff...
}

并且此 @Monitor 注释将在 foo 之前和之后注入一些代码以为其生成指标。

在 Go 中是否有类似的方法来实现这一点?

Is there a similar way to achieve this in Go[...]?

没有

您必须编写一个包装器来手动拦截输入、分析输出并测量时间。

(请注意,如果语言只是 "Go"。golang.org 是网站。)

检查Aspect-Oriented Programming framework for Go and this

并查看 How to write benchmarks in Go - Dave Cheney


您可以使用代理功能来执行此操作:

total time: 1.002061047s
total number of requests: 10
number of errors: 0

代理函数:

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
    }
}

全部:

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)
}