20

I want to write some logs at the debug log which will not be available in the production logs which has info log level. So how will this extra debug logs affect the performance? I mean if we set the log level at INFO, the logger has to check what the log level is and find that the log.debug needto be ignored.

So does this extra log level checking affect performance?

Is there any automagical way of removing the log.debug() statements while deployment? I mean during development time the log.debug will be there and we can debug. But during production deployment time the automagical mechanism will remove all log.debug() messages. I am not sure whether these are possible.

asked Apr 7, 2017 at 18:03
2
  • 1
    Of course it affects performance. The question is how much does it affect performance. The answer is that it depends on what you're logging, because params to log will still be evaluated even if there's no logging output. One way around this is to wrap your logging statements with a check against a static variable which can then be optimized away, or check the log level before entering a logging block. The question is whether or not it's worth it. Commented Apr 7, 2017 at 18:09
  • you can use async loggers from log4j2 in order to get good performance even in case of debug calls. Commented Nov 5, 2019 at 9:33

5 Answers 5

12

So how will this extra debug logs affect the performance?

It affects the performance of the application as loggers are disc I/O calls (assuming you are writing to file system) and DEBUG log level is strictly NOT recommended for production environments.

Is there any automagical way of removing the log.debug() statements while deployment?

No, there is no magical way of removing the log.debug() statements, BUT when you set the logging level to INFO, then as long as you are NOT doing heavy computations while passing the parameters to the debug() method, it should be fine. For example, if you have logger level set to INFO and assume you have got the below two loggers in your code:

logger.debug(" Entry:: "); //this logger is fine, no calculations
//Below logger, you are doing computations to print i.e., calling to String methods
logger.debug(" Entry : product:"+product+" dept:"+dept);//overhead toString() calls

I recommend to use slf4j so that you can avoid the second logger computations overhead by using {} (which replaces with actual values using it's MessageFormatter) as shown below:

//Below logger product and dept toString() NOT invoked
logger.debug(" Entry : product:{} dept{}", product, dept);

One more important point is that with slf4j is just an abstraction and you can switch between any logging frameworks, you can look below text taken from here.

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.

answered Apr 7, 2017 at 18:13
Sign up to request clarification or add additional context in comments.

3 Comments

Can we not use the log4j2 which has the same feature as sl4j?
yes, it is up to you, either log4j2 or slf4j are definitely better options compared to log4j1.x to avoid DEBUG overheads (like shown above)
Actually - the magical way to remove your log::debug is by way of a deployment script. Write a routine to remove those lines from the code before it publishes it.
9

You can wrap your "debug" statements in a call to isDebugEnabled()

if (log.isDebugEnabled()) {
 log.debug("my debug statement");
}

Likewise, wrap your "info" statements in a call to isInfoEnabled() etc.

The idea behind doing this is that checking whether a logging level is enabled is an inexpensive (fixed cost) operation. The cost to generate the statement that is being logged will vary depending on what you are doing.

answered Apr 7, 2017 at 18:13

Comments

5

You can minimize this by how you write your logging statements. If you write

Object a = .... 
log.debug("I have an a: " + a);

then regardless of the logging framework you're using the argument has to get evaluated before the debug function gets run. That means that even if you're at INFO level, you're paying the performance cost of calling toString on a and building the argument string. If you instead write e.g. (depending on what formatting your logging framework uses, this works in log4j and slf4j)

log.debug("I have an a: {}", a);

you don't pay this cost but only the cost of the logger checking whether or not you're in DEBUG mode - unless you need it you don't pay for the argument evaluation.

The other thing to check is that you're buffering output (again, in slf4j, there are buffering appenders) which will minimize the writes.

answered Apr 7, 2017 at 18:17

Comments

4

Another technique that I'd like to point out, often used in Android development, is that you can post-process your jar to remove calls such as debug. The tool used is usually proguard. If you define the call as side-effect free, it can be removed by the optimizer ensuring pretty much zero performance penalty.... it should even be smart enough to optimize away any string construction you were doing for the log message.

https://www.guardsquare.com/en/proguard/manual/usage#assumenosideeffects

answered Jun 9, 2017 at 17:30

Comments

1

The overhead of checking the logging level is very less, almost negligible. You will see a significant impact on performance when you enable debug logs. The impact would depend on how much you data you write to the logs, your storage(if your storage is an SSD the performance hit is lesser compared to the performance hit you get using a normal disk), how many threads write to log (Since only one thread can write to a file at once all the other threads have to wait and it is a sequential process). I have mentioned three but there are more factors that decide how much impact logging will have on application performance.

To answer your second question there is no automatic way to remove debug statements from your code.

answered Apr 7, 2017 at 18:14

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.