我的目的是创建一个记录函数,该函数列出函数名称和传递的参数列表。
一个例子如下:
func MyFunc(a string, b int){
... some code ...
if err != nil{
errorDescription := myLoggingFunction(err)
fmt.Println(errorDescription)
}
}
func main(){
MyFunc("hello", 42)
}
// where MyLoggingFunction should return something like:
// "MyFunc: a = hello, b = 42, receivedError = "dummy error description"
到目前为止,似乎在golang中没有办法在运行时获取函数的参数名称,正如this question中回答的那样,但是我可以放弃此功能。
通过分析堆栈跟踪,我设法获得了传递的参数的函数名和内存地址,但是在打印以某种方式从其地址开始的参数时,我遇到了麻烦(我知道视参数的类型而定,可能并非无关紧要,但即使是很简单的操作现在也可以做到)
这是我正在构建的日志记录功能的实现(您可以在此playground上对其进行测试),是否可以打印参数值?
func MyLoggingFunction(err error) string {
callersPCs := make([]uintptr, 10)
n := runtime.Callers(2, callersPCs) //skip first 2 entries, (Callers, GetStackTrace)
callersPCs = callersPCs[:n]
b := make([]byte, 1000)
runtime.Stack(b, false)
stackString := string(b)
frames := runtime.CallersFrames(callersPCs)
frame, _ := frames.Next()
trimmedString := strings.Split(strings.Split(stackString, "(")[2], ")")[0]
trimmedString = strings.Replace(trimmedString, " ", "", -1)
parametersPointers := strings.Split(trimmedString, ",")
return fmt.Sprintf("Name: %s \nParameters: %s \nReceived Error: %s", frame.Function, parametersPointers, err.Error())
}
如果还有其他想法可以在不分析堆栈跟踪的情况下构建这种日志记录功能,除了通过传递map[string]interface{}
的想法外,该{包含所有传递的参数名称作为键,其值作为值(这是我目前的实施,而且非常乏味,因为我想经常记录错误),我很高兴阅读它们。