简体   繁体   中英

Debug Level Logging Statement Performance

How do I tune my debug logging level statements for performance? I ask because my spring batch job can call roughly 50 of these logger.debug statements (doing more or less the same) a couple million times per job.

Query:

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

Query Execution:

myJdbcTemplate.update(updateIsUserFl, name, id);

Logging Statements:

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

Specific Questions:

  1. So, basically, I want to print out the exact query passed in to my JdbcTemplate. Is there a better / less costly way than StringUtils.replace? Hopefully a little less heavy-handed as well (for maintainability sake).

  2. Is calling toString on updateUserFl the right / efficient way to copy a final string object to do string manipulation?

  3. Would wrapping this in an if logger.IsDebugEnabled check help or is slf4j already doing this for me?

  4. Can I use logback / {} (in some way I can't think of) to help?

  5. Is the log4j2, Java 8 (lambdas) an option I should consider? See: Avoid Log4j/Slf4j debug enabled checks

This will work with org.springframework.jdbc-3.0.6.RELEASE.jar. TRACE level will do the thing .

I'm using log4j-1.2.15 along with slf4j (1.6.4) and properties file to configure the log4j:

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

This displays both the SQL statement and bound parameters like this:

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 type we can ignore it here

For just an SQL (ie if you're not interested in bound parameter values) DEBUG should be enough.

First of all, you could leverage the existing Spring logging mechanism to see your queries and parameters as @Mr. Noob pointed out.

If you want to optimise your own logging, there're a couple of things to consider:

  1. Calling updateIsUserFl.toString() is redundant. updateIsUserFl is already a String that contains your query. When you call replace() on a String , it returns a new String instead of changing the existing one ( String s are immutable in Java).
  2. Check logging level before constructing log messages. There's no need to do all those operations if the message won't eventually make it to the log. Log4j does the same check but only after you have already spent resources on building your log message.
  3. replace() is not a good choice here (it uses regular expressions). It's better to add the parameter values to the end of the SQL-statement. It will be enough for analysis.

So, finally, you could do that:

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

And yes, Java 8 and Log4j2 is an option worth considering. It will allow you to use lazily executed lambdas instead of level checks. It's also generally faster and less memory-consuming.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM