-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add caller offset to fix caller's problem #63. #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I like this idea a lot more than adding caller information to every entry, which is going to be too much data for those not using this feature. This is the only way to get the correct level in the hook? It cannot be hard-coded? |
I think there is some other trick to solve this problem. Such like keep all log function with same stack depth. Now when we invoke Println, the calling path is Println->Infoln->Info->log(stack depth is 3), but when we invoke Infoln, it's caller path is Infoln->Info->log(stack depth is 2). It always change. If we could keep their stack depth a fix number, we can solve this problem without CallerOffset. |
If you update this PR to just go directly to |
It's right. I'll update it this weekend. |
I have complete it. But I find another problem some framework insert their own function object between the real caller and entry.log. Look at below stack info:
fun callIt(log *Logger){
Invoke(log, "Println", "Hello")
}
func Invoke(any interface{}, name string, args ...interface{}) {
inputs := make([]reflect.Value, len(args))
for i, _ := range args {
inputs[i] = reflect.ValueOf(args[i])
}
reflect.ValueOf(any).MethodByName(name
8000
).Call(inputs)
} |
Sorry, not sure I understand. How does that happen, and what's the solution? |
I think I find out the reason. If we use |
I write a hook like this. Magic number 5 work well both with Logger and Entry. import (
"path/filepath"
"runtime"
"strconv"
"strings"
"github.com/bobcyw/logrus"
)
func NewNormalCaller() logrus.Hook {
return &callerHook{}
}
type callerHook struct {
}
func (hook *callerHook) Fire(entry *logrus.Entry) error {
entry.Data["caller"] = hook.caller(entry)
return nil
}
func (hook *callerHook) Levels() []logrus.Level {
return []logrus.Level{
logrus.PanicLevel,
logrus.FatalLevel,
logrus.ErrorLevel,
logrus.WarnLevel,
logrus.InfoLevel,
logrus.DebugLevel,
}
}
func (hook *callerHook) caller(entry *logrus.Entry) string {
if _, file, line, ok := runtime.Caller(5); ok {
return strings.Join([]string{filepath.Base(file), strconv.Itoa(line)}, ":")
} else {
return ""
}
} |
Hi, @sirupsen , I have rebased this commit on the newest master branch. And solved the unstable caller problem. The solution is modifying not only entry's function but also public log's function. |
After read the zap, I think add caller offset to entry is a good idea to solve #63.
Then we can use a hook like this