-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: log: improve the existing logger without breaking any existing functionalities #48503
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
Comments
Except for var _ func(calldepth int, s string) error = log.Output |
Thanks for your feedback @ericlagergren, you're right. When this case is considered, it will not have complete backward compatibility. |
https://go.dev/blog/module-compatibility#adding-to-a-function func (l *Logger) Output(calldepth int, s string) error {
return l.OutputLevel(nil/*or default backward-compatible level*/, calldepth+1, s) // +1 for this frame.
}
func (l *Logger) OutputLevel(level Level, calldepth int, s string) error {
...
}
...
func Output(calldepth int, s string) error {
return std.Output(calldepth+1, s) // +1 for this frame.
}
func OutputLevel(level Level, calldepth int, s string) error {
return std.OutputLevel(level, calldepth+1, s) // +1 for this frame.
} |
Your suggestion seems like an appropriate solution to this backward compatibility problem, I'm gonna update my proposal and MR according to your suggestion. Thanks for your feedback @AlexanderYastrebov . |
The proposal and MR have been updated according to @AlexanderYastrebov's suggestion. |
There are of course many other logging packages. |
This proposal has been added to the active column of the proposals project |
Based on the discussion above, this proposal seems like a likely decline. |
Which parts of the proposal are not exactly fit? Could you please share your thoughts in comment before declining? It would be better to discuss each part of it indivually. |
See the comment above: #48503 (comment). There are many existing logging packages. I think the way to move this forward is to build consensus among logging package authors and users as to the common set that should be supported by all. It may make sense to put that common set in the standard library's log package. But previous efforts at this have failed. With respect, given the existing ecosystem and history, I don't think it's an effective use of the proposal committee's time to discuss each part of this complex proposal individually. The goal of the proposal committee in complex areas like this is to find consensus. To do that we need to bring more people into the discussion, not just the proposal committee. Thanks. |
No change in consensus, so declined. |
As you know, the current implementation of the log.Logger provides us with limited flexibility and does not meet developers' needs so most of the developers use third-party libraries for logging. Moreover, we use multiple third-party libraries in our projects and each of these libraries uses different third-party logger implementations. This is a common problem that has been addressed and faced frequently.
The problems with the existing API are:
(These problems have been already addressed in #13182 and #28412)
The latest developments show that log.Logger type will be changed to an interface in Go2 (see also the discussion on #13182). However, it is not going to provide backward compatibility and will affect most of the libraries that use the standard Logger. In my opinion, it would be better to improve existing implementation without breaking any existing functionalities and affecting libraries that use the standard logger implementation such as HTTP.
Proposal
This proposes some changes to the existing logger which won't break any existing functionalities or affect any libraries. In my opinion, developer needs will be met thanks to these changes. Moreover, it will have backward compatibility.
Here are the changes proposed:
The standard log package does not have levels, To support this, additional methods can be added such as Warn, Error, Info, etc.
Any Formatter interface can be introduced, which helps developers to customize the output based on their needs. The current implementation of the log.Logger enforces a specific logging format.
Logger should be context-aware. So that we can add contextual values into the log output such as TraceId and CorrelationId.
Loggers should be able to have a Root Logger. Thanks to this, we can have multiple loggers with different prefixes which write to the same output destination.
For more detail, please check out the sections below and review PR(#48464) I have already created.
Logger Levels
In order to support logger levels, a function named OutputLevel can be added. The function might look like this:
There is no need to change for Output function's signature not to break any functionality and support backward compatibility.
Instead, the Output function might invoke the OutputLevel function directly.
We can set the logger level using the following method.
To enable the level mechanism, we can use a flag named Llevel:
The following levels can be supported:
The following methods can be added to the current implementation in order to write log outputs at different levels. They will only invoke the OutputLevel function and pass the level value to it.
Formatter
In case we would like to format the output based on our needs or requirements, we can format the log output with the help of an interface.
The interface I have in mind is this:
Entry might look like this:
(Entry fields will be set in the OutputLevel function and we will have all necessary data for logging.)
We can set or get formatter by using the following methods.
Sample Formatter:
context.Context
log.Logger should be context-aware. So that we can add values or fields into the output from context.Context using a custom formatter. In order to make it context-aware, we can add a method as shown below.
The following method which will be added creates an entry and adds the given context to it. See the Formatter section for more details about Entry.
In addition to this, the logger should have its own context. It can be set using the following method.
Root Logger
In case we would like to have multiple loggers with different prefixes which write to the same output destination, we should be able to do this as shown below. In the following example, log.GetLogger will return two loggers with different prefixes whose root logger is the standard logger. These loggers will have separate logger levels and contexts however they will write the same output destination where the standard logger points to. Moreover, they will share the root logger's flag and formatter.
The benefit of this feature will be that each module/package can have a separate logger with different prefixes and logs can be differentiated easily.
Sample output looks like this:
This proposal might be too broad. I'm looking forward to your feedback and ideas :)
The text was updated successfully, but these errors were encountered: