8

I've got 3 developers on a project who have different styles when writing to logs. Which of these variations is best?

LOG.info("error = {}", errmsg);
LOG.info("error = ", errmsg);
LOG.info("error = " + errmsg);
Kirby
  • 15,127
  • 10
  • 89
  • 104
m0therway
  • 431
  • 1
  • 4
  • 13

4 Answers4

11
LOG.info("error = {}", errmsg);

Correct and best.

LOG.info("error = ", errmsg);

This is most likely wrong. Unless errmsg is an exception, it will never be logged.

LOG.info("error = " + errmsg);

This one is not performing as good as first. You'll run String concatenation every time you hit this line while in first case variable replacement occurs only if statement will actually be logged.

Some time ago I blogged about different logging syntaxes in .

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    I guess the 2nd is used for exceptions, right? e.g. LOG.info("Error reading file", e); – m0therway Aug 31 '12 at 21:16
  • @Pregnantmom: you're absolutely right! The `errmsg` made me believe this is not an exception. Corrected my answer. – Tomasz Nurkiewicz Aug 31 '12 at 21:23
  • Personally I prefer the third using string concatenation. As for performance, String concatenation can be faster: http://stackoverflow.com/questions/925423/is-it-better-practice-to-use-string-format-over-string-concatenation-in-java – Kirby Nov 25 '14 at 16:59
  • Agree, `LOG.info("error = {}", errmsg);` should be used. No other options should be considered. Also https://stackoverflow.com/questions/10555409/logger-slf4j-advantages-of-formatting-with-instead-of-string-concatenation – Yang Liu Oct 28 '21 at 18:26
3

This is the best (jcabi-log on top of SLF4J):

Logger.info(this, "error=%s", errmsg);

It's a short alternative to:

private static Logger LOG = Logger.getLogger(Foo.class);
LOG.info(String.format("error=%s", errmsg));

First, it's convenient to let one utility class to take care about loggers instantiation. Second, it's very convenient to use String.format() for text formatting, because you always see the whole string and can easily translate it.

yegor256
  • 102,010
  • 123
  • 446
  • 597
2

An alteration of the first form is the best

log.info("error={}", errmsg);

As others have said, the second example has to be a mistake as there is no format token to insert errmsg into "error = ", unless errmsg is a Throwable and info level logging is enabled. Then the logger will print a stracktrace.

For many years I preferred the string concatenation, the third form. I found it easier to read months or years later when I go back to read the code.

However, as Tomasz Nurkiewicz answered, the first form LOG.info("error={}", errmsg); is the best. The reason, though, isn't that String.format() is faster than String concatenation. It isn't. See Is it better practice to use String.format over string Concatenation in Java?.

The reason the first form performs better is that if the info level logging is disabled, then the logging framework doesn't have to call errmsg.toString() and it doesn't have to execute String.format() at all. The only case where errmsg.toString() has no performance cost is if errmsg is a String.

I also would suggest no whitespace around the = as many log aggregators like Splunk will automatically index error=errmsg into a field and value pair. Also, if this truly is an error, then I would write it to the error() level, not info(). And most likely there is a Throwable exception somewhere before this code that should go into the Throwable parameter.

And, logger, while it is probably declared as final, is a mutable object, so, it should be in lower case. See Should a "static final Logger" be declared in UPPER-CASE?.

which means the answer really should be

log.info("error={}", errMsg, exception);
Kirby
  • 15,127
  • 10
  • 89
  • 104
0

Below is the exact copy paste from actual slf4j javadoc. Its worth visiting here :http://www.slf4j.org/api/org/slf4j/Logger.html

import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

 public class Wombat {

   final static Logger logger = LoggerFactory.getLogger(Wombat.class);
   Integer t;
   Integer oldT;

   public void setTemperature(Integer temperature) {
     oldT = t;
     t = temperature;
     logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
     if(temperature.intValue() > 50) {
       logger.info("Temperature has risen above 50 degrees.");
     }
   }
 }