[slf4j-dev] [JIRA] (SLF4J-371) Support the lambda expression in the Logger

QOS.CH (JIRA) noreply-jira at qos.ch
Tue May 2 09:08:00 CEST 2017


    [ https://jira.qos.ch/browse/SLF4J-371?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18767#comment-18767 ] 

MiNG commented on SLF4J-371:
----------------------------

In the @HermanBovens case, does anyone think about how to define the method signature of `debug`, is the above code able to compile?

In Java, function/method is not the first-class type, every lambda expression must be converted to a SAM interface in compile time.

So, in the above case, if you want to use like this:
{code:java}
LOG.debug("can mix {} and {} arguments", "normal", () -> "lambda");{code}
you must declare the method with fixed parameters:
{code:java}
void debug(String format, Object arg1, Supplier<?> arg2);{code}

How about the varargs?
In the varargs case the parameter type MUST declare as Object.
{code:java}
void debug(String format, Object... args);{code}
Then, we MUST call it like this:
{code:java}
LOG.debug("can mix {} and {} arguments", "normal", (Supplier<?>)() -> "lambda");{code}

Isn't that weird?

So, I think the following method signature is more friendly to users:
{code:java}
// Supply the formatted string to log
debug(Function<MessageFormatter, String> messageSupplier);

// Invoke the log method in the closure lazily
debug(Consumer<Logger> lazyLog);
{code}

call example:
{code:java}
// Supply the formatted string to log
logger.debug(fmt -> "xxx" + Json.serialize(huge));

// Invoke the log method in the closure lazily
logger.debug(log -> log.invoke("xxx {}", Json.serialize(huge)));{code}

> Support the lambda expression in the Logger
> -------------------------------------------
>
>                 Key: SLF4J-371
>                 URL: https://jira.qos.ch/browse/SLF4J-371
>             Project: SLF4J
>          Issue Type: Improvement
>          Components: Core API
>    Affects Versions: 1.7.22
>            Reporter: MiNG
>            Assignee: SLF4J developers list
>
> In some cases, we don't want to calculate the expression for logging eagerly cause the performance reason. Then, we would write the code like the following:
> ```
>     if (LOGGER.isWarnEnabled())
>     {
>        LOGGER.warn("some message: {}", Json.serialize(obj));
>     }
> ```
> Before JDK8, there is no way to encapsulate the above code, because the expression is always calculated before passed as an argument. So, many "if"s appear in the code and smell badly.
> Now, the lambda expression is supported by JDK8, the above could be simplified like following:
> ```
>     LOGGER.warn(formatter -> formatter.format("some message: {}", Json.serialize(obj)));
> ```
> With the default method definition in the org.slf4j.Logger:
> ```
>     public interface Logger
>     {
>       default void warn(Function<MessageFormatter, String> messageSupplier)
>       {
>         if (this.isWarnEnabled())
>         {
>           /* Calculate the expression only if the WARN level logging is enabled. */
>           this.warn(messageSupplier.apply(this.getFormatter()));
>         }
>       }
>     }
> ```



--
This message was sent by Atlassian JIRA
(v7.3.1#73012)


More information about the slf4j-dev mailing list