views:

32

answers:

2

Logger

Hi,

I have a Spring MVC webapps that needs some server side logging so I configured Log4J in my Spring MVC

<listener>
 <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

In my controller, I logged all user transaction.

@Controller
public class MyController {
 protected final Log logger = LogFactory.getLog(getClass());

 public String setup(){
  MyObject object = new MyObject();

  logger.info("User check in data...." + object.data);
 }
}

I have some questions though:

  1. Are Logging in a Spring MVC Webapps considered a costly transaction? I mean will this slowdown my app?
  2. In a production enviroment, will it be OK if I leave out this logger.info? I need to add this for traceability of each transaction and is a requirement but I am worried about the impact of these.

Thanks

+1  A: 

Log4j has almost no overhead itself. It is designed to be compiled into your code and enabled or disabled by configuration.

When it is disabled, it is very fast. The only problem you may have is in preparing the log message, which will then not be used. You can avoid this with a guard:

 if (logger.isInfoEnabled()){  // in case object.data.toString() is costly
    logger.info("User check in data...." + object.data);
 }

When it is enabled, it obviously takes some time to write the message to the log file/daemon/database. However, since you have enabled it, you need that log message (you say you have a traceability requirement), so the fair comparison would be to creating the log message in another way. And here, the log4j overhead (versus calling the logging backend directly) is minimal.

The full cost of logging the message will thus be determined by what kind of backend you are using (and not by log4j itself).

Thilo
@Thilo. Excellent thought. Just some clarification though, what do you mean by this 'The full cost of logging the message will thus be determined by what kind of backend you are using'. You mean my SPring MVC Web App? Thanks..=)
Mark Estrada
No, I mean "the I/O for appending to a local file or an in-memory buffer or running a database query or talking to syslogd". And you may want to compare that cost to the time taken by the web app serving the user request (to do productive work) to see if it matters. Neither Log4J nor Spring should add too much overhead. Just try it out, and see if there is a bottleneck with logging.
Thilo
A: 

Before you continue, a brief disclaimer: as yet I have no experience with the spring MVC, however I have used log4j with basic java servlets and I believe the same principles apply.

Based on your provided code, you can do two things to improve the logging speed:

  • Declare logger as static:

protected static final Log logger = LogFactory.getLog(MyController.class);

If multiple instances of your object are created, this ensures you aren't creating a new logger each time (as creating or retrieving a logger is an expensive operation).

  • Guard using an if statement to check whether the specified level of logging is enabled, as per Thilo's answer. Not only will you avoid the costs of the toString() method (as he rightly pointed out), but you avoid unnecessary string concatenation.

If you follow these suggestions, the cost of logging when logging is disabled will be the initial setup cost of log4j + the initialization of a logger for each class using loggers + a single if statement to evaluate (and if I recall correctly, in log4j this boils down to the overhead of the function call plus a single integer comparison).

When logging is enabled, you have to account for any costs introduced by the appender you choose to use (for example, logging to a database will incur some overhead) as well as the time required to format the log information. For example, when using the PatternLayout, using the %F, %M, or %L patterns is an expensive operation as log4j generates this information by building a full stack trace.

Source: log4j introduction and log4j source code.

Caspar