github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/log/hooks/call_stack.go (about) 1 package hooks 2 3 import ( 4 "fmt" 5 "runtime" 6 "strings" 7 8 "github.com/sirupsen/logrus" 9 ) 10 11 func NewCallStackHook() *CallStackHook { 12 return &CallStackHook{} 13 } 14 15 type CallStackHook struct { 16 } 17 18 func (hook *CallStackHook) Fire(entry *logrus.Entry) error { 19 inFunc, file, line := findCaller() 20 entry.Data["file"] = fmt.Sprintf("%s:%d (%s)", file, line, inFunc) 21 return nil 22 } 23 24 func (hook *CallStackHook) Levels() []logrus.Level { 25 return logrus.AllLevels 26 } 27 28 func findCaller() (inFunc string, file string, line int) { 29 pc := uintptr(0) 30 skip := 5 31 32 for i := 0; i < 10; i++ { 33 pc, file, line = getCaller(skip + i) 34 if !(strings.HasPrefix(file, "logrus")) { 35 inFunc = runtime.FuncForPC(pc).Name() 36 break 37 } 38 } 39 40 return 41 } 42 43 func getGoPkgName(file string) string { 44 n := 0 45 for i := len(file) - 1; i > 0; i-- { 46 if file[i] == '/' { 47 n += 1 48 if n >= 2 { 49 file = file[i+1:] 50 break 51 } 52 } 53 } 54 return file 55 } 56 57 func getCaller(skip int) (uintptr, string, int) { 58 pc, file, line, ok := runtime.Caller(skip) 59 60 if !ok { 61 return 0, "", 0 62 } 63 64 return pc, getGoPkgName(file), line 65 }