一、 背景
一直想给项目构建一个统一的日志收集系统,先迈出第一步,构建一个日志收集类,用AOP实现无侵入日志收集
二、 环境
1.此随笔内容基于spring boot项目
2.数据库为mysql 5.7.9版本
3.jdk 版本为1.8
三、 说明
此版采用数据库存储,之后考虑使用elasticsearch等工具存储
四、 内容
1、构建日志采集实体类:baseLogMessage
public class baseLogMessage {
private String serverIP;
private String appName;
private String method;
private String type;
private String userCode;
private String uri;
private String operationName;
private String operationStatus;
private long startTime;
private Object parameter;
private Object result;
private int SpendTime;
// 此处省略get、set
}
2、构建一个配置文件读取类,用于读取配置文件中的系统名称:SystemPropetiesUtil
@Configuration
public class SystemPropetiesUtil {
@Value("${spring.application.name}")
private String sysName;//系统名称
// 此处省略get、set
}
3、新建一个AOP类,在控制器方法上作为切点,执行日志收集: LogAspect
@Aspect
@Component
public class LogAspect {
@Autowired
private SystemPropetiesUtil systemPropetiesUtil;
//定义切点方法
@Pointcut("execution(public * cq..campus.prevented.controller.*.*(..))")
public void controllerLog() {
}
public static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class);
@Around("controllerLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
//获取当前请求对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//记录请求信息
baseLogMessage baseLogMessage = new baseLogMessage();
//1.获取到所有的参数值的数组
Object[] args = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
//2.获取到方法的所有参数名称的字符串数组
String[] parameterNames = methodSignature.getParameterNames();
Object result = joinPoint.proceed();
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(ApiOperation.class)) {
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
baseLogMessage.setOperationName(apiOperation.value());
}
long endTime = System.currentTimeMillis();
String urlStr = request.getRequestURL().toString();
baseLogMessage.setUri(urlStr);
baseLogMessage.setType("操作日志");
baseLogMessage.setServerIP(getRemoteIP(request));
baseLogMessage.setMethod(request.getMethod());
baseLogMessage.setAppName(systemPropetiesUtil.getSysName());
baseLogMessage.setResult(result);
baseLogMessage.setParameter(getParameter(method, joinPoint.getArgs()));
baseLogMessage.setSpendTime((int) (endTime - startTime));
baseLogMessage.setStartTime(endTime);
LOGGER.info("{}", JsonUtils.objectToJson(baseLogMessage));
// 数据库存储操作
return result;
}
@AfterThrowing(pointcut = "controllerLog()", throwing = "e")
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
long startTime = System.currentTimeMillis();
if(null==kafkaClient){
kafkaClient = KafkaProducerClient.getInstance(systemPropetiesUtil.getKafkaHost());
// redisClient= RedisClient.getInstance(systemPropetiesUtil.getReidsHost(), Integer.parseInt(systemPropetiesUtil.getRedisPort()), "");
}
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
String urlStr = request.getRequestURL().toString();
baseLogMessage baseLogMessage = new baseLogMessage();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
StringBuffer strbuff = new StringBuffer();
for (StackTraceElement stet : elements) {
strbuff.append(stet + "n");
}
String message = exceptionName + ":" + exceptionMessage + strbuff.toString();
try {
Object[] args = joinPoint.getArgs();
String[] parameterNames = methodSignature.getParameterNames();
long endTime = System.currentTimeMillis();
baseLogMessage.setUri(urlStr);
baseLogMessage.setType("异常日志");
baseLogMessage.setServerIP(getRemoteIP(request));
baseLogMessage.setMethod(request.getMethod());
baseLogMessage.setAppName(systemPropetiesUtil.getSysName());
baseLogMessage.setResult(message);
baseLogMessage.setParameter(getParameter(method, joinPoint.getArgs()));
baseLogMessage.setSpendTime((int) (endTime - startTime));
baseLogMessage.setStartTime(endTime);
LOGGER.info("{}", JsonUtils.objectToJson(baseLogMessage));
// 数据库存储操作
} catch (Exception e2) {
e2.printStackTrace();
}
}
private Object getParameter(Method method, Object[] args) {
List
五、 问题
1、如果方法正常执行,不进入AOP类,请检查AOP的切点是否书写正确。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



