使用lambda参数记录kotlin

时间:2016-06-11 18:55:05

标签: java-8 log4j2 kotlin

在log4j2中,我们有一个方便的功能,描述为

// Java-8 style optimization: no need to explicitly check the log level:
// the lambda expression is not evaluated if the TRACE level is not enabled
logger.trace("Some long-running operation returned {}", () -> expensiveOperation());

我试图在kotlin中使用它

log.debug("random {}", { UUID.randomUUID() })

将打印

random Function0<java.util.UUID>

我们如何使用kotlin使用lambda参数记录?或者我们如何明确告诉kotlin要调用哪种方法?

3 个答案:

答案 0 :(得分:9)

问题是debug()被重载,并且有另一种方法将vararg对象作为参数。 Kotlin选择过载而不是以Supplier<?>作为参数的过载,因为它不知道lambda表达式应该是供应商。

只需将其指定为供应商:

log.debug("random {}", Supplier { UUID.randomUUID() })

答案 1 :(得分:1)

我写了一个让这个很有趣的课程......这样我们就可以写出像

这样的东西
log.debug { "some $thing is $that" }

相当于懒惰的lambda日志记录,如

log.debug("some {} is {}", ()->thing, ()->that)

您甚至不需要这些{}来对字符串进行参数化,并且您拥有所有原始记录器方法,因为它是委托...

这是任何想要使用它的人的课程......

import org.apache.logging.log4j.util.Supplier

class Logger(private val logger: org.apache.logging.log4j.Logger) : org.apache.logging.log4j.Logger by logger {

    fun info(supplier: () -> String) {
        logger.info(Supplier { supplier.invoke() })
    }

    fun debug(supplier: () -> String) {
        logger.debug(Supplier { supplier.invoke() })
    }

    fun warn(supplier: () -> String) {
        logger.warn(Supplier { supplier.invoke() })
    }

    fun error(supplier: () -> String) {
        logger.error(Supplier { supplier.invoke() })
    }

    fun trace(supplier: () -> String) {
        logger.trace(Supplier { supplier.invoke() })
    }
}

或者如果你想在日志中利用对源代码的精彩引用

import org.apache.logging.log4j.util.Supplier

class Logger(val logger: org.apache.logging.log4j.Logger) : org.apache.logging.log4j.Logger by logger {

    inline fun info(crossinline supplier: () -> String) {
        logger.info(Supplier { supplier.invoke() })
    }

    inline fun debug(crossinline supplier: () -> String) {
        logger.debug(Supplier { supplier.invoke() })
    }

    inline fun warn(crossinline supplier: () -> String) {
        logger.warn(Supplier { supplier.invoke() })
    }

    inline fun error(crossinline supplier: () -> String) {
        logger.error(Supplier { supplier.invoke() })
    }

    inline fun trace(crossinline supplier: () -> String) {
        logger.trace(Supplier { supplier.invoke() })
    }
}

答案 2 :(得分:0)

签出https://github.com/MicroUtils/kotlin-logging。它还提供了这些功能:

一个方便高效的日志记录库,其中包含带有Kotlin扩展名的slf4j。

调用日志方法,而无需检查相应的日志级别是否已启用:

logger.debug { "Some $expensive message!" }

在幕后,如果未启用调试,则昂贵的消息不会得到评估:

if (logger.isDebugEnabled) logger.debug("Some $expensive message!")

定义记录器,而无需显式指定类名:

// Place definition above class declaration to make field static  
private val logger = KotlinLogging.logger {}