log4j增加输出访问者ip、session等相关信息

背景介绍

在当前服务器中日志输出并没有访问者ip等相关信息,所以增加需求,需要在日志中打印访问者的ip

实现步骤

1:首先下载log4j.jar包并将其导入到项目中
2:建立一个log4j.xml或者是log4j.properties文件。(我此处选择的是log4j.xml文件)

<?xml version="1.0" encoding="UTF-8"?>       
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">      
          
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> 
 <appender name="myFile" class="org.apache.log4j.RollingFileAppender">    
		 <!--设置日志名称-->      
        <param name="File" value="D:/output.log" />>       
        <!--设置日志编码--> 
        <param name="Encoding" value="GBK" />
        <!--设置是否在重新启动服务时,在原有日志的基础添加新日志-->       
        <param name="Append" value="true" /> 
        <!--设置日志文件大小--> 
        <param name="MaxFileSize" value="50MB" />    
        <!--设置日志文件个数-->   
        <param name="MaxBackupIndex" value="10" />   
        <param name="DatePattern" value="'.'yyyy-MM-dd" />    
        <layout class="org.apache.log4j.PatternLayout">       
            <param name="ConversionPattern" 
             value="[%d{MMdd HH:mm:ss SSS\} %-5P] [%X{requestCode}:%X{userId}:%X{sessionId}:%X{ip}] [%t] %c{1}.%M(%L) | %m%n" />       
        </layout>       
    </appender> 

	<logger name="org.apache">
		<level value="debug"/>
	</logger>
	<root>
		<level value="debug"/>
		<appender-ref ref="myFile"/>
	</root>
</log4j:configuration>        

3:web.xml文件中增加过滤器

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">
		
		<!-- 其他配置省略 -->
		<filter>
			<filter-name>Log4jMDCFilter</filter-name>
			<!-- 此处为你所建立类Log4jMDCFilter的路径 -->
			<filter-class>*.Log4jMDCFilter</filter-class>
		</filter>
		<filter-mapping>
			<filter-name>Log4jMDCFilter</filter-name>
			<!-- filter中路径不支持写 /  -->
			<url-pattern>/*</url-pattern>
		</filter-mapping>
  </web-app>

4:建立对应的filter实现个性化配置

public class Log4jMDCFilter extends GenericFilterBean{
	static final Logger logger = LoggerFactory.getLogger(Log4jMDCFilter .calss);
	// 当前登录用户的信息
	private static final String REQUESTCODE = "requestCode";
	private static final String USERID= "userId";
	private static final String SESSIONID= "sessionId";
	private static final String IP= "ip";
	// 默认信息
	private static final String DEFAULT_USERID= "default_userId";
	private static final String DEFAULT_SESSIONID= "default_sessionId";
	private static final String DEFAULT_IP= "default_ip";

	@Override
	public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain) throws IOException,ServletException{
		try[
			HttpServletRequest req = (HttpServletRequest )request;
			HttpServletResponse res = (HttpServletResponse )response;
			pushMDC(req,res);
			filterChain.doFilter(request,response);
		} finally{
			clearMDC();	
		}
	}

	// 增加日志输出所需要的参数 
	protected void pushMDC(HttpServletRequest request,HttpServletResponse response){
		String requestCode = UUID.randomUUID().toString();
		MDC.put(REQUESTCODE,requestCode);

		String ip = request.getHeader("x-forwarded-for");
		if(StringUtils.isNotBlank(ip)){
			ip = ip.split(",")[0];
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getHeader("Proxy-Client-IP");  
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getHeader("WL-Proxy-Client-IP"); 
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getHeader("HTTP_CLIENT_IP");  
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getHeader("X-Real-IP");
		}
		if(StringUtils.isBlank(ip) || StringUtils.equalsIgnoreCase("unknown",ip)){
			ip = request.getRemoteAddr(); 
		}

		if(StringUtils,isEmpty(ip)){
			MDC.put(IP,DEFAULT_IP);
		} else {
			if(logger.isDebugEnabled()){
				logger.info("request ip is->" + ip);
			}
			MDC.put(IP,ip);
		}

		HttpSession session = request.getSession(false);
		if(session == null){
			MDC.put(SESSIONID,DEFAULT_SESSIONID);
		} else {
			if(logger.isDebugEnabled()){
				logger.info("request sessionId is->" + session.getId());
			}
			MDC.put(SESSIONID,session.getId());
		}

		String userId = getUserId(request);
		if(StringUtils.isBlank(userId)){
			MDC.put(USERID,DEFAULT_USERID);
		} else {
			if(logger.isDebugEnabled()){
				logger.info("request userIdis->" + userId );
			}
			MDC.put(USERID,userId );
		}
	}

	potected static String getUserId(HttpServletRequest request){
		// 根据自己的服务进行实现
		// 下面是我自己项目的实现方式
		HttpSession session = request.getSession(false);
		if(session == null){
			if(logger.isErrorEnabled()){
				logger.info("session is null");
			}
			return  null;
		}
		Object userId = session.getAttribute("自己安全认证配置文件中配置的常量名");
		if(null != userId)[
		 	return userId.toString;
		} else {
			SecurityConterxt sc = SecurityConterxtHolder.getContext();
			if(sc == null){
				if(logger.isErrorEnabled()){
					logger.info(" The SecurityConterxt is null");
				}
				return  null;
			}
			Authentication at = sc.getAuthentication();
			if(at != null && at.getPrincipal() != null){
				T user = (T)at.getPrincipal();
				if(user != null){
					String userId = user.getUserId();
					session.setAttribute("自己安全认证配置文件中配置的常量名",userId);
					return userId;
				} else {
					if(logger.isErrorEnabled()){
						logger.info("The user is null");
					}
					return  null;
				}
			} else {
				if(logger.isErrorEnabled()){
					logger.info(" The Authentication is null or The Principal is null");
				}
				return  null;
			}
		}
	}
	potected void clearMDC(){
		MDC.clear();
	}
}

重启项目,此时再次访问就会记录访问者的ip。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值