This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

background

Logging was briefly introduced in the previous article. In daily development, there are two types of logs commonly used by us. One is business logs, which are mainly used to record changes or attribute changes of some services in the system. For example, state changes or object attribute changes are recorded in the process of business flow. The other is the system log, which mainly records the method invocation information, such as the method name, parameters, and the name, IP, and invocation time of the caller. Combined with the actual situation in the project, this article introduces how to use Spring AOP principle to achieve system-level log management.

The core code

1. Declare the system log aspect class and submit it to the Spring container for management

The code is as follows:

@Aspect @Component public class SysLogAspect { @Autowired private SysLogService sysLogService; @Pointcut("execution(* com.xx.xx.*.service.*.*(..) )") public void logPointCut() { } @Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); Object result = point.proceed(); Long Time = system.currentTimemillis () -BeginTime; SaveSysLog (point, time); return result; } private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { String userName = BaseController.getUsername(); // The BaseController is the base class in the project, which mainly stores some basic information after the user login. This class can be used or not, depending on your actual situation. If (joinPoint. GetTarget () instanceof SysLogService) {//SysLogService, return the system log interface; } MethodSignature signature = (MethodSignature) joinPoint.getSignature(); SysLog sysLog = new SysLog(); String className = JoinPoint.gettarget ().getClass().getName(); String methodName = signature.getName(); sysLog.setMethod(className + "." + methodName + "()"); Object[] args = JoinPoint.getargs (); try{ String params = JSONObject.toJSONString(args[0]); sysLog.setParams(params); } the catch (Exception e) {} / / access request it request = HttpUtils. GetHttpServletRequest (); SetIp (iputils.getipaddr (request)); // Set the IP address syslog.setip (iputils.getipaddr (request)); Syslog.setusername (userName); Syslog.settime (time); // Execute duration (milliseconds) syslog.settime (time); Syslogservice. save(sysLog); }}Copy the code

2. Declare the IP tool class

The code is as follows:

public class IPUtils { private static Logger logger = LoggerFactory.getLogger(IPUtils.class); If you use reverse proxy software such as Nginx, you cannot obtain the IP address through request.getremoteaddr (). * If you use reverse proxy software, the value of x-forwarded-for is not one, but a list of IP addresses. This is the first valid IP string in x-Forwarded-for that is not unknown, */ public static String getIpAddr(HttpServletRequest Request) {String IP = null; try { ip = request.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } catch (Exception e) { logger.error("IPUtils ERROR ", e); } return ip; }}Copy the code

3. Declare HttpUtils utility class

The code is as follows:

public class HttpUtils { private static final Log log = LogFactory.getLog(HttpUtils.class); /** * getHttpServletRequest object * @return */ public static HttpServletRequest getHttpServletRequest() {return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); * @param response * @throws IOException */ public static void print(HttpServletResponse Response, int code, String msg) throws IOException { response.setContentType("application/json; charset=utf-8"); HttpResult result = HttpResult.error(code, msg); String json = JSONObject.toJSONString(result); response.getWriter().print(json); response.getWriter().flush(); response.getWriter().close(); } public static String sendpost(String serverUrl, String data) { StringBuilder responseBuilder = null; BufferedReader reader = null; OutputStreamWriter wr = null; String re=null; try { URL url = new URL(serverUrl); URLConnection e = url.openConnection(); e.setDoOutput(true); e.setConnectTimeout(5000); wr = new OutputStreamWriter(e.getOutputStream()); wr.write(data); wr.flush(); reader = new BufferedReader(new InputStreamReader(e.getInputStream())); responseBuilder = new StringBuilder(); String line = null; while((line = reader.readLine()) ! = null) { responseBuilder.append(line).append("\n"); } re=responseBuilder.toString(); Log.debug (" HTTP request returns result: "+re); } catch (IOException e1) { log.error("", e1); } finally { if(wr ! = null) { try { wr.close(); } catch (IOException e2) { log.error("close error", e2); } } if(reader ! = null) { try { reader.close(); } catch (IOException e3) { log.error("close error", e3); } } } return re; }}Copy the code

4. Test results

Note: Since the system is frequently used, each interface generates a piece of data when it is invoked. Therefore, the amount of data in the system log table is very large. You must periodically back up data and clear some old data; otherwise, more data in the table will affect the performance.