How to use SLF4J Loggers in a JSP
Question
I'm in the process of migrating the logging of a middle-sized application from a custom solution to something more standard. I've decided on using Logback and SLF4J, and I have successfully migrated most of the Java code. However, I have quite a bit of JSPs that simply use System.out for logging. I've never worked much with JSPs, and started to wonder: how am I supposed to use proper logging in a JSP?
<%@page import="org.slf4j.Logger"%>
<%@page import="org.slf4j.LoggerFactory"%>
<%
Logger log = LoggerFactory.getLogger(getClass());
%>
<!-- ... -->
<%
log.info("Hello Logging!");
%>
This is what came to mind first, but it seems wrong on several points:
- way too verbose, and needs a lot of work to convert the existing JSPs
- a call is made to LoggerFactory.getLogger() every time the page is rendered (as opposed to a static
logger
field in a standard Java class) - I think the name of the logger is also going to be something not really straightforward this way
Is there some kind of standard, or a best practice, or anything for logging in JSPs?
Also, IIRC, there was some kind of taglib for Log4J. Is there something similar for SLF4J (or maybe Logback)?
Solution
Have a look at slf4j-taglib.
OTHER TIPS
You could try (Note the "!")
<%! org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("JSPname"); %>
Then replace your System.out's with
<% log.info("Hello Logging!"); %>
Boris's comment should really be taken into concideration though, JSPs should not need logging in general. I would only use this technique (or anything similiar) to replace existing logging that needed to be kept.
public enum MyLoggerFactory {
INSTANCE;
@SuppressWarnings("unchecked")
private final Map<Class, Logger> loggers = new HashMap<Class, Logger>();
@SuppressWarnings("unchecked")
public Logger getLogger(Class clazz) {
if (loggers.get(clazz) == null) {
loggers.put(clazz, LoggerFactory.getLogger(clazz));
}
return loggers.get(clazz);
}
}
Then your JSP page could look like:
<%
MyLoggerFactory.INSTANCE.getLogger(getClass()).info("Hello Logging!");
%>
To use logger in the jsp file, initialize the logger object in the following way:
<% Logger logger = LoggerFactory.getLogger(this.getClass()); %>
And then you could go ahead by using
logger.info(); or logger.error();, etc.
I think it's bad practice to trigger logging from withing the representational layer of an application. Generally, I would expect to find logging in the business logic only - a JSP cluttered with logging invocation would certainly break the separation of concerns principle.
As a temporary, yet elegant workaround, you could try and create a custom tag lib.