-
Notifications
You must be signed in to change notification settings - Fork 442
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
centralize logging and make it pluggable #70
Conversation
Thanks, it's a reasonable suggestion. I explicitly didn't go this route when I refactored the API (edit: #30) because I just wanted it to expose a hook to set a standard library So I'm 👎 on this. I'm curious as to how you want to hook into this on your application side? For example, the existing API provides a level hook, and |
well, with your method you force the use of the internal In our case, this was a simple wrapper looking something like: // A simple wrapper around our logger
type SimpleReachLogger struct {
*logging.Logger
}
func (l *SimpleReachLogger) Debugf(format string, v ...interface{}){
l.Debug(format, v)
}
func (l *SimpleReachLogger) Infof(format string, v ...interface{}){
l.Info(format, v)
}
func (l *SimpleReachLogger) Warnf(format string, v ...interface{}){
l.Warning(format, v)
}
func (l *SimpleReachLogger) Errorf(format string, v ...interface{}){
l.Error(format, v)
} |
Also, there are a few loggers out there that allow you to, with a single call, log to both a file and a syslog/rsyslog or aggregation. Which go-logging currently does. Not sure how we would even be able to do that here. |
Easiest thing to do would be to use http://golang.org/pkg/io/#MultiWriter as the |
The point is that other people may want to have colorized logs, or may want to log JSON objects for later data analysis. This doesn't allow for that. Having an interface lets the user define how the logging is done and how it looks. In my experience no two people have the same idea for how application logs need to look, this gives them the option to have it their way. |
@jehiah care to weigh in |
Maybe I went overboard when requiring all log levels in the interface, maybe something a little more lightweight could also do the job, similar to how mgo does it: https://github.com/go-mgo/mgo/blob/v2/log.go |
I had been poking around as well and had also seen that approach in This still might be a good happy medium because you would be able to still pass a I kinda like this approach, actually. Want to try and whip that up? |
A user's func (l *MyLogger) Printf(format string, v ...interface{}){
switch v[0]{
case nsq.LogLevelDebugPrefix:
l.Debug(format[5:], v[1:]...)
case nsq.LogLevelInfoPrefix:
l.Info(format[5:], v[1:]...)
case nsq.LogLevelWarningPrefix:
l.Warning(format[5:], v[1:]...)
case nsq.LogLevelErrorPrefix:
l.Error(format[5:], v[1:]...)
default:
l.Info(format[5:], v...)
}
} |
Actually, I was suggesting the same interface as type log_Logger interface {
Output(calldepth int, s string) error
} This way our changes here are completely backwards compatible (existing users can still just pass a stdlib type MyLogger struct {
l *logging.Logger
}
func (m *MyLogger) Output(calldepth int, s string) {
switch s[1:4] {
case "DBG":
m.l.Debug(s[5:])
case "INF":
m.l.Info(s[5:])
case "WRN":
m.l.Warning(s[5:])
case "ERR":
m.l.Error(s[5:])
}
} |
Whoops, your changes are also backwards compatible as |
They're both hacks, really, but they get the job done. My preference to choose |
the problem with using |
I like it, thanks for working through this @devdazed Do you mind squashing those commits down to 1? |
centralize logging and make it pluggable
This request does two things, it centralizes logging to the
log.go
to remove some code duplication with respect to logging. It also make the log an interface so that people can easily drop their own logging structures in.The structure simply needs to implement the following methods: