3030</properties >
3131
3232<dependencies >
33+ <dependency >
34+ <groupId >com.google.guava</groupId >
35+ <artifactId >guava</artifactId >
36+ </dependency >
37+
3338<dependency >
3439<groupId >org.springframework.boot</groupId >
3540<artifactId >spring-boot-starter-web</artifactId >
8691 * </p>
8792 *
8893 * @author yangkai.shen
94+ * @author chen qi
8995 * @date Created in 2018-10-01 22:05
9096 */
9197@Aspect
9298@Component
9399@Slf4j
94100public class AopLog {
95- private static final String START_TIME = " request-start" ;
96-
97- /**
98- * 切入点
99- */
100- @Pointcut (" execution(public * com.xkcoding.log.aop.controller.*Controller.*(..))" )
101- public void log () {
102-
103- }
104-
105- /**
106- * 前置操作
107- *
108- * @param point 切入点
109- */
110- @Before (" log()" )
111- public void beforeLog (JoinPoint point ) {
112- ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder . getRequestAttributes();
113-
114- HttpServletRequest request = Objects . requireNonNull(attributes). getRequest();
115-
116- log. info(" 【请求 URL】:{}" , request. getRequestURL());
117- log. info(" 【请求 IP】:{}" , request. getRemoteAddr());
118- log. info(" 【请求类名】:{},【请求方法名】:{}" , point. getSignature(). getDeclaringTypeName(), point. getSignature(). getName());
119-
120- Map<String , String []> parameterMap = request. getParameterMap();
121- log. info(" 【请求参数】:{}," , JSONUtil . toJsonStr(parameterMap));
122- Long start = System . currentTimeMillis();
123- request. setAttribute(START_TIME , start);
124- }
125-
126- /**
127- * 环绕操作
128- *
129- * @param point 切入点
130- * @return 原方法返回值
131- * @throws Throwable 异常信息
132- */
133- @Around (" log()" )
134- public Object aroundLog (ProceedingJoinPoint point ) throws Throwable {
135- Object result = point. proceed();
136- log. info(" 【返回值】:{}" , JSONUtil . toJsonStr(result));
137- return result;
138- }
139-
140- /**
141- * 后置操作
142- */
143- @AfterReturning (" log()" )
144- public void afterReturning () {
145- ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder . getRequestAttributes();
146- HttpServletRequest request = Objects . requireNonNull(attributes). getRequest();
147-
148- Long start = (Long ) request. getAttribute(START_TIME );
149- Long end = System . currentTimeMillis();
150- log. info(" 【请求耗时】:{}毫秒" , end - start);
151-
152- String header = request. getHeader(" User-Agent" );
153- UserAgent userAgent = UserAgent . parseUserAgentString(header);
154- log. info(" 【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}" , userAgent. getBrowser(). toString(), userAgent. getOperatingSystem(). toString(), header);
155- }
101+ /**
102+ * 切入点
103+ */
104+ @Pointcut (" execution(public * com.xkcoding.log.aop.controller.*Controller.*(..))" )
105+ public void log () {
106+
107+ }
108+
109+ /**
110+ * 环绕操作
111+ *
112+ * @param point 切入点
113+ * @return 原方法返回值
114+ * @throws Throwable 异常信息
115+ */
116+ @Around (" log()" )
117+ public Object aroundLog (ProceedingJoinPoint point ) throws Throwable {
118+
119+ // 开始打印请求日志
120+ ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder . getRequestAttributes();
121+ HttpServletRequest request = Objects . requireNonNull(attributes). getRequest();
122+
123+ // 打印请求相关参数
124+ long startTime = System . currentTimeMillis();
125+ Object result = point. proceed();
126+ String header = request. getHeader(" User-Agent" );
127+ UserAgent userAgent = UserAgent . parseUserAgentString(header);
128+
129+ final Log l = Log . builder()
130+ .threadId(Long . toString(Thread . currentThread(). getId()))
131+ .threadName(Thread . currentThread(). getName())
132+ .ip(getIp(request))
133+ .url(request. getRequestURL(). toString())
134+ .classMethod(String . format(" %s.%s" , point. getSignature(). getDeclaringTypeName(),
135+ point. getSignature(). getName()))
136+ .httpMethod(request. getMethod())
137+ .requestParams(getNameAndValue(point))
138+ .result(result)
139+ .timeCost(System . currentTimeMillis() - startTime)
140+ .userAgent(header)
141+ .browser(userAgent. getBrowser(). toString())
142+ .os(userAgent. getOperatingSystem(). toString()). build();
143+
144+ log. info(" Request Log Info : {}" , JSONUtil . toJsonStr(l));
145+
146+ return result;
147+ }
148+
149+ /**
150+ * 获取方法参数名和参数值
151+ * @param joinPoint
152+ * @return
153+ */
154+ private Map<String , Object > getNameAndValue (ProceedingJoinPoint joinPoint ) {
155+
156+ final Signature signature = joinPoint. getSignature();
157+ MethodSignature methodSignature = (MethodSignature ) signature;
158+ final String [] names = methodSignature. getParameterNames();
159+ final Object [] args = joinPoint. getArgs();
160+
161+ if (ArrayUtil . isEmpty(names) || ArrayUtil . isEmpty(args)) {
162+ return Collections . emptyMap();
163+ }
164+ if (names. length != args. length) {
165+ log. warn(" {}方法参数名和参数值数量不一致" , methodSignature. getName());
166+ return Collections . emptyMap();
167+ }
168+ Map<String , Object > map = Maps . newHashMap();
169+ for (int i = 0 ; i < names. length; i++ ) {
170+ map. put(names[i], args[i]);
171+ }
172+ return map;
173+ }
174+
175+ private static final String UNKNOWN = " unknown" ;
176+
177+ /**
178+ * 获取ip地址
179+ */
180+ public static String getIp (HttpServletRequest request ) {
181+ String ip = request. getHeader(" x-forwarded-for" );
182+ if (ip == null || ip. length() == 0 || UNKNOWN . equalsIgnoreCase(ip)) {
183+ ip = request. getHeader(" Proxy-Client-IP" );
184+ }
185+ if (ip == null || ip. length() == 0 || UNKNOWN . equalsIgnoreCase(ip)) {
186+ ip = request. getHeader(" WL-Proxy-Client-IP" );
187+ }
188+ if (ip == null || ip. length() == 0 || UNKNOWN . equalsIgnoreCase(ip)) {
189+ ip = request. getRemoteAddr();
190+ }
191+ String comma = " ," ;
192+ String localhost = " 127.0.0.1" ;
193+ if (ip. contains(comma)) {
194+ ip = ip. split(" ," )[0 ];
195+ }
196+ if (localhost. equals(ip)) {
197+ // 获取本机真正的ip地址
198+ try {
199+ ip = InetAddress . getLocalHost(). getHostAddress();
200+ } catch (UnknownHostException e) {
201+ log. error(e. getMessage(), e);
202+ }
203+ }
204+ return ip;
205+ }
206+
207+ @Data
208+ @Builder
209+ @NoArgsConstructor
210+ @AllArgsConstructor
211+ static class Log {
212+ // 线程id
213+ private String threadId;
214+ // 线程名称
215+ private String threadName;
216+ // ip
217+ private String ip;
218+ // url
219+ private String url;
220+ // http方法 GET POST PUT DELETE PATCH
221+ private String httpMethod;
222+ // 类方法
223+ private String classMethod;
224+ // 请求参数
225+ private Object requestParams;
226+ // 返回参数
227+ private Object result;
228+ // 接口耗时
229+ private Long timeCost;
230+ // 操作系统
231+ private String os;
232+ // 浏览器
233+ private String browser;
234+ // user-agent
235+ private String userAgent;
236+ }
156237}
157238```
158239
@@ -165,22 +246,36 @@ public class AopLog {
165246 * </p>
166247 *
167248 * @author yangkai.shen
249+ * @author chen qi
168250 * @date Created in 2018-10-01 22:10
169251 */
252+ @Slf4j
170253@RestController
171254public class TestController {
172255
173- /**
174- * 测试方法
175- *
176- * @param who 测试参数
177- * @return {@link Dict}
178- */
179- @GetMapping (" /test" )
180- public Dict test (String who ) {
181- return Dict . create(). set(" who" , StrUtil . isBlank(who) ? " me" : who);
182- }
183-
256+ /**
257+ * 测试方法
258+ *
259+ * @param who 测试参数
260+ * @return {@link Dict}
261+ */
262+ @GetMapping (" /test" )
263+ public Dict test (String who ) {
264+ return Dict . create(). set(" who" , StrUtil . isBlank(who) ? " me" : who);
265+ }
266+
267+ /**
268+ * 测试post json方法
269+ * @param map 请求的json参数
270+ * @return {@link Dict}
271+ */
272+ @PostMapping (" /testJson" )
273+ public Dict testJson (@RequestBody Map<String , Object > map ) {
274+
275+ final String jsonStr = JSONUtil . toJsonStr(map);
276+ log. info(jsonStr);
277+ return Dict . create(). set(" json" , map);
278+ }
184279}
185280```
186281
0 commit comments