【问题标题】:Debug Level Logging Statement Performance调试级别日志记录语句性能
【发布时间】:2017-01-03 18:38:24
【问题描述】:

如何调整调试日志记录级别语句的性能?我问是因为我的春季批处理作业可以调用大约 50 个这些 logger.debug 语句(做或多或少相同)每个作业几百万次。

查询:

private final String updateIsUserFl = "update users "
+ "set flag = 'Y' "
+ "where name = ? and id = ? ";

查询执行:

myJdbcTemplate.update(updateIsUserFl, name, id);

记录语句:

String debugQuery = updateIsUserFl.toString();
logger.debug(replace(debugQuery, "?", name, 1));
logger.debug(replace(debugQuery, "?", Integer.toString(id), 1)); 

具体问题:

  1. 所以,基本上,我想打印出传递给我的 JdbcTemplate 的确切查询。有没有比 StringUtils.replace 更好/成本更低的方法?希望也少一些笨拙(为了可维护性)。

  2. 在 updateUserFl 上调用 toString 是复制最终字符串对象以进行字符串操作的正确/有效方法吗?

  3. 是否会将其包装在 if logger.IsDebugEnabled 检查帮助中,还是 slf4j 已经为我这样做了?

  4. 我可以使用 logback / {}(以某种我想不到的方式)来提供帮助吗?

  5. 我应该考虑使用 log4j2、Java 8 (lambdas) 的选项吗?见:Avoid Log4j/Slf4j debug enabled checks

【问题讨论】:

  • 只是一个非常通用的提示,因为我对 spring 了解不多:一般来说,JVM 可以很好地与 lambdas 配合使用,所以很可能某些使用 lambdas 的表达式比另一个表达式具有更好的性能,非-lambda 解决方案。所以如果可能的话,你可能想调查一下。
  • 使用github.com/arthurblake/log4jdbc 进行sql 日志记录。

标签: java spring performance logging log4j


【解决方案1】:

这将适用于 org.springframework.jdbc-3.0.6.RELEASE.jar。 TRACE 级别会做的事情。

我正在使用 log4j-1.2.15 以及 slf4j (1.6.4) 和属性文件来配置 log4j:

log4j.logger.org.springframework.jdbc.core = TRACE

这将显示 SQL 语句和绑定参数,如下所示:

Executing prepared SQL statement [select HEADLINE_TEXT, NEWS_DATE_TIME from MY_TABLE where PRODUCT_KEY = ? and NEWS_DATE_TIME between ? and ? order by NEWS_DATE_TIME]
Setting SQL statement parameter value: column index 1, parameter value [aaa], value class [java.lang.String], SQL type unknown
Setting SQL statement parameter value: column index 2, parameter value [Thu Oct 11 08:00:00 CEST 2012], value class [java.util.Date], SQL type unknown
Setting SQL statement parameter value: column index 3, parameter value [Thu Oct 11 08:00:10 CEST 2012], value class [java.util.Date], SQL type unknown

SQL类型我们这里可以忽略

对于一个 SQL(即,如果您对绑定参数值不感兴趣)DEBUG 就足够了。

【讨论】:

    【解决方案2】:

    首先,您可以利用现有的 Spring 日志记录机制将您的查询和参数视为@Mr。 Noob 指出。

    如果您想优化自己的日志记录,需要考虑以下几点:

    1. 调用updateIsUserFl.toString() 是多余的。 updateIsUserFl 已经是包含您的查询的 String。当您在 String 上调用 replace() 时,它会返回一个新的 String 而不是更改现有的(Strings 在 Java 中是不可变的)。
    2. 在构造日志消息之前检查日志级别。如果消息最终不会进入日志,则无需执行所有这些操作。 Log4j 会执行相同的检查,但前提是您已经花费了资源来构建日志消息。
    3. replace() 在这里不是一个好的选择(它使用正则表达式)。最好将参数值添加到 SQL 语句的末尾。分析就足够了。

    所以,最后,你可以这样做:

    if (logger.isDebugEnabled()) {
        logger.debug(String.format("%s; name=%s, id=%d", updateIsUserFl, name, id));
    }
    

    是的,Java 8 和 Log4j2 是值得考虑的选项。它将允许您使用延迟执行的 lambdas 而不是级别检查。它通常速度更快,内存消耗更少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多