java - 如何使用 Java8s lambdas 改进日志记录机制

标签 java logging lambda java-8

如何通过没有字符串连接的开销来改进您的日志记录机制?

考虑以下示例:

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggerTest {
    public static void main(String[] args) {
        // get logger
        Logger log = Logger.getLogger(LoggerTest.class.getName());

        // set log level to INFO (so fine will not be logged)
        log.setLevel(Level.INFO);

        // this line won't log anything, but will evaluate the getValue method
        log.fine("Trace value: " + getValue());
    }

    // example method to get a value with a lot of string concatenation
    private static String getValue() {
        String val = "";

        for (int i = 0; i < 1000; i++) {
            val += "foo";
        }

        return val;
    }
}

日志方法 log.fine(...) 不会记录任何内容,因为日志级别设置为 INFO。问题是,方法 getValue 无论如何都会被评估。

在具有大量调试语句的大型应用程序中,这是一个很大的性能问题。

那么,如何解决这个问题呢?

最佳答案

从 Java8 开始,可以使用新引入的 lambda expressions对于这种情况。

这是一个修改后的日志示例:

LoggerTest.class

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggerTest {
    public static void main(String[] args) {
        // get own lambda logger
        LambdaLogger log = new LambdaLogger(LoggerTest.class.getName());

        // set log level to INFO (so fine will not be logged)
        log.setLevel(Level.INFO);

        // this line won't log anything, and will also not evaluate the getValue method!
        log.fine(()-> "Trace value: " + getValue());  // changed to lambda expression
    }

    // example method to get a value with a lot of string concatenation
    private static String getValue() {
        String val = "";

        for (int i = 0; i < 1000; i++) {
            val += "foo";
        }

        return val;
    }
}

LambdaLogger.class

import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LambdaLogger extends Logger {
    public LambdaLogger(String name) {
        super(name, null);
    }

    public void fine(Callable<String> message) {
        // log only, if it's loggable
        if (isLoggable(Level.FINE)) {
            try {
                // evaluate here the callable method
                super.fine(message.call());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

通过此修改,如果您有许多仅用于调试目的的日志语句,您可以大大提高应用程序的性能。

当然,您可以使用任何您想要的记录器。这只是 java.util.Logger 的一个示例。

关于java - 如何使用 Java8s lambdas 改进日志记录机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21751954/

相关文章:

java - 操作两个流后无法将结果保存到 List<Long>

java - JPA eclipselink 实体之间的继承 : oracle database

java - jsp/servlet页面的问题

logging - 排除 ch.qos.logback 溢出

django - 如何将 Django 警告和错误记录到生产中的日志文件中?

c++ - 在模板类中编写的 lambda 函数不支持 restrict(...) 吗?

java - Java 中 getter 的命名约定有多重要?

java - 搜索查看空引用 android

java - Solaris 上不明确的输出重定向

mysql - 无服务器框架、typescript、nodejs 和 mysql - 错误 : Received packet in the wrong sequence