[slf4j-dev] Proposal for SLF4J 2.0 Logger API
Remko Popma
remko.popma at gmail.com
Thu Dec 19 08:35:59 CET 2019
On Thu, Dec 19, 2019 at 3:23 PM Ralph Goers <ralph.goers at dslextreme.com> wrote:
>
>
>
> On Dec 18, 2019, at 11:01 PM, Remko Popma <remko.popma at gmail.com> wrote:
>
>
> I am guessing you are asking how one could go one step further and
> make the actual logger implementation completely garbage-free.
> For text-based loggers, one idea is to extract the text from the specified
> domain Object (it may not be a CharSequence, but it may implement
> some other interface that allows creating a text representation), and to
> copy this text representation into a StringBuilder owned by the Logger.
>
> The next step is to turn the text representation into bytes which can be
> written to disk or sent over a network. For this, the logging
> implementation needs to do some work with java.nio.CharBuffer, ByteBuffer
> and CharsetEncoders (and making this thread-safe can be quite involved).
>
>
> Or maybe the
> StringBuilder is provided by the logging back-end and only borrowed by
> the client?
>
>
> That is a very good point!
> (And that is one of the reasons why focusing too much on just
> CharBuilder would be a mistake in my opinion.)
>
> A SLF4J implementation could provide its own interface that applications
> could implement on objects that need to be logged without allocations.
> For example:
>
> interface StringBuilderFormattable {
> /**
> * Writes a text representation of this object into the specified
> * StringBuilder, ideally without allocating temporary objects.
> *
> * @param buffer the StringBuilder to write into
> */
> void formatTo(StringBuilder buffer);
> }
>
> The SLF4J implementation detects that the logged Object implements
> this interface, then calls the formatTo(StringBuilder) method on it with
> the StringBuilder owned by the logger. This has the advantage that the
> application no longer needs to manage any StringBuilders, and it
> reduces copying between various buffers. For example:
>
>
>
> As soon as you do this, and require that the implementation start checking if particular interfaces are implemented
Nothing is "required": my example illustrated one way for
implementations who want to provide extra benefits to do so, other
implementations can simply call toString on the Object.
> I have to say, why not use a Message instead.
The Message interface has four methods, which makes it a bit more
cumbersome for domain objects to implement. I suspect that only some
applications with specific needs would take the trouble to implement
Message in their domain objects.
So I would say, perhaps use a Message in addition, but not instead of Object.
> The Log4j API has been doing this for years now. It has solved the problems you are bringing up nicely.
The Message interface in the Log4j API is useful, but it does not solve
any of the problems I indicated. The main problem to me is that it is
still String-based. If SLF4J were to adopt a Message-like interface I
would argue that its methods should return CharSequence instead of
String.
However, in terms of being useful for allocation-sensitive application,
even such a revamped Message interface would still require domain objects
to manage their own StringBuilders, so an interface like
StringBuilderFormattable where the StringBuilder is supplied externally
would be even more useful.
> In fact I am pretty sure you implemented making some Messages reusable to make them garbage free.
Yes, we added a ReusableMessage interface that extends Message and
StringBuilderFormattable. That was necessary to allow the logger
implementation to extract the text without allocating.
> SLf4J wouldn’t have to do this. If it were to support a MessageFactory interface Log4j’s SLF4J binding could provide MessageFactories that implement Log4j’s Message interface so SLF4J (and Log4j) would be garbage free via the logging implementation, at least for some Message classes.
>
> Since you have admitted that you have to leave the existing methods alone, why not just go all the way?
>
> As you well know, the Log4j API still allows users to log Strings or arbitrary Objects. Under the covers it just puts them into a Message. The benefit here is that the logging implementation doesn’t have to check for all kinds of interfaces - it just processes the Message interface. SLF4J could do the same thing.
I'm not opposed to introducing a Message interface in the SLF4J API,
but it should not replace logging arbitrary objects with
Logger.info(Object).
>
> Ralph
> _______________________________________________
> slf4j-dev mailing list
> slf4j-dev at qos.ch
> http://mailman.qos.ch/mailman/listinfo/slf4j-dev
More information about the slf4j-dev
mailing list