Closed icamys closed 6 months ago
Hi @icamys!
Thanks for opening an issue for this! The server provides no logging interface by design. Of course this is open for discussion.
There are two moments where the server logs:
MarshalJSON
methods.Write
the response.The only reason for a logger would be to make sure they do not just go to stout.
This can already be done with log.SetOutput
.
@q-uint Thanks for the response. I understand the reasoning behind the low logger usage. My proposal is more about providing a choice of the logger that should be used by this package. When the server uses the log
package, there's an assumption that a global logger instance inside the log
package is already configured somewhere earlier in the application. But that's not always the case. In some applications (like mine) the logger is passed as a dependency to object constructors and doesn't use global variables. If instead of implicitly using the log
package the server could use an instance passed via a Logger
interface, it would remove an implicit dependency from the log
package and provide more freedom to the developers to choose what logging facility they want to use.
Just wanted to make clear, that this approach is not something exotic. It is widely used in the wild:
Hi! First of all, that you for implementing this package!
I've noticed that for logging errors the
log
package is used, concretely two functionslog.Printf
andlog.Fatalf
. There are a couple of issues with this approach:log
package itself, which is not a good solution. Ideally, we should be able to use any logger we prefer.log.Fatalf
terminates the program, which is not always the preferred behaviour.I'd propose allowing the caller provide the logger implementation on Server constructor and use the
log
package by default. Here's an example of what I'd would do.Since both
log.Printf
andlog.Fatalf
are used to print errors, we define aLogger
interface to replace them both:Add an
ErrorLogger
field to theServer
:When creating the
Server
, pass any instance ofLogger
. Here's an example of implementation based on slog logger:func (l *SlogErrorLogger) Println(v ...interface{}) { for _, msg := range v { l.Log.Error(fmt.Sprint(msg)) } }
func main() { // set up the slog.Logger instance // slogLogger := ...
}