method 1 利用defer
func elapsed(what string) func() {
start := time.Now()
return func() {
fmt.Printf("%s took %v\n", what, time.Since(start))
// fmt.Println(time.Now().Sub(now))
}
}
func main() {
defer elapsed("page")()
time.Sleep(time.Second * 2)
}
method2 自动识别函数名
package main
import (
"fmt"
"log"
"regexp"
"runtime"
"time"
)
func TimeTrack(start time.Time) {
elapsed:=time.Since(start)
pc,_,_,_:=runtime.Caller(1)
fmt.Println(pc)
funcObj:=runtime.FuncForPC(pc)
runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")
fmt.Println(name)
log.Println(fmt.Sprintf("%s took %s", name, elapsed))
}
func ExecuteTimeTest() {
defer TimeTrack(time.Now())
time.Sleep(time.Second*2)
}
func main() {
ExecuteTimeTest()
}
相关函数介绍
runtime.Caller(skip int) (pc uintptr, file string, line int, ok bool)
Caller可以返回函数调用栈的某一层的程序计数器、文件信息、行号。
0 代表当前函数,也是调用runtime.Caller的函数。1 代表上一层调用者,以此类推。
func FuncForPC(pc uintptr) *Func
FuncForPC 是一个有趣的函数, 它可以把程序计数器地址对应的函数的信息获取出来。如果因为内联程序计数器对应多个函数,它返回最外面的函数。
它的返回值是一个Func类型的值,通过Func可以获得函数地址、文件行、函数名等信息。
pc,_,_,_:=runtime.Caller(1)
fmt.Println(pc)
funcObj:=runtime.FuncForPC(pc)
fmt.Println(funcObj.Name())
//main.ExecuteTimeTest