Is there a reason part of FieldLogger interface methods return a concrete Entry instead of the interface?
The problem is that this precludes embedding existing FieldLogger while being able to reimplement (full) FieldLogger interface.
The interface matches the WithField methods of Logger and Entry otherwise they wouldn't implements this interface.
I suspect this interface has been added after the implementation of the former struct which couldn't be changed without a major interface change.
Yes, so it looks as if the PR that introduced the FieldLogger interface would've also updated the signatures of those methods, there would be no issue :-(
I'll tag this issue as 2.0 target as we can not change that without making a breaking interface change.
I second this issue.
I've run into this problem trying to implement a composite logger, returning Entry makes it impossible to fully implement this interface.
Also, FiledEntry interface lacks of methods Trace..., despite the fact that both Logger and Entry implement these methods.
There is also https://godoc.org/github.com/sirupsen/logrus#Ext1FieldLogger. Adding those extra methods to the interface would have broken backwards compatibility because anything else implementing that interface would then no longer be implementing it.
PS: interfaces should be defined locally. When/if we get to a v2, I'll be pushing to not provide the v2 equivalent of the logrus.FieldLogger or logrus.Ext1FieldLogger interfaces. If users need an interface they can and should define it locally to cover the methods of logrus.Logger / logrus.Field (or their v2 equivalents) that they use.
@freeformz I believe that the interface for the entity that writes the logs is necessary.
Firstly, it frees your hands when adding new entities for logging. You can never say for sure that the entities Logger and Entry will not be supplemented by anything else in a couple of years.
Secondly, as the most important point for me, passing an interface instead of a specific type along a long chain of objects saves you from long refactoring if something changes in this chain. In my project (sorry I can鈥檛 show - it鈥檚 private) the logger is passed to 20+ entities. At the top level, I create the base logger, and pass the logger directly to the child entities, or create the Entry with additional configuration using the WithFields (fields Fields) *Entry method. Some of these loggers are passed through to the child objects. In all entities that use logging, the logger or Entry created from it is stored as the FieldLogger type, and this is very convenient: this allows me to itemize logger for child entities without paying attention to the specific logger type, i.e. it doesn't matter to me is it Logger or Entry.
I know that every user of logrus can add the interface to his/her project, but it will not be the same as adding the interface directly to the logger project. The main problem is that the interface declared in the logrus states the appearance of the entities Logger and Entry: this gives stability to the code. The interface declared in my project does not guarantee that Logger and Entry will always have the same look.
I hope I convinced you. I would be glad to see your arguments in support of removing the interface common to loggers from the logrus project.
Closing per the project being put into maintenance mode
@belyshevdenis I agree with you. there's an issue I got with the same approach. There are some places that I need to add fields to the logger. the logger itself is passed as a FieldLogger to other functions. So, how do you cast from Entry to FieldLogger in this situation?
@AienTech
entry := logrus.New().WithField("new", "entry")
var logger logrus.FieldLogger = entry
logger.Debug("Hello from Entry method")
Most helpful comment
@freeformz I believe that the interface for the entity that writes the logs is necessary.
Firstly, it frees your hands when adding new entities for logging. You can never say for sure that the entities Logger and Entry will not be supplemented by anything else in a couple of years.
Secondly, as the most important point for me, passing an interface instead of a specific type along a long chain of objects saves you from long refactoring if something changes in this chain. In my project (sorry I can鈥檛 show - it鈥檚 private) the logger is passed to 20+ entities. At the top level, I create the base logger, and pass the logger directly to the child entities, or create the Entry with additional configuration using the
WithFields (fields Fields) *Entrymethod. Some of these loggers are passed through to the child objects. In all entities that use logging, the logger or Entry created from it is stored as the FieldLogger type, and this is very convenient: this allows me to itemize logger for child entities without paying attention to the specific logger type, i.e. it doesn't matter to me is it Logger or Entry.I know that every user of logrus can add the interface to his/her project, but it will not be the same as adding the interface directly to the logger project. The main problem is that the interface declared in the logrus states the appearance of the entities Logger and Entry: this gives stability to the code. The interface declared in my project does not guarantee that Logger and Entry will always have the same look.
I hope I convinced you. I would be glad to see your arguments in support of removing the interface common to loggers from the logrus project.