Грубоватое решение, но тем не менее...
Для начало нужно создать реализацию
ServletRequestListener, в котором мы будем получать id сессии и ассоциировать с потоком обрабатывающем текущий запрос с помощью
ThreadLocal.
package ua.home.web.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
public class RequestListener implements ServletRequestListener {
private static final ThreadLocal<String> sessionIds = new ThreadLocal<>();
public static String getCurrentSessionId() {
return sessionIds.get();
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
String id = request.getSession().getId();
sessionIds.set(id);
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) { }
}
Листенер можно зарегистрировать или пометив его аннотацией
@WebListener (для
Servlet API 3.x), или по старинки, прописав его в
web.xml<listener>
<listener-class>ua.home.web.listener.RequestListener</listener-class>
</listener>
С помощью нашего статического метода
ServletRequestListener.getCurrentSessionId()
мы сможем получать id сессии вне сервлета.
Далее нам нужно переопределить метод format класса
PatternLayout и прописать новую реализацию в
log4j.properties.
В новой реализации метода, мы будет получать id сессии и заменять наш псевдопаттер в строке лога на id.
package ua.home.web.log;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import ua.home.web.listener.RequestListener;
public class CustomPatternLayout extends PatternLayout {
@Override
public String format(LoggingEvent event) {
return super.format(event).replace("%sid", RequestListener.getCurrentSessionId());
}
}
Файл
log4j.propertieslog4j.rootCategory=INFO,S
log4j.appender.S=org.apache.log4j.ConsoleAppender
log4j.appender.S.layout=ua.home.web.log.CustomPatternLayout
log4j.appender.S.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %sid %m%n
Теперь, если мы где то вызовем, например
LOG.info("log message")
, то в лог у нас запишется строка:
2016-08-23 12:20:18 TestServlet [INFO] 441135221F8A492364C836560BDEE15E log message