maven pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.6.2</version>
</dependency>
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<Properties>
<!--${web:rootDir} 的使用需要配置web.xml-->
<Property name="webroot">${web:rootDir}</Property>
</Properties>
<Appenders>
<Console name="DEBUGSTDOUT" target="SYSTEM_OUT">
<MarkerFilter marker="DEBUGMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c - %m%n</Pattern>
</PatternLayout>
</Console>
<Console name="TRACESTDOUT" target="SYSTEM_OUT">
<MarkerFilter marker="TRACEMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c - %m%n</Pattern>
</PatternLayout>
</Console>
<Console name="INFOSTDOUT" target="SYSTEM_OUT">
<MarkerFilter marker="INFOMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c - %m%n</Pattern>
</PatternLayout>
</Console>
<Console name="WARNSTDOUT" target="SYSTEM_OUT">
<MarkerFilter marker="WARNMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c - %m%n</Pattern>
</PatternLayout>
</Console>
<Console name="ERRORSTDOUT" target="SYSTEM_OUT">
<MarkerFilter marker="ERRORMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c - %m%n</Pattern>
</PatternLayout>
</Console>
<RollingRandomAccessFile name="TraceFile" fileName="${webroot}/logs/trace/trace.log"
filePattern="logs/trace/$${date:yyyy-MM}/trace-%d{yyyy-MM-dd-HH}-%i.log.gz">
<MarkerFilter marker="TRACEMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c{1.} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="200 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="InfoFile" fileName="${webroot}/logs/info/info.log"
filePattern="logs/info/$${date:yyyy-MM}/info-%d{yyyy-MM-dd-HH}-%i.log.gz">
<MarkerFilter marker="INFOMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c{1.} - %m%n</Pattern>
</PatternLayout>
<Policies>
<!-- Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time
and size based triggering policies, will create up to 7 archives on the same day (1-7) that are stored in
a directory based on the current year and month, and will compress each archive using gzip and will
roll every 6 hours when the hour is divisible by 6 -->
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="200 MB"/>
</Policies>
</RollingRandomAccessFile>
<!-- warn file will be store operation info,warn -->
<RollingRandomAccessFile name="WarnFile" fileName="${webroot}/logs/warn/warn.log"
filePattern="logs/warn/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd-HH}-%i.log.gz">
<MarkerFilter marker="WARNMARKER" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c{1.} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="8" modulate="true"/>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
</RollingRandomAccessFile>
<!-- error file will be store error -->
<RollingRandomAccessFile name="ErrorFile" fileName="${webroot}/logs/error/error.log"
filePattern="logs/error/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH}-%i.log.gz">
<MarkerFilter marker="ERRORMARKER" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %c{1.} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="8" modulate="true"/>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ErrorFile" level="ERROR"/>
<AppenderRef ref="WarnFile" level="WARN"/>
<AppenderRef ref="InfoFile" level="INFO"/>
<AppenderRef ref="STDOUT2" level="TRACE"/>
<AppenderRef ref="STDOUT" level="DEBUG"/>
</Root>
<!-- 调试阶段可使用console输出
<Root level="debug">
<AppenderRef ref="ERRORSTDOUT" level="ERROR"/>
<AppenderRef ref="WARNSTDOUT" level="WARN"/>
<AppenderRef ref="INFOSTDOUT" level="INFO"/>
<AppenderRef ref="TRACESTDOUT" level="TRACE"/>
<AppenderRef ref="DEBUGSTDOUT" level="DEBUG"/>
</Root>
-->
</Loggers>
</configuration>
web.xml
<!-- log4j web listener must place before others listener,otherwise log4j2 can't find ${web:rootDir} when others listener using Log -->
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>
Log.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.MarkerManager;
public class Log {
public static void trace(Object value){
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).debug(MarkerManager.getMarker("TRACEMARKER"), caller[1] + ": " + value);
}
public static void debug(Object value){
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).debug(MarkerManager.getMarker("DEBUGMARKER"), caller[1] + ": " + value);
}
public static void info(Object value)
{
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).info(MarkerManager.getMarker("INFOMARKER"), caller[1] + ": " + value);
}
public static void warn(Object value)
{
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).warn(MarkerManager.getMarker("WARNMARKER"), caller[1] + ": " + value);
}
public static void error(Object value)
{
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).error(MarkerManager.getMarker("ERRORMARKER"), caller[1] + ":" + value);
}
public static void fatal(Object value)
{
Object[] caller = getCallerInfo();
LogManager.getLogger((Class<?>)caller[0]).fatal(MarkerManager.getMarker("FATALMARKER"), caller[1] + ": " + value);
}
protected static Object[] getCallerInfo()
{
Object[] ret = new Object[2];
try
{
StackTraceElement[] stack = new Throwable().getStackTrace();
StackTraceElement ste = stack[2];
ret[0] = Class.forName(ste.getClassName());
ret[1] = ste.getMethodName();
}catch (Exception localException) {}
return ret;
}
}
Sample.java
Log.trace("your trace info")
Log.debug("your debug info")