-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Log filename and line number #63
Comments
There's currently no way of doing it. Would definitely be interested in a contribution adding this. |
I was part of the discussion leading to this solution: inconshreveable/log15@dbf739e |
Hm.. it'd be nice if formatters and hooks could lazily load this if they need it, but I'm not sure if we can do that nicely. I don't want to call those functions and pass it down with the entry every time we log. |
I'm interested in this as well. @sirupsen from your perspective how do you feel about adding some sort of a middleware layer that allows people to gather their own context and automatically append it to an entry's Fields? That mechanism would allow us to add this sort of thing in quite easily. I am not sure about what other use cases this might also open up. |
I wouldn't be opposed to adding it by default and then allowing the formatters/hooks to use it appropriately. This is also useful for exception tracking etc., however, it might have a performance impact. We'll need to measure that |
Yes please, this feature is very much needed. |
I like the idea of a middleware layer but agree with @sirupsen that this is not something I would want to occur in a production environment. If we're logging errors the existing ability to log detailed and helpful values should be sufficient; however, in a development environment quick access to filepath and line number is very valuable. Thanks everyone for this discussion. |
Yes, unless someone can prove a negligible performance impact I think this should be a hook. |
I solve this in a performant manner by doing the following: var log *logrus.Logger
func init() {
log = mylog.NewLogger()
}
func NewLogger() *logrus.Logger {
_, file, _, ok := runtime.Caller(1)
if !ok {
file = "unknown"
}
ret := logrus.New()
inst := &logInstance{
innerLogger: ret,
file: filepath.Base(file),
}
ret.Hooks.Add(inst)
return ret
} logInstance is a hook that adds "file" to the log entry. This saves me calling runtime.Caller each time I log a message while still having code that does log.WithField()....Info() The disadvantage is that I only have one "log" per package that contains the filename of where it was created. This usually works enough for me since I use many packages. If not, I would give each file it's own log() variable. |
+1 it's a MUST-HAVE, and saying "completely API compatible with the standard library logger" in the README is wrong as we have that feature in the standard Go logger (SetFlags) http://golang.org/pkg/log/#SetFlags |
+1 |
Perhaps someone take a closer look at |
@sirupsen, I can definitely have a look :) |
@chreble awesome, let me know what you find! |
@sirupsen unfortunately, the Is this such a big deal to implement in logrus? |
@dmlyons no it's not, I've just not needed this myself and haven't seen an implementation that hasn't failed on different platforms. |
Has anyone resolved this in a reasonable way? I just want the filename and line number. I'd also prefer to be able to configure it to only print on specific levels (e.g. err, panic, warn) |
We have wrapped the stuff we most use from logrus with the file information, i don't know if you will find it useful or not but here you are https://gist.github.com/gonzaloserrano/d360c1b195f7313b6d19 |
+1 |
1 similar comment
+1 |
I will try to take a swing at it, as @dmlyons said it is pretty straightforward to implement. |
+1 |
+1 |
My solution was to use https://github.com/inconshreveable/log15 |
This feature is contained in v1.2.0 |
Hi all, is there a way to cut the longest file path? like just to display the INFO[0000]/test/main.go:17 main.main() hello world Thanks...QQ |
@andytsnowden , this helps a lot, thanks. |
any idea on how to cut file name ? |
@Wamani please don't comment on closed issue, because it's kind of hard to find it back. That said if you want to customiza the output of the caller field you can give a specific formatting function in the CallerPrettyfier field of the JSONFormatter (https://godoc.org/github.com/sirupsen/logrus#JSONFormatter) or of the TextFormatter (https://godoc.org/github.com/sirupsen/logrus#TextFormatter). You also have an example in the logrus repository on how to use that with the JSONFormatter here |
Here's how to cut the longest file path: package main
import (
"fmt"
"os"
"runtime"
"strings"
"github.com/sirupsen/logrus"
)
func main() {
log := logrus.New()
log.SetReportCaller(true)
log.Formatter = &logrus.TextFormatter{
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
repopath := fmt.Sprintf("%s/src/github.com/bob", os.Getenv("GOPATH"))
filename := strings.Replace(f.File, repopath, "", -1)
return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
},
}
log.Println("hello world")
} Output: INFO[0000]/test/main.go:23 main.main() hello world |
thanks it works |
Thank a lot of! package main
import (
"fmt"
"path"
"runtime"
"github.com/sirupsen/logrus"
)
func main() {
log := logrus.New()
log.SetReportCaller(true)
log.Formatter = &logrus.TextFormatter{
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
filename := path.Base(f.File)
return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
},
}
log.Println("hello world")
}
` |
@art-frela great suggestion on using |
Worth mentioning that if you are using logrus JSONFormatter and you need filename and line support, there is a handy example in the codebase which adds funcname and filename. - https://github.com/sirupsen/logrus/blob/master/example_custom_caller_test.go
A slight modification to it can return line number also
|
My code ended up looking a little like this:
Which logs source file name, function name, and line number. |
I can't reproduce this in logrus 1.4.2 using Go 1.14, I tried @art-frela snippet, and I can't reproduce it. This is my output:
I would have expected to see something like
Any ideas? |
related to #1096 |
Yep it's Go 1.14 thanks @dgsb I thought I was going crazy for the last hour 👍 |
Note: import ( runtime "github.com/banzaicloud/logrus-runtime-formatter" |
This lose coloring on console. |
Just for reference I came up with this to show log.SetReportCaller(true)
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
CallerPrettyfier: func(f *runtime.Frame) (second string, first string) {
_, b, _, _ := runtime.Caller(0)
basepath := filepath.Dir(b)
rel, err := filepath.Rel(basepath, f.File)
if err != nil {
log.Error("Couldn't determine file path\n", err)
}
return "", fmt.Sprintf("%s:%d", rel, f.Line)
},
})
|
您的邮件已收到,我会尽快查看&回复:)
|
You're right.. Using &log.TextFormatter loses all the colors.. log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
}) |
Is there a way to do this with the file and line number added as separate fields? |
您的邮件已收到,我会尽快查看&回复:)
|
I think the best way would be to create an instance per package and pass a custom string (package name or tag) to the formatter. At least that way you know which package the error took place in. It just adds some context instead of a spontaneous error message. |
After set The log looks like this:
2 problems:
|
您的邮件已收到,我会尽快查看&回复:)
|
Both stdlib package log and many other logging frameworks are supporting this (e.g. https://github.com/inconshreveable/log15). Am I missing how to enable it or is it not supported?
The text was updated successfully, but these errors were encountered: