需求: 记录日志时需要添加服务IP和服务编号(由UUID生成),便于运维人员在查看日志时定位到哪台服务器上的哪个服务。
基于spring web项目
1、 log4j2.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" monitorInterval="30">
<Properties>
<!-- 配置日志文件输出目录 -->
<Property name="LOG_HOME">/home/logs</Property>
</Properties>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1.}:%L - IP:%X{ip}&ID:%X{UUID} %msg%xEx%n" />
</Console>
<!-- 按天第天备份一个日志 -->
<RollingFile name="FILE" fileName="${LOG_HOME}/demo.log"
filePattern="${LOG_HOME}/demo.log.%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1.}:%L - %X{ip}&ID:%X{UUID} %msg%xEx%n" />
<Policies>
<!-- 每24小时更新一次 -->
<TimeBasedTriggeringPolicy modulate="true"
interval="24" />
<SizeBasedTriggeringPolicy size="128KB" />
</Policies>
<!-- 最多备份10个 -->
<DefaultRolloverStrategy max="10" />
</RollingFile>
</Appenders>
<Loggers>
<!--<Logger name="com.mosen" level="info">-->
<!--<AppenderRef ref="FILE" />-->
<!--</Logger>-->
<Root level="info">
<AppenderRef ref="CONSOLE" />
<AppenderRef ref="FILE"></AppenderRef>
</Root>
</Loggers>
</Configuration>
pattern格式配置
%d{yyyy-MM-dd HH:mm:ss.SSS} “d”, “date” 时间格式
%-5level “p”, “level” 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%class{1.} “C”, “class” 类名,包名只有1位
%C{3} 获取类名前3级目录(包含类名)
%L “L”, “line” 输出行号
%M “M”, “method” 输出所在方法名
%m “m”, “msg”, “message” 日志文本
%xEx “xEx”, “xThrowable”, “xException” ExtendedThrowablePatternConverter
“ex”, “throwable”, “exception” ThrowablePatternConverter
“rEx”, “rThrowable”, “rException” RootThrowablePatternConverter
%n 换行
其他占位符有(部分):
%l “l”, “location” 输出语句所在的行数, 包括类名、方法名、文件名、行数 例如:hahaha.Log4j2Test.main(Log4j2Test.java:15)
%T “T”, “tid”, “threadId” 输出线程ID
%t “t”, “tn”, “thread”, “threadName” 输出当前线程名称
%tp “tp”, “threadPriority” 输出线程权级
%F “F”, “file” 输出所在的类文件名,如Log4j2Test.java
%logger “c”, “logger” 输出logger名称,LogManager.getLogger(Log4j2Test.class);中的名称,此处是hahaha.Log4j2Test
%N “N”, “nano” 纳秒
%sn “sn”, “sequenceNumber” 日志计数(全局)
%u “u”, “uuid” UUID(全局)
%X{ip} “X”, “mdc”, “MDC” MDC方式获取ip(等同于 %MDC{ip} 和 %mdc{ip} )
%x “x”, “NDC” NDC方式
2、 过滤器类
log4j2中用ThreadContext代替MDC
package demo;
import org.apache.logging.log4j.ThreadContext;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class ThreadContextFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
ThreadContext.put("UUID", StaticUUID.ID); //StaticUUID是自己写的类,用于生成UUID常量。
ThreadContext.put("ip", request.getLocalAddr());
chain.doFilter(request, response);
} finally {
//清除ThreadContext,避免内存泄露
ThreadContext.clearAll();
}
}
@Override
public void destroy() {
}
}
3、 web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>log4jFilter</filter-name>
<filter-class>demo.ThreadContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>log4j2demo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>log4j2demo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
4、 Hello类测试
package demo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class Hello {
public static Logger logger = LogManager.getLogger();
@RequestMapping("/hello")
public void hello(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info("hello");
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
测试结果(多次刷新页面)
2017-06-28 21:04:59.013 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello
2017-06-28 21:06:48.364 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello
2017-06-28 21:06:49.203 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello
2017-06-28 21:06:49.900 INFO d.Hello:22 - IP:0:0:0:0:0:0:0:1&trace ID:5ba23654bc104e8b8019963084f16cb8 hello
其中IP:0:0:0:0:0:0:0:1等同于127.0.0.1,由于是本地访问,就会出现这个值。用别的机器访问就会正常。