go语言读取当前文件名行号和函数名

当我们需要打印日志的时候经常会需要标示当前的代码位置信息,包括所在文件名,行号,以及所在函数等等;特别是在处理log信息的时候。

go语言提供的runtime和reflect库可以帮助我们获取这些信息。下面是一个重写的log函数例子;自定义了一套log接口: ENTRY/EXIT/INFO/DEBUG等等,这些接口都是相似,所以代码例子只给出了ENTRY和DEBUG

package main

import (
  "fmt"
  "log"
  "strings"
  "runtime"
 _"reflect"
  "path/filepath"
)

type MyStruct struct {
}

func (m *MyStruct) foo(p string) {
  ENTRY("")
  ENTRY("Param p=%s", p)
  DEBUG("Test %s %s", "Hello", "World")
}

func DEBUG(formating string, args... interface{}) {
  LOG("DEBUG", formating, args...)
}

func ENTRY(formating string, args... interface{}) {
  LOG("ENTRY", formating, args...)
}

func LOG(level string, formating string, args... interface{}) {
  filename, line, funcname := "???", 0, "???"
  pc, filename, line, ok := runtime.Caller(2)
  // fmt.Println(reflect.TypeOf(pc), reflect.ValueOf(pc))
  if ok {
      funcname = runtime.FuncForPC(pc).Name()       // main.(*MyStruct).foo
      funcname = filepath.Ext(funcname)             // .foo
      funcname = strings.TrimPrefix(funcname, ".")  // foo

      filename = filepath.Base(filename)  // /full/path/basename.go => basename.go
  }

  log.Printf("%s:%d:%s: %s: %s\n", filename, line, funcname, level, fmt.Sprintf(formating, args...))
}

func main() {
  ss := MyStruct{}
  ss.foo("helloworld")
}

编译运行

$ go build main.go && ./main 
2017/09/24 09:37:29 main.go:17:foo: ENTRY: 
2017/09/24 09:37:29 main.go:18:foo: ENTRY: Param p=helloworld
2017/09/24 09:37:29 main.go:19:foo: DEBUG: Test Hello World

这样在log里面可以清楚的看到输出ENTRY/DEBUG语句所在的代码信息,包括所在文件,行号,以及函数名。

    原文作者:CodingCode
    原文地址: https://www.jianshu.com/p/7aa54489bb4b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞