11package com .xkcoding .log .aop .aspectj ;
22
3+ import cn .hutool .core .util .ArrayUtil ;
34import cn .hutool .json .JSONUtil ;
5+ import com .google .common .collect .Maps ;
46import eu .bitwalker .useragentutils .UserAgent ;
7+ import lombok .AllArgsConstructor ;
8+ import lombok .Builder ;
9+ import lombok .Data ;
10+ import lombok .NoArgsConstructor ;
511import lombok .extern .slf4j .Slf4j ;
6- import org .aspectj .lang .JoinPoint ;
712import org .aspectj .lang .ProceedingJoinPoint ;
8- import org .aspectj .lang .annotation .*;
13+ import org .aspectj .lang .Signature ;
14+ import org .aspectj .lang .annotation .Around ;
15+ import org .aspectj .lang .annotation .Aspect ;
16+ import org .aspectj .lang .annotation .Pointcut ;
17+ import org .aspectj .lang .reflect .MethodSignature ;
918import org .springframework .stereotype .Component ;
1019import org .springframework .web .context .request .RequestContextHolder ;
1120import org .springframework .web .context .request .ServletRequestAttributes ;
1221
1322import javax .servlet .http .HttpServletRequest ;
23+ import java .net .InetAddress ;
24+ import java .net .UnknownHostException ;
25+ import java .util .Collections ;
1426import java .util .Map ;
1527import java .util .Objects ;
1628
2032 * </p>
2133 *
2234 * @author yangkai.shen
35+ * @author chen qi
2336 * @date Created in 2018-10-01 22:05
2437 */
2538@ Aspect
2639@ Component
2740@ Slf4j
2841public class AopLog {
29- private static final String START_TIME = "request-start" ;
30-
3142 /**
3243 * 切入点
3344 */
@@ -36,27 +47,6 @@ public void log() {
3647
3748 }
3849
39- /**
40- * 前置操作
41- *
42- * @param point 切入点
43- */
44- @ Before ("log()" )
45- public void beforeLog (JoinPoint point ) {
46- ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder .getRequestAttributes ();
47-
48- HttpServletRequest request = Objects .requireNonNull (attributes ).getRequest ();
49-
50- log .info ("【请求 URL】:{}" , request .getRequestURL ());
51- log .info ("【请求 IP】:{}" , request .getRemoteAddr ());
52- log .info ("【请求类名】:{},【请求方法名】:{}" , point .getSignature ().getDeclaringTypeName (), point .getSignature ().getName ());
53-
54- Map <String , String []> parameterMap = request .getParameterMap ();
55- log .info ("【请求参数】:{}," , JSONUtil .toJsonStr (parameterMap ));
56- Long start = System .currentTimeMillis ();
57- request .setAttribute (START_TIME , start );
58- }
59-
6050 /**
6151 * 环绕操作
6252 *
@@ -66,25 +56,123 @@ public void beforeLog(JoinPoint point) {
6656 */
6757 @ Around ("log()" )
6858 public Object aroundLog (ProceedingJoinPoint point ) throws Throwable {
59+
60+ // 开始打印请求日志
61+ ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder .getRequestAttributes ();
62+ HttpServletRequest request = Objects .requireNonNull (attributes ).getRequest ();
63+
64+ // 打印请求相关参数
65+ long startTime = System .currentTimeMillis ();
6966 Object result = point .proceed ();
70- log .info ("【返回值】:{}" , JSONUtil .toJsonStr (result ));
67+ String header = request .getHeader ("User-Agent" );
68+ UserAgent userAgent = UserAgent .parseUserAgentString (header );
69+
70+ final Log l = Log .builder ()
71+ .threadId (Long .toString (Thread .currentThread ().getId ()))
72+ .threadName (Thread .currentThread ().getName ())
73+ .ip (getIp (request ))
74+ .url (request .getRequestURL ().toString ())
75+ .classMethod (String .format ("%s.%s" , point .getSignature ().getDeclaringTypeName (),
76+ point .getSignature ().getName ()))
77+ .httpMethod (request .getMethod ())
78+ .requestParams (getNameAndValue (point ))
79+ .result (result )
80+ .timeCost (System .currentTimeMillis () - startTime )
81+ .userAgent (header )
82+ .browser (userAgent .getBrowser ().toString ())
83+ .os (userAgent .getOperatingSystem ().toString ()).build ();
84+
85+ log .info ("Request Log Info : {}" , JSONUtil .toJsonStr (l ));
86+
7187 return result ;
7288 }
7389
7490 /**
75- * 后置操作
91+ * 获取方法参数名和参数值
92+ * @param joinPoint
93+ * @return
7694 */
77- @ AfterReturning ("log()" )
78- public void afterReturning () {
79- ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder .getRequestAttributes ();
80- HttpServletRequest request = Objects .requireNonNull (attributes ).getRequest ();
95+ private Map <String , Object > getNameAndValue (ProceedingJoinPoint joinPoint ) {
8196
82- Long start = (Long ) request .getAttribute (START_TIME );
83- Long end = System .currentTimeMillis ();
84- log .info ("【请求耗时】:{}毫秒" , end - start );
97+ final Signature signature = joinPoint .getSignature ();
98+ MethodSignature methodSignature = (MethodSignature ) signature ;
99+ final String [] names = methodSignature .getParameterNames ();
100+ final Object [] args = joinPoint .getArgs ();
85101
86- String header = request .getHeader ("User-Agent" );
87- UserAgent userAgent = UserAgent .parseUserAgentString (header );
88- log .info ("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}" , userAgent .getBrowser ().toString (), userAgent .getOperatingSystem ().toString (), header );
102+ if (ArrayUtil .isEmpty (names ) || ArrayUtil .isEmpty (args )) {
103+ return Collections .emptyMap ();
104+ }
105+ if (names .length != args .length ) {
106+ log .warn ("{}方法参数名和参数值数量不一致" , methodSignature .getName ());
107+ return Collections .emptyMap ();
108+ }
109+ Map <String , Object > map = Maps .newHashMap ();
110+ for (int i = 0 ; i < names .length ; i ++) {
111+ map .put (names [i ], args [i ]);
112+ }
113+ return map ;
114+ }
115+
116+ private static final String UNKNOWN = "unknown" ;
117+
118+ /**
119+ * 获取ip地址
120+ */
121+ public static String getIp (HttpServletRequest request ) {
122+ String ip = request .getHeader ("x-forwarded-for" );
123+ if (ip == null || ip .length () == 0 || UNKNOWN .equalsIgnoreCase (ip )) {
124+ ip = request .getHeader ("Proxy-Client-IP" );
125+ }
126+ if (ip == null || ip .length () == 0 || UNKNOWN .equalsIgnoreCase (ip )) {
127+ ip = request .getHeader ("WL-Proxy-Client-IP" );
128+ }
129+ if (ip == null || ip .length () == 0 || UNKNOWN .equalsIgnoreCase (ip )) {
130+ ip = request .getRemoteAddr ();
131+ }
132+ String comma = "," ;
133+ String localhost = "127.0.0.1" ;
134+ if (ip .contains (comma )) {
135+ ip = ip .split ("," )[0 ];
136+ }
137+ if (localhost .equals (ip )) {
138+ // 获取本机真正的ip地址
139+ try {
140+ ip = InetAddress .getLocalHost ().getHostAddress ();
141+ } catch (UnknownHostException e ) {
142+ log .error (e .getMessage (), e );
143+ }
144+ }
145+ return ip ;
146+ }
147+
148+ @ Data
149+ @ Builder
150+ @ NoArgsConstructor
151+ @ AllArgsConstructor
152+ static class Log {
153+ // 线程id
154+ private String threadId ;
155+ // 线程名称
156+ private String threadName ;
157+ // ip
158+ private String ip ;
159+ // url
160+ private String url ;
161+ // http方法 GET POST PUT DELETE PATCH
162+ private String httpMethod ;
163+ // 类方法
164+ private String classMethod ;
165+ // 请求参数
166+ private Object requestParams ;
167+ // 返回参数
168+ private Object result ;
169+ // 接口耗时
170+ private Long timeCost ;
171+ // 操作系统
172+ private String os ;
173+ // 浏览器
174+ private String browser ;
175+ // user-agent
176+ private String userAgent ;
89177 }
90178}
0 commit comments