Log4j隐式字符串格式

zysjyyx4  于 2022-11-06  发布在  其他
关注(0)|答案(5)|浏览(135)

我正在使用log4j v1.2.14在我的项目中进行日志记录,并且我还在使用Java 7String.format()在我的输出中放置变量。

LOGGER.info(String.format("Your var is [%s] and you are [%s]", myVar, myVar1));

这真的是输出字符串的最佳方式吗?我觉得log4j应该隐式地实现它,如下所示:

LOGGER.info("Your var is [%s] and you are [%s]", myVar, myVar1);

我错过了什么吗?进一步说,有没有任何Java日志记录框架支持这一点?

gk7wooem

gk7wooem1#

slf4j的api提供了“参数化日志记录”,它允许你准确地做到这一点,尽管语法稍有不同。这里的例子是:

logger.debug("Value {} was inserted between {} and {}.", newVal, below, above);

对于一个实现,您可以使用Logback来本地实现slf4j,或者使用slf4j绑定来连接log4j或其他记录器。The User Manual解释了这一点,沿着了一个简短的示例。

brgchamk

brgchamk2#

使用String.format+或日志记录系统未提供的字符串格式化程序(例如log4j)被认为是不好的做法。
通常,在代码中有很多低级日志如果你使用String.format来格式化要记录的字符串,那么你将在堆上分配并格式化一个新的String,它可能会很长并消耗资源,即使在结束时不记录任何内容(例如,如果log4j最小级别被设置为警告或错误)。
通过使用logger格式化程序系统(如log4j中的格式化程序系统),您可以让您的logger在不需要记录的情况下避免生成格式化字符串。
这在某些情况下可能会产生很大的不同。

piv4azn7

piv4azn73#

Log4j支持内部格式化。我没有在任何地方找到它的文档,但我在这里看到了它的一个例子:
https://logging.apache.org/log4j/2.x/manual/markers.html
我试过了,它工作了!我在log4j 2.11.2上。

int i = 42;
String str1 = "the answer";
String str2 = "life, the universe, and everything";
console.info("{} is {} to {}", i, str1, str2);

看一下Logger的javadoc,我认为它是在Lo 4j 2中引入的,并且支持多达10个参数。
https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Logger.html

to94eoyn

to94eoyn4#

顺便说一句,在这种情况下,使用+将变量添加到字符串和使用String.format没有太大区别--除非你真的想在所有日志中重用“Your var is...”。
slf 4j允许您以以下身份登录
log.info("Your var is {} and you are {}", myVar, myVar1);
注意使用{}而不是打印格式化程序。

yeotifhr

yeotifhr5#

我首先支持“使用logger.debug(format, varargs)“方法,因为它不会在不需要的时候分配额外的String
但是,我突然想到,logger.debug(String format, Object... varargs)仍然为varargs分配了一个Array
已在https://godbolt.org/noscript/java上尝试

class VarargTest {
    static boolean debugging = false;
    static void debug(String format, Object... args) {
       if (debugging) {
           System.out.println(String.format(format, args));
       }
    }

    static void logVarargs(int n) {
        debug("debug message {}", n);
    }

    static void logIf(int n) {
        if (VarargTest.debugging) {
            debug("debug message 2 " + n);
        }
    }
}

并且实际上,所得到的x1M4N1X调用分配x1M5N1X。
所以最快的代码应该是

if (logger.isDebugEnabled()) {
    logger.debug("format {}", arg);
}

如果它不是超级性能关键型的,那么一个可读性更好、速度更快的代码应该是

logger.debug("format {}", arg);

相关问题