|
@@ -0,0 +1,159 @@
|
|
|
+/*
|
|
|
+ * The MIT License (MIT)
|
|
|
+ *
|
|
|
+ * Copyright © 2021 xrv <xrg@live.com>
|
|
|
+ *
|
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
+ * of this software and associated documentation files (the "Software"), to deal
|
|
|
+ * in the Software without restriction, including without limitation the rights
|
|
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
+ * copies of the Software, and to permit persons to whom the Software is
|
|
|
+ * furnished to do so, subject to the following conditions:
|
|
|
+ *
|
|
|
+ * The above copyright notice and this permission notice shall be included in
|
|
|
+ * all copies or substantial portions of the Software.
|
|
|
+ *
|
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
+ * THE SOFTWARE.
|
|
|
+ */
|
|
|
+
|
|
|
+package com.tzld.piaoquan.api.aop;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.google.common.base.Strings;
|
|
|
+import com.tzld.commons.aliyun.log.AliyunLogManager;
|
|
|
+import com.tzld.piaoquan.growth.common.utils.IpUtil;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.aspectj.lang.JoinPoint;
|
|
|
+import org.aspectj.lang.annotation.*;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.slf4j.MDC;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.context.request.RequestContextHolder;
|
|
|
+import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 请求日志记录
|
|
|
+ *
|
|
|
+ * @author ehlxr
|
|
|
+ * @since 2021-12-14 14:03.
|
|
|
+ */
|
|
|
+@Aspect
|
|
|
+@Component
|
|
|
+public class LogRequestAop {
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(LogRequestAop.class);
|
|
|
+
|
|
|
+ private final AliyunLogManager aliyunLogManager;
|
|
|
+ /**
|
|
|
+ * aliyun log 配置
|
|
|
+ */
|
|
|
+ @Value("${aliyun.log.project:}")
|
|
|
+ private String projcet;
|
|
|
+ @Value("${aliyun.log.logstore.request:request-log}")
|
|
|
+ private String logStore;
|
|
|
+ @Value("${aliyun.log.topic:}")
|
|
|
+ private String topic;
|
|
|
+
|
|
|
+ private String LOG_TRACE_ID = "logTraceId";
|
|
|
+ private String REQUEST_START_TIME = "request_start_time";
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public LogRequestAop(AliyunLogManager aliyunLogManager) {
|
|
|
+ this.aliyunLogManager = aliyunLogManager;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切入点
|
|
|
+ */
|
|
|
+ @Pointcut("execution(public * com.tzld.piaoquan.api.controller..*(..)) " +
|
|
|
+ "&& !@annotation(com.tzld.piaoquan.api.annotation.NoRequestLog)")
|
|
|
+ public void requestLog() {
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 前置操作
|
|
|
+ */
|
|
|
+ @Before("requestLog()")
|
|
|
+ public void beforeLog() {
|
|
|
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
|
+ HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
|
|
|
+
|
|
|
+ request.setAttribute(REQUEST_START_TIME, System.currentTimeMillis());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 后置操作
|
|
|
+ */
|
|
|
+ @AfterReturning(pointcut = "requestLog()", returning = "returnValue")
|
|
|
+ public void afterReturning(JoinPoint point, Object returnValue) {
|
|
|
+ logRecord(point, JSON.toJSONString(returnValue));
|
|
|
+ }
|
|
|
+
|
|
|
+ @AfterThrowing(pointcut = "requestLog()", throwing = "ex")
|
|
|
+ public void afterThrowing(JoinPoint point, Exception ex) {
|
|
|
+ logRecord(point, ex.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void logRecord(JoinPoint point, String message) {
|
|
|
+ try {
|
|
|
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
|
+ HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
|
|
|
+
|
|
|
+ Long startTime = (Long) request.getAttribute(REQUEST_START_TIME);
|
|
|
+ if (Objects.isNull(startTime)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String query = request.getQueryString();
|
|
|
+ String uri = request.getRequestURI();
|
|
|
+
|
|
|
+ Map<String, Object> logMap = new HashMap<>(8);
|
|
|
+ String url = Strings.isNullOrEmpty(query) ? uri : uri + "?" + query;
|
|
|
+ if (StringUtils.isNotBlank(url) && url.contains("/test")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ logMap.put("url", url);
|
|
|
+ logMap.put("method", request.getMethod());
|
|
|
+ logMap.put("header", getHeaders(request));
|
|
|
+ logMap.put("elapsedTime", String.valueOf(System.currentTimeMillis() - startTime));
|
|
|
+ logMap.put("clientIp", IpUtil.getIpAddr(request));
|
|
|
+ logMap.put("requestBody", getRequestBody(point.getArgs()));
|
|
|
+ logMap.put(LOG_TRACE_ID, Strings.nullToEmpty(MDC.get(LOG_TRACE_ID)));
|
|
|
+ logMap.put("responseBody", message);
|
|
|
+ aliyunLogManager.sendLog(projcet, logStore, topic, logMap);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("log report request error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Object getRequestBody(Object[] args) {
|
|
|
+ try {
|
|
|
+ return JSON.toJSONString(args[0]);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return args;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getHeaders(HttpServletRequest request) {
|
|
|
+ return Collections.list(request.getHeaderNames())
|
|
|
+ .stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ name -> name,
|
|
|
+ request::getHeader)).toString();
|
|
|
+ }
|
|
|
+}
|