1.背景
在我们项目开发中,很多时候需要记录访问ip地址,方便跟踪操作日志定位是哪个机器访问了我们的服务(逮住证据),或者根据ip做一些分析统计。
那么使用springboot自带的logback如何记录客户端访问ip呢?下面详细说明。
2.重写日志规则方法记录ip
创建IPLogConfig类实现ClassicConverter类重写convert方法获取请求上下文返回ip,如下:
package com.bylz.api.config;
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.bylz.api.utils.IpUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Author: lizhi
* Date: 2021-10-11
* Describe: 日志输出ip配置
*/
public class IPLogConfig extends ClassicConverter {
@Override
public String convert(ILoggingEvent event) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return "127.0.0.1";
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
return IpUtils.getIpAddr(request);
}
}
IpUtils工具类:
package com.bylz.api.utils;
import com.google.common.base.Strings;
import javax.servlet.http.HttpServletRequest;
/**
* @author lizhi
* @version 1.0
* @date 2021/8/31 11:33
*/
public class IpUtils {
private IpUtils(){
}
public static String getIpAddr(HttpServletRequest request) {
String xIp = request.getHeader("X-Real-IP");
String xFor = request.getHeader("X-Forwarded-For");
if (!Strings.isNullOrEmpty(xFor) && !"unKnown".equalsIgnoreCase(xFor)) {
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = xFor.indexOf(",");
if (index != -1) {
return xFor.substring(0, index);
} else {
return xFor;
}
}
xFor = xIp;
if (!Strings.isNullOrEmpty(xFor) && !"unKnown".equalsIgnoreCase(xFor)) {
return xFor;
}
if (Strings.nullToEmpty(xFor).trim().isEmpty() || "unknown".equalsIgnoreCase(xFor)) {
xFor = request.getHeader("Proxy-Client-IP");
}
if (Strings.nullToEmpty(xFor).trim().isEmpty() || "unknown".equalsIgnoreCase(xFor)) {
xFor = request.getHeader("WL-Proxy-Client-IP");
}