操作日志记录

Posted 无聊想被打

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作日志记录相关的知识,希望对你有一定的参考价值。

1.存在的意义

  所日志记录,就是记录所有的操作,使领导对这个系统的流转了如指掌,同时要是系统出现了问题,也可以清楚找到问题的所在。

2. 界面展示

 

3. 主要代码分析(提供三种方法)

  3.1 方法一 使用aop实现

 

源码介绍:

01.首先在保证你的环境无误的情况下(我用的是ssh)

02.BussAnnotation.java  (自定义注解)

package cn.bdqn.annotation;

/**
 * 自定义注解(用于记录日志)
 */
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface BussAnnotation {
    // 模块名
    String moduleName();
    // 操作内容 
    String option();
}
View Code

03.LogBeforeAdvice.java (前置增强)---主要记录的方法

package cn.bdqn.aop;
/**
 * aop前置增强结合自定义注解实现记录日志
 */
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.struts2.ServletActionContext;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.bdqn.annotation.BussAnnotation;
import cn.bdqn.base.BaseService;
import cn.bdqn.entity.PSUser;
import cn.bdqn.entity.PsLogs;
import cn.bdqn.service.IPsLogsService;

public class LogBeforeAdvice implements MethodBeforeAdvice{

     public void before(Method method, Object[] args, Object target)   
                throws Throwable {  
            // 拿到我们的service对象
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            IPsLogsService bean = (IPsLogsService)context.getBean("pslsi");
            //注解,拿到类型的元数据
            BussAnnotation ol = method.getAnnotation(BussAnnotation.class);
            if (ol!=null) {
                 System.out.println(ol.moduleName()+"\\t"+ol.option());
                 //判断是否
                 PSUser user=(PSUser)ServletActionContext.getRequest().getSession().getAttribute("loginuserinfo");
                 PsLogs logs=new PsLogs();
                 if(user==null){//在登录的时候记录登录信息
                     String userCode = ServletActionContext.getRequest().getParameter("userCode");//登录界面的值
                     System.out.println(userCode);
                     //赋值并保存
                     SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                     Date date = sdf.parse(sdf.format(new Date()));
                     logs.setOperateInfo(ol.option());
                     logs.setOperateDatetime(date);
                     logs.setUserCode(userCode);
                     ((BaseService<PsLogs>) bean).save(logs);
                 }else{//登录后,直接记录我们自定义注解中指定的信息
                     //赋值并保存
                     SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                     Date date = sdf.parse(sdf.format(new Date()));
                     logs.setOperateInfo(ol.option());
                     logs.setOperateDatetime(date);
                     logs.setUserCode(user.getUserCode());
                     ((BaseService<PsLogs>) bean).save(logs);
                     
                 }
            }
         
        }    

}
View Code

04.XXXAction.java (Action类中使用自定义注解实现记录)

        /*
     * 用于登录
     */
    @BussAnnotation(moduleName="用户登录",option="登录")
    public String login() {
        
          //关键代码

       return SUCCESS;
    }
View Code

05.applicationContext.xml (配置aop)

<!-- aop结合自定义注解实现日志记录 -->
    <bean name="logBefore" class="cn.bdqn.aop.LogBeforeAdvice"></bean>
    <aop:config proxy-target-class="true">
        <aop:pointcut expression="execution(* *..action.*.*(..))"
            id="pointcut" />
        <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut" />
    </aop:config>
View Code

  3.2 方法二  使用过滤器实现

源码介绍:

01.FunctionFilter.java (过滤器)---主要记录的方法

package cn.bdqn.filter;
/** 
 * 用于记录操作日志的过滤器类(方法二)
 */
import java.io.IOException;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 */
import cn.bdqn.entity.PSFunction;
import cn.bdqn.entity.PSRole;
import cn.bdqn.entity.PSUser;
import cn.bdqn.entity.PsLogs;
import cn.bdqn.service.IPsLogsService;


public class FunctionFilter implements Filter {
    public void destroy() {
        
    }
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("用于记录操作日志的过滤器类");
        HttpServletRequest req=(HttpServletRequest)request;
        String url=req.getRequestURI();
        System.out.println(url);
        //过滤掉所有静态资源,不做处理
        if (url.endsWith(".js")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".css")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".html")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".txt")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".gif")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".jpg") || url.endsWith(".jpeg")) {
            chain.doFilter(request, response);
        } 
        if (url.endsWith(".png")) {
            chain.doFilter(request, response);
        }
        int pos=url.indexOf("?");
        if (pos>-1) {
            url=url.substring(0,pos); 
        }
        int actionindex=url.indexOf(".action");
        if(actionindex>-1){
            url=url.substring(0,actionindex);
        }
        int of = url.indexOf("/", 2);
        url=url.substring(of+1);
        
        System.out.println("url地址:"+url);
        //判断是否登录
        PSUser user=(PSUser)req.getSession().getAttribute("loginuserinfo");
        if(url.endsWith("login")||url.equals("")){
                chain.doFilter(request, response);
        }else if(user!=null){
            for (PSRole role : user.getRole()) {
                for (PSFunction function : role.getPsFunctions()) {
                    if(function.getFuncUrl().equals(url)){
                        PsLogs log=new PsLogs();
                        log.setOperateDatetime(new Date());
                        log.setOperateInfo(function.getFunctionName());
                        log.setUserCode(user.getUserCode());
                        //获取spring的上下文容器
                        ApplicationContext contex=new ClassPathXmlApplicationContext("applicationContext.xml");
                        //获取spring容器中定义的IRoleService对象实例用于查询角色信息
                        IPsLogsService logsService = contex.getBean(IPsLogsService.class,"pslsi");
                        logsService.save(log);
                        chain.doFilter(request, response);
                    }
                }
        }
        }else{
            HttpServletResponse resp=(HttpServletResponse) response;
            resp.setCharacterEncoding("utf-8");
            resp.getWriter().write("<script type=\'text/javascript\'>alert(\'您没有该权限\')</script>");
        }
    }


    public void init(FilterConfig arg0) throws ServletException {
        
    }

}
View Code

02.web.xml

       <!-- 配置记录日志的过滤器(方法二) -->
     <filter>
        <filter-name>functionfilter</filter-name>
        <filter-class>cn.filter.FunctionFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>functionfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping> 
View Code  

  3.3 方法三  使用拦截器实现

源码介绍:

01.BussAnnotation.java  (自定义注解)

package cn.bdqn.annotation;

/**
 * 自定义注解(用于记录日志)
 */
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface BussAnnotation {
    // 模块名
    String moduleName();
    // 操作内容 
    String option();
}
View Code

02.OperateLogIntercepter.java (自定义拦截器)---主要记录的方法

package cn.bdqn.interceptor;
/**
 * 记录日志的拦截器(方法三)
 */

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.bdqn.annotation.BussAnnotation;
import cn.bdqn.base.BaseService;
import cn.bdqn.entity.PSUser;
import cn.bdqn.entity.PsLogs;
import cn.bdqn.service.IPsLogsService;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class OperateLogIntercepter extends AbstractInterceptor{

    private static final long serialVersionUID = 1L;
    
    private static final Log log=LogFactory.getLog(OperateLogIntercepter.class);
    
    
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        /*Object bean = SpringContextHelper.getBean("psLogsService");*/
        
        System.out.println("日志拦截器已经开始启动");
        //获得service实例
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        IPsLogsService bean = (IPsLogsService)context.getBean("pslsi");
        
        Class<? extends Object> actionClass=invocation.getAction().getClass();
        String methodName=invocation.getProxy().getMethod();
        //获取当前方法
        Method currentMethod=actionClass.getMethod(methodName);
        boolean flag = currentMethod.isAnnotationPresent(BussAnnotation.class);
        if(flag){
            BussAnnotation ol=currentMethod.getAnnotation(BussAnnotation.class);
            PsLogs logs=new PsLogs();
            PSUser user=(PSUser)ServletActionContext.getRequest().getSession().getAttribute("loginuserinfo");
            if(user==null){//在登录的时候记录登录信息
                String userCode = ServletActionContext.getRequest().getParameter("userCode");
                System.out.println(userCode);
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = sdf.parse(sdf.format(new Date()));
                logs.setOperateInfo(ol.option());
                logs.setOperateDatetime(date);
                logs.setUserCode(userCode);
                ((BaseService<PsLogs>) bean).save(logs);
            }else{//登录后,直接记录我们自定义注解中指定的信息
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = sdf.parse(sdf.format(new Date()));
                logs.setOperateInfo(ol.option());
                logs.setOperateDatetime(date);
                logs.setUserCode(user.getUserCode());
                ((BaseService<PsLogs>) bean).save(logs);
                
            }
            
        }
        return invocation.invoke();
    }

    public static Log getLog() {
        return log;
    }
}
View Code

03.XXXAction.java (Action类中使用自定义注解实现记录)

        /*
     * 用于登录
     */
    @BussAnnotation(moduleName="用户登录",option="登录")
    public String login() throws Exception {

            //主要代码
    
          return SUCCESS;

    }
View Code

04.struts.xml (使用拦截器)

               <!-- 拦截器 -->
        <interceptors>
            <!-- 声明记录日志拦截器 -->
            <interceptor name="logs" class="cn.interceptor.OperateLogIntercepter"></interceptor>
            <!-- 配置一个拦截器栈 -->
            <interceptor-stack name="myStack">
                <!-- <interceptor-ref name="logs"></interceptor-ref> -->
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!--默认使用这个拦截器栈 -->
        <default-interceptor-ref name="myStack"></default-interceptor-ref>
View Code

 

以上是关于操作日志记录的主要内容,如果未能解决你的问题,请参考以下文章

AOP实现日志记录功能

AOP实现日志记录功能

argparse 代码片段只打印部分日志

提效小技巧——记录那些不常用的代码片段

ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段

varnishlogVarnishstat详解