@Slf4j @Aspect @Component public class WebLogAspect { /** * 线程绑定变量,用于记录请求的开始时间 */ private static final ThreadLocal<Long> START_TIME_THREAD_LOCAL = new ThreadLocal<>(); /** * 配置织入点 */ @Pointcut("@annotation(com.jie.code.common.annotation.Log)") public void logPointCut() { } @Before("logPointCut()") public void recordStartTime(JoinPoint joinPoint) { START_TIME_THREAD_LOCAL.set(System.currentTimeMillis()); } /** * 处理完请求后执行 * * @param joinPoint 切点 */ @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) { long time = System.currentTimeMillis() - START_TIME_THREAD_LOCAL.get(); handleLog(joinPoint, null, jsonResult, time); START_TIME_THREAD_LOCAL.remove(); } /** * 拦截异常操作 * * @param joinPoint 切点 * @param e 异常 */ @AfterThrowing(value = "logPointCut()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Exception e) { long time = System.currentTimeMillis() - START_TIME_THREAD_LOCAL.get(); handleLog(joinPoint, e, null, time); START_TIME_THREAD_LOCAL.remove(); } protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, Long executionTime) { try { // 获得注解 Log log = getAnnotationLog(joinPoint); if (log == null) { return; } // 获取当前的用户 UserEntity loginUser = SecurityUtils.getSysUserIsNull(); // *========数据库日志=========*// SysLogEntity sysLog = new SysLogEntity(); sysLog.setStatus(StatusEnums.ENABLE.getKey()); HttpServletRequest request = ServletUtils.getRequest(); // 请求的IP地址 String ip = IpUtil.getIp(request); sysLog.setIp(ip); // 返回参数 sysLog.setJsonResult(JSONUtil.toJsonStr(jsonResult)); // 请求URL sysLog.setUrl(request.getRequestURI()); if (loginUser != null) { sysLog.setUsername(loginUser.getUsername()); } if (e != null) { sysLog.setStatus(StatusEnums.DISABLE.getKey()); sysLog.setErrorMsg(StrUtil.sub(e.getMessage(), 0, 2000)); } // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); sysLog.setMethod(className + "." + methodName + "()"); // 设置请求方式 sysLog.setRequestMethod(ServletUtils.getRequest().getMethod()); sysLog.setCreateTime(DateUtil.date()); // 获取浏览器和终端系统信息 String userAgentString = request.getHeader("User-Agent"); UserAgent userAgent = UserAgentUtil.parse(userAgentString); // 系统信息 sysLog.setOs(userAgent.getOs().getName()); // 浏览器信息 sysLog.setBrowser(userAgent.getBrowser().getName()); sysLog.setBrowserVersion(userAgent.getBrowser().getVersion(userAgentString)); // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, log, sysLog); // 执行时长 sysLog.setExecutionTime(executionTime); // 保存数据库 AsyncManager.me().execute(AsyncFactory.logTask(sysLog)); } catch (Exception exp) { // 记录本地异常日志 log.error("==前置通知异常=="); log.error("异常信息:{}", exp.getMessage()); } } /** * 获取注解中对方法的描述信息 用于Controller层注解 * * @param log 日志 * @param sysLog 操作日志 */ public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysLogEntity sysLog) throws Exception { // 设置标题 sysLog.setTitle(log.title()); // 是否需要保存request,参数和值 if (log.isSaveRequestData()) { // 获取参数的信息,传入到数据库中。 setRequestValue(joinPoint, sysLog); } } /** * 获取请求的参数,放到log中 * * @param sysLog 操作日志 * @throws Exception 异常 */ private void setRequestValue(JoinPoint joinPoint, SysLogEntity sysLog) throws Exception { String requestMethod = sysLog.getRequestMethod(); if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) { String params = argsArrayToString(joinPoint.getArgs()); sysLog.setParam(StrUtil.sub(params, 0, 2000)); } else { Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); sysLog.setParam(StrUtil.sub(paramsMap.toString(), 0, 2000)); } } /** * 是否存在注解,如果存在就获取 */ private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(Log.class); } return null; } /** * 参数拼装 */ private String argsArrayToString(Object[] paramsArray) { StringBuilder params = new StringBuilder(); if (paramsArray != null) { for (Object o : paramsArray) { if (!isFilterObject(o)) { Object jsonObj = JSONUtil.toJsonStr(o); params.append(jsonObj.toString()).append(" "); } } } return params.toString().trim(); } /** * 判断是否需要过滤的对象。 * * @param o 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ public boolean isFilterObject(final Object o) { return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; } }
在获取IP的时候使用工具类 IpUtil
@Slf4j public class IpUtil { /** * 用于IP定位转换 */ private static final String REGION = "内网IP|内网IP"; private static final String UNKNOWN = "unknown"; public static String getIp() { return getIp(ServletUtils.getRequest()); } public static String getIp(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } String comma = ","; String localhost = "127.0.0.1"; if (ip.contains(comma)) { ip = ip.split(",")[0]; } if (localhost.equals(ip)) { // 获取本机真正的ip地址 try { ip = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } log.info("getIpAddr:{} ", ip); return ip; } /** * 根据ip获取详细地址 */ public static String getAddress(String ip) { // 1、创建 searcher 对象 String dbPath = "ip2region/ip2region.xdb"; // 获取ip2region.db文件的位置 InputStream inputStream = IpUtil.class.getClassLoader() .getResourceAsStream(dbPath); Searcher searcher = null; try { if ("0:0:0:0:0:0:0:1".equals(ip)) { return REGION; } long sTime = System.nanoTime(); searcher = Searcher.newWithBuffer(IoUtil.readBytes(inputStream)); // 2、查询 String region = searcher.search(ip); long cost = TimeUnit.NANOSECONDS.toMicros(System.nanoTime() - sTime); log.info("region: {}, ioCount: {}, took: {} μs", region, searcher.getIOCount(), cost); return region; } catch (Exception e) { log.error("failed to create searcher with {}", dbPath, e); } finally { if (searcher != null) { try { searcher.close(); } catch (IOException ignored) { } } } return REGION; } /** * 获取浏览器类型 浏览器信息 * * @param request * @return */ public static String getBrowser(HttpServletRequest request) { // 获取浏览器和终端系统信息 String userAgentString = request.getHeader("User-Agent"); UserAgent userAgent = UserAgentUtil.parse(userAgentString); Browser browser = userAgent.getBrowser(); return browser.getName(); } /** * 操作系统 系统信息 */ public static String getOs(HttpServletRequest request) { // 获取浏览器和终端系统信息 String userAgentString = request.getHeader("User-Agent"); UserAgent userAgent = UserAgentUtil.parse(userAgentString); return userAgent.getOs().getName(); } }
注意记得下载 ip2region.xdb 文件
这个是使用的hutool工具 可以读取本地的IPV4 的IP 然后分析IP的实际地址
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); while (networkInterfaces.hasMoreElements()) { NetworkInterface networkInterface = networkInterfaces.nextElement(); if (networkInterface.getName().startsWith("wlan")) { Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses(); while (inetAddresses.hasMoreElements()) { InetAddress inetAddress = inetAddresses.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress.isSiteLocalAddress()) { String IP = inetAddress.getHostAddress(); if ("0:0:0:0:0:0:0:1".equals(IP)) { IP = "127.0.0.1"; operLog.setOperLocation("本地局域网"); } operLog.setOperIp(IP); String url = "https://opendata.baidu.com/api.php?query="+inetAddress.getHostAddress()+"&co=&resource_id=6006&oe=utf8"; String result1= HttpUtil.get(url); System.out.println(result1); // string转map Gson gson = new Gson(); Map<String, Object> map = new HashMap<>(); map = gson.fromJson(result1, map.getClass()); String[] data = map.get("data").toString().split(","); if (StringUtils.isNotEmpty(data[6])) { System.out.println(data[6]); System.out.println(extractChinese(data[6])); operLog.setOperLocation(extractChinese(data[6])); } } } } }