一个思路:实现 golang 中的 `__file__` `__line__` 宏

发布时间 2023-09-27 14:25:36作者: ahfuzhang

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


测试 zaplog 发现,开启 caller 的调用,会使整个服务增加 2% 的损耗。
其实文件及其行号完全可以在编译期加上去,没必要带来运行期的性能损耗。

因此有一个思路,可以解决这个问题:

1.获取源码行的代码:

package debug

import (
	"fmt"
	"runtime"
	"strings"
)

// SourceCodeLoc 获取源码行
func SourceCodeLoc(callDepth int) string {
	_, file, line, ok := runtime.Caller(callDepth)
	if !ok {
		return ""
	}
	file = strings.ReplaceAll(file, "\\", "/")
	arr := strings.Split(file, "/")
	if len(arr) > 3 {
		file = strings.Join(arr[len(arr)-3:], "/")
	}
	return fmt.Sprintf("%s:%d", file, line)
}

2.在代码中输出行号:

func xxx(){
    if err!=nil{
        return fmt.Errorf("[%s]error detail=%s", debug.SourceCodeLoc(1), err.Error())
    }
}

3.编译前

开发一个工具,在编译前把所有的 debug.SourceCodeLoc(1) 替换为文件中的文件和行号。然后再 go build.

近期会写这样一个工具出来。