-
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
Provide Output method to Entry #118
Comments
+1. As an example, not having this makes SetLogger() in go-nsq hard to use. |
+1. Same as @maxpersson has said. Want to use logrus with go-nsq and Output method is mandatory for it to be used with go-nsq's SetLogger. |
@sundarv85 @maxpersson why not just use logger := logrus.WithFields(logrus.Fields{
"id": r.id,
"topic": r.topic,
"channel": r.channel
}) And then use it: logger.Info("OMG messages")
logger.Warn("OOMG too many messages!") That'll log with all those fields. That's a much cleaner pattern in my opinion. Although |
The issue is some libs (in this case NSQ Go client) require the specific On Sun, Mar 15, 2015 at 10:18 PM, Simon Eskildsen [email protected]
|
@nvcnvn ya, I agree it should be in, I'm just saying I don't see it as a Logrus best practise. |
Hi Simon, On Sun, Mar 15, 2015 at 10:29 PM, Simon Eskildsen [email protected]
|
oooh, that use case makes a lot more sense. Gotcha! ✨ Either way, I'll happily accept a patch for this. I might do this at some point if nobody else does. |
Does any one know what is expected behavior of "Output" method Calldepth arg? |
+1 mgo use this method as well. |
Any news on this? |
Got bitten by this today… |
Can someone write a patch? |
The way that I think the only way to write a generic |
+1 mgo need it. |
@michaeltrobinson I'd be interested in looking at your work-around. |
@sporkmonger - This is how we are using |
Thanks for the super-quick response. Looks to me like this is really more of an issue w/ the go-nsq package than w/ logrus. |
Well, if |
True. |
I don't understand why the MR #390 was closed without being merged :( |
There are three reasons for implementing
|
In my opinion logrus should provide a very simple interface that represents its core feature set in the simplest and cleanest way possible. This is why I wouldn't include utility methods like I've recently mentioned (here and here) that Most of these issues are about implementing a logrus-to-something adapter. Whether that something is a The problem discussed here ( package main
import (
"github.com/sirupsen/logrus"
"log"
"runtime"
)
func main() {
o := &logrusOutput{
entry: logrus.StandardLogger().WithField("logger", "nsq"),
}
o.Output(1, "woof")
log.SetFlags(log.Llongfile)
log.Output(1, "meow")
}
type logrusOutput struct {
entry *logrus.Entry
}
func (o *logrusOutput) Output(calldepth int, s string) error {
// Since logrus doesn't support reporting filenames and line numbers
// we could simply ignore calldepth or we can add them as fields.
if _, file, line, ok := runtime.Caller(calldepth); ok {
o.entry.WithFields(logrus.Fields{
"file": file,
"line": line,
}).Info(s)
return nil
}
o.entry.Info(s)
return nil
} Similarly to the above A problem like this isn't a good reason to put extra code into the logrus core. It would be needless liability. Some adapters could be provided as a separate package that isn't a dependency of logrus core. Here is another example that creates a new standard logger on top of logrus: package main
import (
"github.com/sirupsen/logrus"
"log"
)
func main() {
w := &log2LogrusWriter{
entry: logrus.StandardLogger().WithField("logger", "log2Logrus"),
}
logger := log.New(w, "", 0)
logger.Output(1, "woof")
}
// log2LogrusWriter exploits the documented fact that the standard
// log pkg sends each log entry as a single io.Writer.Write call:
// https://golang.org/pkg/log/#Logger
type log2LogrusWriter struct {
entry *logrus.Entry
}
func (w *log2LogrusWriter) Write(b []byte) (int, error) {
n := len(b)
if n > 0 && b[n-1] == '\n' {
b = b[:n-1]
}
w.entry.Info(string(b))
return n, nil
} |
I certainly agree with @pasztorpisti that certain logging interfaces/APIs are unnecessarily complex and that one could, as demonstrated by pasztorpisti's post, code around Output's absence. However, logrus specifically states that it's "completely API compatible with the standard library logger" and by doing so, a developer can easily replace golang's logger with its implementation by changing a dependent package's 'log" import statement. No further coding is required, unless of course there's a logrus feature that you wish to exploit. I'm also confident, that most developers that chose to replace golang's logger did so seamlessly but as evidenced by this thread, there were those of us who attempted this easy replacement method and encountered a compilation error. This error exposed the absence of golang's public Inconsistencies between a project's stated intent and an actual experience using it beget questions like:
It boils down to this: if logrus wants to be "completely API compatible..." then implement Output, otherwise, advertise that they are "almost API compatible..." and identify the differences. |
@WhisperingChaos Your point is completely valid regarding the claims of the documentation. Being std log compatible might have some "marketing" related value because "compatible" sounds to be a good/safe choice. However from a technical perspective its usefulness is questionable. Providing backward compatibility interfaces as separate adapters is a better design. And in a lot of cases there is no need for adapters: My approach to adapting logrus in an existing codebase probably wouldn't include replacing standard The first (and last) step would be redirecting all standard logs in In the future I'd insert new log statements by importing logrus without import alias and calling it directly. |
Like @WhisperingChaos said, if the library claims to be completely API-compatible with the standard logging package, then it really should be that. I was hoping to use logrus with mgo (MongoDB client library), which uses standard log package, but cannot since logrus misses the Output method that the log.Logger interface declares. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Standar log pakcage have the Output method for Logger http://golang.org/pkg/log/#Logger.Output
Maybe Entry should have that method so it interface exactly with std Logger.
The text was updated successfully, but these errors were encountered: