-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: log: change Logger to be an interface #13182
Comments
Could I request a review of the proposal? Should I submit a CL? |
I don't see the advantage that this provides over the default logger. Instead of parsing colons you parse tabs? |
No no.... the idea is to define a minimal function type mimicking the current This would allow for instance to pass a log.Logger to http.Server that can plug into any other logging service merely by implementing an OutputFn() and passing it to the Logger. Purely as an example here, I have implemented a version of |
Hi - could I pls. request another evaluation of the proposal as I believe it may have been mis-understood originally. The objective is NOT to write logs with tabs formatting or whatever. The objective is to introduce flexibility in the standard Logger to allow alternative logging implementations (which could include writing to files, over network, databases etc.) to plug into it with a minimal interface while retaining full backwards compatibility. |
Like @adg, I don't believe this proposal has enough benefit to warrant the complexity suggested for the API. The log package already has a way to divert output, namely Note that the log package guarantees to deliver each message in a different Write call. So if you really need to tweak the format, it's possible to do today with no changes to the standard library: tweak the log message itself. Quoting the docs:
The only possible benefit I can see is that the current output writer doesn't know the call depth on each Write, so it can't reconstruct the file and line number for itself. But if that's really important, it's easy to pull them from the written data. |
Thanks for reviewing Russ. Here is the benefit I see of enabling a more flexible logger output via an approach like
|
With the exception of file name, you can shorten to:
If you want file names, then yes you have to use SetFlags(Llongfile) or Lshortfile and parse the file name. That's unfortunate, but it doesn't seem worth a whole new API. If we were starting over then yes I think we might reasonably make SetOutput take a func and have a separate SetWriter. But we're not starting over. We're working with what we have. If we created new API every time we realized we could have done something differently, we'd end up with a much larger (and arguably bloated) standard library. The bar is very high for additions. |
Deferring to Go2. |
I think the right answer is to change Logger to be an interface, and to do that in Go 2. |
@robpike Totally agree. We usually use multiple third-party libraries in one project, and each of these third-party libraries usually has its own logger implementation. This is really a nightmare. A simple and generic logger interface will make this better. |
I agree with the approach with Go 2. What would be the development process? |
Someone needs to develop a proposal. Past efforts have had trouble finding a coherent logging interface, as there are many different logging needs. So it's not a simple problem. |
There's a detailed proposal (#28412) which was well thought out in my opinion and has a decent amount of discussion in the comments that was closed as a duplicate of this issue. Not sure where someone can develop a proposal if they get closed and referred back to here. |
Maybe someone could sketch-out a preliminary proposal as a comment to this thread. |
We're running into the need for a revision of the |
The current implementation of the log.Logger provides us with limited flexibility. With the new changes, it will provide more flexibility. The changes introduce new features such as Log Level, Formatter, Root Logger, Context support etc. but the changes made won't break any existing functionalities or affect any libraries which use log package. Thanks to the changes made, any custom logger implementation won't be needed and developer needs will be met. Instead, the formatter can be used to format the output. Fixes golang#13182
The current implementation of the log.Logger provides us with limited flexibility. With the new changes, it will provide more flexibility. The changes introduce new features such as Log Level, Formatter, Root Logger, Context support etc. but the changes made won't break any existing functionalities or affect any libraries which use log package. Thanks to the changes made, any custom logger implementation won't be needed and developer needs will be met. Instead, the formatter can be used to format the output. Fixes golang#13182
Change https://golang.org/cl/350869 mentions this issue: |
Hi All, I have PR related to this issue. I have come up with a different idea that does not break any existing functionalities instead of changing log.Logger into an interface. In my opinion, it will both meet our needs and won't break any existing functionalities. Could you please review it? #48464 |
The current implementation of the log.Logger provides us with limited flexibility. With the new changes, it will provide more flexibility. The changes introduce new features such as Log Level, Formatter, Root Logger, Context support etc. but the changes made won't break any existing functionalities or affect any libraries which use log package. Thanks to the changes made, any custom logger implementation won't be needed and developer needs will be met. Instead, the formatter can be used to format the output. Fixes golang#13182
The current implementation of the log.Logger provides us with limited flexibility. With the new changes, it will provide more flexibility. The changes introduce new features such as Log Level, Formatter, Root Logger, Context support etc. but the changes made won't break any existing functionalities or affect any libraries which use log package. Thanks to the changes made, any custom logger implementation won't be needed and developer needs will be met. Instead, the formatter can be used to format the output. Fixes golang#13182
This comment has been minimized.
This comment has been minimized.
The current implementation of the log.Logger provides us with limited flexibility. With the new changes, it will provide more flexibility. The changes introduce new features such as Log Level, Formatter, Root Logger, Context support etc. but the changes made won't break any existing functionalities or affect any libraries which use log package. Thanks to the changes made, any custom logger implementation won't be needed and developer needs will be met. Instead, the formatter can be used to format the output. Fixes golang#13182
After reading the level logger issues, I worked it for some coding as the 3rd package based on go std log. I mean let the std log be a single-level logger. the level logger need only Ouput() interface. |
IMO this question was pretty well resolved by the discussion for #28412. The takeaway, for me at least, was that if a library wants to support logging the best practice is to provide a callback interface like httptrace. |
Marking this obsoleted by #56345. |
This proposal has been declined as obsolete. |
Motivation
Go stdlib provides a
log.Logger
that is widely used in both Go programs and Go libraries (eg. most notably inhttp.Server
) as a standardized logging component.However, the current implementation of the
log.Logger
enforces a specific logging format with limited flexibility which requires text parsing to allow it to be connected to any other logging system implementation through the swappableio.Writer
interface. This adds complexity and overhead. The other alternative of directly using third party logging libraries is not very scalable both because existing libraries including components likehttp.Server
in the stdlib expectlog.Logger
and because of network effects of stdlib.Proposal
This proposes a minor change to the log package to make
log.Logger
more extensible in a fully backwards compatible by allowingLogger.Output()
to write logs using custom logging implementations.We do this by defining a function type called
OutputFn
with the same function signature as the currentLogger.Output()
and introducing an unexported fieldoutputfn
inLogger
to hold the function that should be used for output much like we use theout
field to hold theio.Writer
currently. By default,log.New()
will set theoutputfn
to the current implementation which is moved toLogger.DefOutputFn()
. This can be swapped to any otherOutputFn
implementation by callingLogger.SetOutputFn()
in the same way as we currently can swapio.Writer
by callingLogger.SetOutput()
For the top level
log
package, we providelog.SetOutputFn()
andlog.SetDefOutputFn()
to set theOutputFn
of thelog.std
logger and reset it to default.Proof of Concept
I have implemented a proof of concept for this proposed change and added an example in the test suite that demonstrates logging to a Tab Separated Variable format. While in the example i am merely writing to a Writer, the Output could be to anything including over the network etc.
If this approach looks ok, I can package this into a CL incorporating any feedback.
Rationale for the Approach
Most of the actual work of logging happens in
Logger.Output()
(and in the unexportedLogger.formatHeader()
called by it) which makes it a prime candidate for flexibility. We cannot changelog.Logger
into an interface due to Go1 compatibility promise and this approach therefore allows a lot of flexibility with a very minor change.The text was updated successfully, but these errors were encountered: