kit: Explain why Logger.log() returns error

Hi,

I think go-kit/kit/log reflects my personal thoughts on logging, but I am hesitant to use it directly due to Logger.log() returning an error. In my opinion errors are intended to be checked, not ignored. And it’s unreasonable to ask users to check log messages. I feel a better philosophy is for the formatters/writers that eventually output messages to disk/tcp/stdout/etc to allow registering handlers for error types. Then, when I setup logging I can say "Here is a logger that logs JSON to a file. If there is an error, call this function (maybe try stdout or maybe trigger some application “debug me” state).

Maybe something like

type jsonLogger struct {
  io.Writer
  onError func(err error, keyvals ...interface{})
}

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 42 (30 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve argued that if an interface method returns an error, you have to check it in the general/library case, which everyone has tacitly accepted by not arguing against it—please do so now if you missed that point.

I don’t know what “the general/library case” is. I don’t agree with your conclusion without qualifications. If you want to provide some value-add wrapper, router, decorator, etc. to the Go kit logger interface in an intermediating library, and you want your intermediating library to be fully general i.e. accommodate both application and event logging, then yes, you must deal with the errors somehow, likely by bubbling them through to the callsite. But, I think this is not a common use case. I think it is much more common that an intermediating library would specialize to e.g. application logging, and e.g. squelch the errors. @ChrisHines has provided several examples in this thread of ways to do that. Indeed, your own ApplicationAdapterLogger is a great example of what an intermediating library or framework could provide. This is not problematic in any way. This is precisely how the Go kit logger is intended to be used.

I’ve also asked what value there is in propagating logging errors along a chain of Loggers, which hasn’t been answered—from which I’m forced to conclude there is none. For example, I don’t understand why an audit trail Logger would need to propagate its error (to what other Logger? and why a Logger? what would it do with it?) or handle one from another Logger (how would it? and does it even make sense for an audit trail logger to decorate another Logger?). For these reasons, I still think Log shouldn’t return an error.

I’m sorry, I feel like both Chris and I have exhaustively responded to all of these points.

Audit trails and tracking don’t seem like logging to me; they seem like endpoints. I don’t follow why something so general has to be supported by logging.

To be clear, what the log package does is allow programmers to write structured data to some destination. From this general form, and using the defined Logger interface, we are able to specialize both to application logging and event logging, depending on the underlying implementation (the concrete objects constructed to satisfy the Logger interface) and its physical destination (a file on disk, a network socket, an OS pipe, or anything else).

So,

Why not have a separate log/event package with a Logger that returns errors? That separates the concerns. If you want application Loggers to play nicely with event Loggers, you can just adapt them

The answer is that we have decided to combine these two use cases into a single, more general-purpose interface, and have decided that the inevitable and concomitant loss in specificity that comes with such generalizations is a cost we are willing to bear. I completely understand that you disagree with this conclusion. I completely understand that you want the Logger interface to specialize to the application logging use case. But that is not what it is, and for what I believe are good reasons 😃