Logging
Logging support
Struts logs through Log4j2. The struts2-core artifact declares log4j-api
and log4j-core, and configuration is plain Log4j2 configuration — a log4j2.xml on the classpath, typically under
src/main/resources. See Debugging Struts for an example configuration and the
framework packages worth raising to DEBUG.
The pluggable logging layer that XWork used to provide — com.opensymphony.xwork2.util.logging.LoggerFactory, the
xwork.loggerFactory system property and the Commons Logging / SLF4J / JDK Logger delegates — was deprecated in
Struts 2.5 and removed in Struts 6.0.0. There is no framework-level logging abstraction to configure any more, and
setting -Dxwork.loggerFactory has no effect.
The Log4j2 bridges for third-party libraries (log4j-jcl for Commons Logging, log4j-slf4j-impl for SLF4J) are a
separate concern and remain available. They route logging emitted by transitive dependencies into Log4j2.
Struts 7.3.0 finished the job: the last java.util.logging and SLF4J call sites inside the framework — in the
dependency-injection container, its finalizable reference queue and the Tiles plugin’s Velocity renderable — now log
through Log4j2, and the slf4j-api dependency was dropped from struts2-core, see
WW-5620. That dependency was declared optional, so it was never
propagated to applications and nothing changes on your classpath. Struts 6.11.0 still declares it.
Removed in Struts 7.3.0: the internal DI container no longer provides a Logger binding. @Inject-ing a
java.util.logging.Logger into a container-managed bean used to yield a JUL logger named after the declaring class;
that binding was removed along with the JUL usage, so such an injection no longer resolves. Declare a Log4j2 logger
directly instead, as shown below.
Usage
Declare a Log4j2 logger in your own classes as usual:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyAction {
private static final Logger LOG = LogManager.getLogger(MyAction.class);
private String userName;
public String execute() {
LOG.debug("MyAction executed with UserName [{}]", userName);
return "success";
}
// getter / setter
}
Note the {} placeholder — Log4j2 parameterised messages, not the #0 syntax used by the removed XWork logger.
Routing Struts logging elsewhere
Because Struts logs against the Log4j2 API rather than its own abstraction, redirecting its output is a Log4j2
concern: either configure Log4j2 appenders as you need them, or put a bridge to your logging backend of choice on the
classpath in place of log4j-core. Nothing needs to be declared in struts.xml.