zoukankan      html  css  js  c++  java
  • java log记录(@Aspect)

    切面方法说明:

    1. @Aspect -- 作用是把当前类标识为一个切面供容器读取
    2. @Pointcut -- (切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
    3. @Before -- 标识一个前置增强方法,相当于BeforeAdvice的功能
    4. @AfterReturning -- 后置增强,相当于AfterReturningAdvice,方法退出时执行
    5. @AfterThrowing -- 异常抛出增强,相当于ThrowsAdvice
    6. @After -- final增强,不管是抛出异常或者正常退出都会执行
    7. @Around -- 环绕增强,相当于MethodInterceptor

    代码(参考‘若依‘)

    在pom.xml文件中配置

             <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    @Aspect
    @Component
    public class LogAspect
    {
        private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    
        // 配置织入点
        @Pointcut("@annotation(com.ruoyi.common.annotation.Log)")
        public void logPointCut()
        {
        }
    
        /**
         * 处理完请求后执行
         *
         * @param joinPoint 切点
         */
        @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
        public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
        {
            handleLog(joinPoint, null, jsonResult);
        }
    
        /**
         * 拦截异常操作
         * 
         * @param joinPoint 切点
         * @param e 异常
         */
        @AfterThrowing(value = "logPointCut()", throwing = "e")
        public void doAfterThrowing(JoinPoint joinPoint, Exception e)
        {
            handleLog(joinPoint, e, null);
        }
    
        protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
        {
            try
            {
                // 获得注解
                Log controllerLog = getAnnotationLog(joinPoint);
                if (controllerLog == null)
                {
                    return;
                }
    
                // 获取当前的用户
                SysUser currentUser = ShiroUtils.getSysUser();
    
                // *========数据库日志=========*//
                SysOperLog operLog = new SysOperLog();
                operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
                // 请求的地址
                String ip = ShiroUtils.getIp();
                operLog.setOperIp(ip);
                // 返回参数
                operLog.setJsonResult(JSON.marshal(jsonResult));
    
                operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
                if (currentUser != null)
                {
                    operLog.setOperName(currentUser.getLoginName());
                    if (StringUtils.isNotNull(currentUser.getDept())
                            && StringUtils.isNotEmpty(currentUser.getDept().getDeptName()))
                    {
                        operLog.setDeptName(currentUser.getDept().getDeptName());
                    }
                }
    
                if (e != null)
                {
                    operLog.setStatus(BusinessStatus.FAIL.ordinal());
                    operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
                }
                // 设置方法名称
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = joinPoint.getSignature().getName();
                operLog.setMethod(className + "." + methodName + "()");
                // 设置请求方式
                operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
                // 处理设置注解上的参数
                getControllerMethodDescription(controllerLog, operLog);
                // 保存数据库
                AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
            }
            catch (Exception exp)
            {
                // 记录本地异常日志
                log.error("==前置通知异常==");
                log.error("异常信息:{}", exp.getMessage());
                exp.printStackTrace();
            }
        }
    
        /**
         * 获取注解中对方法的描述信息 用于Controller层注解
         * 
         * @param log 日志
         * @param operLog 操作日志
         * @throws Exception
         */
        public void getControllerMethodDescription(Log log, SysOperLog operLog) throws Exception
        {
            // 设置action动作
            operLog.setBusinessType(log.businessType().ordinal());
            // 设置标题
            operLog.setTitle(log.title());
            // 设置操作人类别
            operLog.setOperatorType(log.operatorType().ordinal());
            // 是否需要保存request,参数和值
            if (log.isSaveRequestData())
            {
                // 获取参数的信息,传入到数据库中。
                setRequestValue(operLog);
            }
        }
    
        /**
         * 获取请求的参数,放到log中
         * 
         * @param operLog 操作日志
         * @throws Exception 异常
         */
        private void setRequestValue(SysOperLog operLog) throws Exception
        {
            Map<String, String[]> map = ServletUtils.getRequest().getParameterMap();
            String params = JSON.marshal(map);
            operLog.setOperParam(StringUtils.substring(params, 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;
        }
    }
    package com.ruoyi.framework.manager.factory;
    
    import java.util.TimerTask;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import com.ruoyi.common.constant.Constants;
    import com.ruoyi.common.utils.AddressUtils;
    import com.ruoyi.common.utils.ServletUtils;
    import com.ruoyi.common.utils.spring.SpringUtils;
    import com.ruoyi.framework.shiro.session.OnlineSession;
    import com.ruoyi.framework.util.LogUtils;
    import com.ruoyi.framework.util.ShiroUtils;
    import com.ruoyi.system.domain.SysLogininfor;
    import com.ruoyi.system.domain.SysOperLog;
    import com.ruoyi.system.domain.SysUserOnline;
    import com.ruoyi.system.service.ISysOperLogService;
    import com.ruoyi.system.service.ISysUserOnlineService;
    import com.ruoyi.system.service.impl.SysLogininforServiceImpl;
    import eu.bitwalker.useragentutils.UserAgent;
    
    /**
     * 异步工厂(产生任务用)
     * 
     * @author liuhulu
     *
     */
    public class AsyncFactory
    {
        private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
    
        /**
         * 同步session到数据库
         * 
         * @param session 在线用户会话
         * @return 任务task
         */
        public static TimerTask syncSessionToDb(final OnlineSession session)
        {
            return new TimerTask()
            {
                @Override
                public void run()
                {
                    SysUserOnline online = new SysUserOnline();
                    online.setSessionId(String.valueOf(session.getId()));
                    online.setDeptName(session.getDeptName());
                    online.setLoginName(session.getLoginName());
                    online.setStartTimestamp(session.getStartTimestamp());
                    online.setLastAccessTime(session.getLastAccessTime());
                    online.setExpireTime(session.getTimeout());
                    online.setIpaddr(session.getHost());
                    online.setLoginLocation(AddressUtils.getRealAddressByIP(session.getHost()));
                    online.setBrowser(session.getBrowser());
                    online.setOs(session.getOs());
                    online.setStatus(session.getStatus());
                    SpringUtils.getBean(ISysUserOnlineService.class).saveOnline(online);
    
                }
            };
        }
    
        /**
         * 操作日志记录
         * 
         * @param operLog 操作日志信息
         * @return 任务task
         */
        public static TimerTask recordOper(final SysOperLog operLog)
        {
            return new TimerTask()
            {
                @Override
                public void run()
                {
                    // 远程查询操作地点
                    operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                    SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
                }
            };
        }
    
        /**
         * 记录登陆信息
         * 
         * @param username 用户名
         * @param status 状态
         * @param message 消息
         * @param args 列表
         * @return 任务task
         */
        public static TimerTask recordLogininfor(final String username, final String status, final String message, final Object... args)
        {
            final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
            final String ip = ShiroUtils.getIp();
            return new TimerTask()
            {
                @Override
                public void run()
                {
                    String address = AddressUtils.getRealAddressByIP(ip);
                    StringBuilder s = new StringBuilder();
                    s.append(LogUtils.getBlock(ip));
                    s.append(address);
                    s.append(LogUtils.getBlock(username));
                    s.append(LogUtils.getBlock(status));
                    s.append(LogUtils.getBlock(message));
                    // 打印信息到日志
                    sys_user_logger.info(s.toString(), args);
                    // 获取客户端操作系统
                    String os = userAgent.getOperatingSystem().getName();
                    // 获取客户端浏览器
                    String browser = userAgent.getBrowser().getName();
                    // 封装对象
                    SysLogininfor logininfor = new SysLogininfor();
                    logininfor.setLoginName(username);
                    logininfor.setIpaddr(ip);
                    logininfor.setLoginLocation(address);
                    logininfor.setBrowser(browser);
                    logininfor.setOs(os);
                    logininfor.setMsg(message);
                    // 日志状态
                    if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
                    {
                        logininfor.setStatus(Constants.SUCCESS);
                    }
                    else if (Constants.LOGIN_FAIL.equals(status))
                    {
                        logininfor.setStatus(Constants.FAIL);
                    }
                    // 插入数据
                    SpringUtils.getBean(SysLogininforServiceImpl.class).insertLogininfor(logininfor);
                }
            };
        }
    }

    切入点(注解)

    package com.ruoyi.common.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import com.ruoyi.common.enums.BusinessType;
    import com.ruoyi.common.enums.OperatorType;
    
    /**
     * 自定义操作日志记录注解
     * 
     * @author ruoyi
     */
    @Target({ ElementType.PARAMETER, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Log
    {
        /**
         * 模块 
         */
        public String title() default "";
    
        /**
         * 功能
         */
        public BusinessType businessType() default BusinessType.OTHER;
    
        /**
         * 操作人类别
         */
        public OperatorType operatorType() default OperatorType.MANAGE;
    
        /**
         * 是否保存请求的参数
         */
        public boolean isSaveRequestData() default true;
    }

    调用方法,红色块

  • 相关阅读:
    StrCopy、StrCat、StrPas
    WinAPI: FlashWindow 闪烁窗口
    WinAPI: SetVolumeLabel 设置磁盘卷标
    WinAPI: GetActiveWindow 获取当前活动窗口的句柄
    WinAPI: SetCurrentDirectory、GetCurrentDirectory 设置与获取当前目录
    WinAPI: CreateDirectoryEx 根据模版建立文件夹
    WinAPI: CreateDirectory 建立文件夹
    WinAPI: RemoveDirectory 删除空目录
    WinAPI: GetLogicalDriveStrings 获取系统中存在的逻辑驱动器字符串
    filer.js: 一个 Unix 命令风格的 HTML 5 FileSystem API 封装 V2EX
  • 原文地址:https://www.cnblogs.com/shuaimeng/p/12092341.html
Copyright © 2011-2022 走看看