All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.healthy.common.log.util.LogUtils Maven / Gradle / Ivy

The newest version!
package com.healthy.common.log.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.healthy.common.core.util.WebUtils;
import com.healthy.common.log.annotation.Log;
import com.healthy.common.log.enums.BusinessStatus;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.IntStream;

/**
 * 日志工具类
 *
 * @author xiaomingzhang
 */
@UtilityClass
public class LogUtils {

	public LogInfo getLogInfo(@NonNull ProceedingJoinPoint joinPoint, @NonNull Log log) {
		HttpServletRequest request = WebUtils.getRequest();
		LogInfo logInfo = new LogInfo();
		logInfo.setTitle(log.title());
		logInfo.setExtra(log.extra());
		logInfo.setBusinessType(log.businessType().ordinal());
		logInfo.setOperationTime(LocalDateTime.now());
		logInfo.setStatus(BusinessStatus.SUCCESS.ordinal());
		logInfo.setArgs(joinPoint.getArgs());

		// 设置方法名称
		String className = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		logInfo.setMethodName(className + StrPool.DOT + methodName + "()");

		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
		logInfo.setMethod(method);

		logInfo.setRemoteAddr(WebUtils.getClientIP(request));
		logInfo.setRequestUri(URLUtil.getPath(request.getRequestURI()));
		logInfo.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));

		String requestMethod = request.getMethod();
		logInfo.setRequestMethod(requestMethod);
		if (log.isSaveRequestData()) {
			if (StrUtil.equalsAnyIgnoreCase(requestMethod, HttpMethod.GET.name())) {
				logInfo.setParams(JSONUtil.toJsonStr(ServletUtil.getParamMap(request)));
			}
			else {
				logInfo.setParams(obtainMethodArgs(joinPoint));
			}
		}
		return logInfo;
	}

	private String obtainMethodArgs(ProceedingJoinPoint joinPoint) {
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		String[] argNames = methodSignature.getParameterNames();
		Object[] argValues = joinPoint.getArgs();
		// 拼接参数
		Map args = MapUtil.newHashMap(argValues.length);
		for (int i = 0; i < argNames.length; i++) {
			String argName = argNames[i];
			Object argValue = argValues[i];
			// 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
			args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
		}
		return JSONUtil.toJsonStr(args);
	}

	private boolean isIgnoreArgs(Object object) {
		Class clazz = object.getClass();
		// 处理数组的情况
		if (clazz.isArray()) {
			return IntStream.range(0, Array.getLength(object))
					.anyMatch(index -> isIgnoreArgs(Array.get(object, index)));
		}
		// 递归,处理数组、Collection、Map 的情况
		if (Collection.class.isAssignableFrom(clazz)) {
			return ((Collection) object).stream().anyMatch((Predicate) LogUtils::isIgnoreArgs);
		}
		if (Map.class.isAssignableFrom(clazz)) {
			return isIgnoreArgs(((Map) object).values());
		}
		// obj
		return object instanceof MultipartFile || object instanceof HttpServletRequest
				|| object instanceof HttpServletResponse;
	}

}