95f26b4ad5eda1a488e76545592bc9ef17894c58
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  # Copyright (c) 2020, CMCC Technologies Co., Ltd.
6  #
7  # Licensed under the Apache License, Version 2.0 (the "License")
8  # you may not use this file except in compliance with the License.
9  # You may obtain a copy of the License at
10  #
11  #       http://www.apache.org/licenses/LICENSE-2.0
12  #
13  # Unless required by applicable law or agreed to in writing, software
14  # distributed under the License is distributed on an "AS IS" BASIS,
15  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  # See the License for the specific language governing permissions and
17  # limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.adapters.nssmf.interceptor;
21
22 import lombok.Data;
23 import lombok.ToString;
24 import org.aspectj.lang.JoinPoint;
25 import org.aspectj.lang.ProceedingJoinPoint;
26 import org.aspectj.lang.annotation.*;
27 import org.aspectj.lang.reflect.MethodSignature;
28 import org.onap.so.adapters.nssmf.annotation.RequestLogger;
29 import org.onap.so.adapters.nssmf.annotation.ServiceLogger;
30 import org.onap.so.adapters.nssmf.exceptions.ApplicationException;
31 import org.onap.so.adapters.nssmf.util.NssmfAdapterUtil;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.core.annotation.Order;
35 import org.springframework.stereotype.Component;
36 import org.springframework.web.context.request.RequestContextHolder;
37 import org.springframework.web.context.request.ServletRequestAttributes;
38 import org.springframework.web.multipart.MultipartFile;
39 import javax.servlet.http.HttpServletRequest;
40 import java.lang.reflect.Method;
41 import java.util.HashMap;
42 import java.util.Map;
43
44 /**
45  * support to print logger of service method
46  */
47 @Aspect
48 @Order(100)
49 @Component
50 public class RequestLogAspect {
51
52     private static final Logger logger = LoggerFactory.getLogger(RequestLogAspect.class);
53
54     @Pointcut("execution(* org.onap.so.adapters.nssmf.service..*(..))")
55     public void serviceLogger() {
56
57     }
58
59     @Around("serviceLogger()")
60     public Object around(ProceedingJoinPoint joinPoint) {
61         try {
62             MethodSignature signature = (MethodSignature) joinPoint.getSignature();
63             Method method = signature.getMethod();
64
65             Class<?> targetClass = method.getDeclaringClass();
66
67             StringBuilder classAndMethod = new StringBuilder();
68             ServiceLogger classAnnotation = targetClass.getAnnotation(ServiceLogger.class);
69             ServiceLogger methodAnnotation = method.getAnnotation(ServiceLogger.class);
70
71             if (classAnnotation == null && methodAnnotation == null) {
72                 return joinPoint.proceed();
73             }
74
75             if (classAnnotation != null) {
76                 if (classAnnotation.ignore()) {
77                     return joinPoint.proceed();
78                 }
79                 classAndMethod.append(classAnnotation.value()).append("-");
80             }
81
82             String target = targetClass.getName() + "#" + method.getName();
83
84             String params = NssmfAdapterUtil.marshal(joinPoint.getArgs());
85
86             logger.info("{} Start: Method = {} \nParams = {}", classAndMethod.toString(), target, params);
87
88             long start = System.currentTimeMillis();
89             Object result = joinPoint.proceed();
90             long timeConsuming = System.currentTimeMillis() - start;
91
92             logger.info("\n{} End: Method = {}, Spend time = {}ms \nResult = {}", classAndMethod.toString(), target,
93                     timeConsuming, NssmfAdapterUtil.marshal(result));
94             return result;
95
96         } catch (Throwable e) {
97             logger.error(e.getMessage(), e);
98         }
99         return null;
100     }
101
102     @Pointcut("execution(* org.onap.so.adapters.nssmf.controller..*(..))")
103     public void controllerLogger() {
104
105     }
106
107     @Around("controllerLogger()")
108     public Object doAroundRequest(ProceedingJoinPoint point) throws Throwable {
109         MethodSignature signature = (MethodSignature) point.getSignature();
110         Method method = signature.getMethod();
111         Class<?> targetClass = method.getDeclaringClass();
112
113         RequestLogger classAnnotation = targetClass.getAnnotation(RequestLogger.class);
114         RequestLogger methodAnnotation = method.getAnnotation(RequestLogger.class);
115
116         if ((classAnnotation == null && methodAnnotation == null)
117                 || (classAnnotation != null && classAnnotation.ignore())
118                 || (methodAnnotation != null && methodAnnotation.ignore())) {
119             return point.proceed();
120         }
121
122         long start = System.currentTimeMillis();
123         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
124
125         assert attributes != null;
126         HttpServletRequest request = attributes.getRequest();
127         Object result = point.proceed();
128         RequestInfo requestInfo = new RequestInfo();
129         requestInfo.setIp(request.getRemoteAddr());
130         requestInfo.setUrl(request.getRequestURL().toString());
131         requestInfo.setHttpMethod(request.getMethod());
132         requestInfo.setClassMethod(String.format("%s.%s", signature.getDeclaringTypeName(), signature.getName()));
133         requestInfo.setRequestParams(getRequestParamsByProceedingJoinPoint(point));
134         requestInfo.setResult(result);
135         requestInfo.setTimeCost(System.currentTimeMillis() - start);
136         logger.info("Request Info      : {}", NssmfAdapterUtil.marshal(requestInfo));
137         return result;
138     }
139
140     @AfterThrowing(pointcut = "controllerLogger()", throwing = "e")
141     public void doAfterRequestThrow(JoinPoint joinPoint, RuntimeException e) {
142         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
143         Method method = signature.getMethod();
144         Class<?> targetClass = method.getDeclaringClass();
145
146         RequestLogger classAnnotation = targetClass.getAnnotation(RequestLogger.class);
147         RequestLogger methodAnnotation = method.getAnnotation(RequestLogger.class);
148
149         if ((classAnnotation == null && methodAnnotation == null)
150                 || (classAnnotation != null && classAnnotation.ignore())
151                 || (methodAnnotation != null && methodAnnotation.ignore())) {
152             return;
153         }
154         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
155         assert attributes != null;
156         HttpServletRequest request = attributes.getRequest();
157         RequestErrorInfo requestErrorInfo = new RequestErrorInfo();
158         requestErrorInfo.setIp(request.getRemoteAddr());
159         requestErrorInfo.setUrl(request.getRequestURL().toString());
160         requestErrorInfo.setHttpMethod(request.getMethod());
161         requestErrorInfo.setClassMethod(String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName(),
162                 joinPoint.getSignature().getName()));
163         requestErrorInfo.setRequestParams(getRequestParamsByJoinPoint(joinPoint));
164         requestErrorInfo.setException(e);
165         String res;
166         try {
167             res = NssmfAdapterUtil.marshal(requestErrorInfo);
168             logger.info("Error Request Info      : {}", res);
169         } catch (ApplicationException ex) {
170             logger.info("Error Request Info      : {}", requestErrorInfo);
171         }
172     }
173
174     private Map<String, Object> getRequestParamsByJoinPoint(JoinPoint joinPoint) {
175         String[] paramNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
176         Object[] paramValues = joinPoint.getArgs();
177
178         return buildRequestParam(paramNames, paramValues);
179     }
180
181
182     private Map<String, Object> getRequestParamsByProceedingJoinPoint(ProceedingJoinPoint proceedingJoinPoint) {
183         String[] paramNames = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames();
184         Object[] paramValues = proceedingJoinPoint.getArgs();
185
186         return buildRequestParam(paramNames, paramValues);
187     }
188
189     private Map<String, Object> buildRequestParam(String[] paramNames, Object[] paramValues) {
190         Map<String, Object> requestParams = new HashMap<>();
191         for (int i = 0; i < paramNames.length; i++) {
192             Object value = paramValues[i];
193
194             if (value instanceof MultipartFile) {
195                 MultipartFile file = (MultipartFile) value;
196                 value = file.getOriginalFilename();
197             }
198
199             requestParams.put(paramNames[i], value);
200         }
201
202         return requestParams;
203     }
204
205     @Data
206     @ToString
207     private class RequestInfo {
208         private String ip;
209         private String url;
210         private String httpMethod;
211         private String classMethod;
212         private Object requestParams;
213         private Object result;
214         private Long timeCost;
215     }
216
217     @Data
218     @ToString
219     private class RequestErrorInfo {
220         private String ip;
221         private String url;
222         private String httpMethod;
223         private String classMethod;
224         private Object requestParams;
225         private RuntimeException exception;
226     }
227 }