代码比较简单,直接看注释吧。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* aop系统日志注解
*
* @author TenSunLee
* @date 2019/7/26
* @version 1.0.0
* @updateBy TenSunLee
* @updated 2019/7/26
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLogger {
/**
* 对调用方法的简单描述
* @return 描述内容
*/
String description() default "";
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
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;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;
/**
* service日志切面类
*
* @author TenSunLee
* @date 2019/7/25
* @version 1.0.0
* @updateBy TenSunLee
* @updated 2019/7/29
*
*/
@Aspect
@Component
public class SystemLogAspect {
/**
* 定义切入点为SystemLogger注解
*/
@Pointcut("@annotation(com.bosssoft.hr.train.jl.boss.bes.basedat.center.aspect.annotation.SystemLogger)")
public void logPointcut(){};
/**
* 日志对象
*/
private static org.slf4j.Logger logger = LoggerFactory.getLogger("System_ControllerLogger");
/**
*记录controller接受请求和响应的状况
*
* @param pjp 切点
*/
@Around(value = "logPointcut()", argNames = "pjp")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
//前置日置记录
//获取方法参数
Object[] args = pjp.getArgs();
StringBuilder stringBuilder = new StringBuilder();
for(Object arg:args){
stringBuilder.append(arg).append(":");
}
String params = stringBuilder.toString();
//获取方法名
String methodName = pjp.getTarget().getClass().getName() + "."
+ pjp.getSignature().getName() + "()";
Method method = ((MethodSignature)pjp.getSignature()).getMethod();
//获取注解中的description参数
SystemLogger systemLoggerAnno = method.getAnnotation(SystemLogger.class);
String methodDescription = "";
if(null!= systemLoggerAnno) {
methodDescription = systemLoggerAnno.description();
}
//尝试获取request对象
HttpServletRequest request = null;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(null!=requestAttributes){
request = ((ServletRequestAttributes) requestAttributes).getRequest();
}
//尝试获取ip及user-agent
String ipAddr = null;
String userAgent = null;
if(null!=request){
ipAddr = getIpAddress(request);
userAgent = request.getHeader("user-agent");
}
//获取本次方法执行唯一标识UUID
String uuid = UUID.randomUUID().toString();
//拼接方法执行前日志字符串
String beforeLogString = uuid + "\n::" + new Date() + "\n::进入方法"+methodName +
"\n::" + methodDescription + "\n::客户端ip地址为" + ipAddr + "\n::客户端信息" +
userAgent + "\n::参数为\n:: " + params;
logger.info(beforeLogString);
long start = System.currentTimeMillis();
//执行原方法
Object ret = pjp.proceed();
long end = System.currentTimeMillis();
//后置日志记录
//拼接方法返回后日志字符串
String afterLogString = uuid + "\n::" + new Date() + "\n::离开方法" + methodName +
"\n::" + methodDescription + "\n::响应对象为\n:: " + ret + "\n::方法执行时间为" +
(end-start) + "ms.";
logger.info(afterLogString);
return ret;
}
/**
* 获取客户端IP地址
*
* @param request request对象
* @return ip地址字符串
*/
private String getIpAddress(HttpServletRequest request) {
String ip = null;
//X-Forwarded-For:Squid 服务代理
String ipAddresses = request.getHeader("X-Forwarded-For");
String unknown = "unknown";
if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
//Proxy-Client-IP:apache 服务代理
ipAddresses = request.getHeader("Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
//WL-Proxy-Client-IP:weblogic 服务代理
ipAddresses = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
//HTTP_CLIENT_IP:有些代理服务器
ipAddresses = request.getHeader("HTTP_CLIENT_IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
//X-Real-IP:nginx服务代理
ipAddresses = request.getHeader("X-Real-IP");
}
//有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
if (ipAddresses != null && ipAddresses.length() != 0) {
ip = ipAddresses.split(",")[0];
}
//还是不能获取到,最后再通过request.getRemoteAddr();获取
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
本文介绍如何使用面向切面编程(AOP)来实现应用程序的日志记录功能,通过在关键点插入日志代码,达到日志统一管理的目的。详细步骤和代码注释帮助理解实践过程。
550

被折叠的 条评论
为什么被折叠?



