ログ収集用のmysqlサブテーブルスプリングインターセプター

要件:システムのすべての操作をログに記録する必要があります

サブテーブルのルールは参照用です。

これはビジネスベースのモデルを採用しています。ユーザーにページクエリをスキップできないように強制します。つまり、ユーザーは次のページまたは前のページをクリックして閲覧することしかできません。具体的な方法は、レコード数をクエリすることです。現在の一意のID値の最大値を記録し、再度クエリを実行するときにwhere条件を追加します...最初から始めましょう:最初のクエリpageNum = 1、pageSize = 10、maxId = 0-> sql:select * from db_x where id> 0 limit 10;次に、対応するライブラリのテーブルに配布し、取得した4 * 10個のデータをマージしてから、それらを解析してメモリ内で並べ替え、最初の10個のデータを取得して、 10番目のデータのid = maxIdを個別に、フロントエンドにレンダリングします。ページに保存します。次のページをクリックすると、maxId = 10も送信され、SQLはselect * from db_x where id>になります。 10制限10、次に解析を続行し、保存を続行します...この方法で返されたデータすべてが安定しており、データは一貫しています(ソート済み)

mysqlテーブル

CREATE TABLE `tb_logging` (
  `id` int(64) NOT NULL COMMENT 'id',
  `class_name` varchar(64) DEFAULT NULL COMMENT '类名',
  `method_name` varchar(64) DEFAULT NULL COMMENT '方法名',
  `param` varchar(3000) DEFAULT NULL COMMENT '参数',
  `url` varchar(512) DEFAULT NULL COMMENT '访问的url',
  `ip` varchar(64) DEFAULT NULL COMMENT '操作人ip',
  `create_user_id` varchar(64) DEFAULT NULL COMMENT '创建人id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `state_time` datetime DEFAULT NULL COMMENT '执行开始时间',
  `end_time` datetime DEFAULT NULL COMMENT '执行结束时间',
  `long_time` varchar(64) DEFAULT NULL COMMENT '耗时',
  `method` varchar(32) DEFAULT NULL COMMENT '请求方式GET、POST...',
  `module_name` varchar(512) DEFAULT NULL COMMENT '操作模块描述',
  `return_value` varchar(521) DEFAULT NULL COMMENT '返回值',
  `browser` varchar(128) DEFAULT NULL COMMENT '当前操作的浏览器',
  `is_delete` tinyint(1) DEFAULT '0' COMMENT '是否删除 0、未删除 1、删除',
  `state` varchar(32) DEFAULT NULL COMMENT '返回状态码',
  PRIMARY KEY (`id`),
  KEY `log_Joint_idx` (`is_delete`,`class_name`,`method_name`,`create_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='日志记录 用于新增修改删除等操作记录';

CREATE TABLE `tb_logging_select` (
  `id` int(64) NOT NULL COMMENT 'id',
  `class_name` varchar(64) DEFAULT NULL COMMENT '类名',
  `method_name` varchar(64) DEFAULT NULL COMMENT '方法名',
  `param` varchar(3000) DEFAULT NULL COMMENT '参数',
  `url` varchar(512) DEFAULT NULL COMMENT '访问的url',
  `ip` varchar(64) DEFAULT NULL COMMENT '操作人ip',
  `create_user_id` varchar(64) DEFAULT NULL COMMENT '创建人id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `state_time` datetime DEFAULT NULL COMMENT '执行开始时间',
  `end_time` datetime DEFAULT NULL COMMENT '执行结束时间',
  `long_time` varchar(64) DEFAULT NULL COMMENT '耗时',
  `method` varchar(32) DEFAULT NULL COMMENT '请求方式GET、POST...',
  `module_name` varchar(512) DEFAULT NULL COMMENT '操作模块描述',
  `return_value` varchar(521) DEFAULT NULL COMMENT '返回值',
  `browser` varchar(128) DEFAULT NULL COMMENT '当前操作的浏览器',
  `is_delete` tinyint(1) DEFAULT '0' COMMENT '是否删除 0、未删除 1、删除',
  `state` varchar(32) DEFAULT NULL COMMENT '返回状态码',
  PRIMARY KEY (`id`),
  KEY `log_Joint_idx` (`is_delete`,`class_name`,`method_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='日志记录用于查询操作记录';

エンティティクラス:



import lombok.Data;

import java.util.Date;


/**
 * 项目名称:
 * 类 名 称:TbLogging
 * 类 描 述:TODO
 * 创建时间:2020/6/11 19:30
 * 创 建 人:heng
 */
@Data
public class TbLogging {
    //id
    private java.lang.Integer id;//id
    //类名
    private java.lang.String class_name;//类名
    //方法名
    private java.lang.String method_name;//方法名
    //参数
    private java.lang.String param;//参数
    //访问的url
    private java.lang.String url;//访问的url
    //操作人ip
    private java.lang.String ip;//操作人ip
    //创建人id
    private java.lang.String create_user_id;//创建人id
    //创建时间
    private Date create_time;//创建时间
    //执行开始时间
    private Date state_time;//执行开始时间
    //执行结束时间
    private Date end_time;//执行结束时间
    //耗时
    private java.lang.String long_time;//耗时
    //请求方式GET、POST...
    private java.lang.String method;//请求方式GET、POST...
    //操作模块描述
    private java.lang.String module_name;//操作模块描述 //操作模块描述
    //返回值
    private java.lang.String return_value;//返回值
    //当前操作的浏览器
    private java.lang.String browser;//当前操作的浏览器
    //是否删除 0、未删除 1、删除
    private java.lang.Integer is_delete;//是否删除 0、未删除 1、删除
    private java.lang.String state;//操作模块描述

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public Date getState_time() {
        return state_time;
    }

    public void setState_time(Date state_time) {
        this.state_time = state_time;
    }

    public Date getEnd_time() {
        return end_time;
    }

    public void setEnd_time(Date end_time) {
        this.end_time = end_time;
    }
}


import lombok.Data;

import java.util.Date;

/**
 * 项目名称:
 * 类 名 称:TbLoggingSelect 
 * 类 描 述:TODO
 * 创建时间:2020/6/11 19:30
 * 创 建 人:heng
 */
@Data
public class TbLoggingSelect {
    //id
    private Integer id;//id
    //类名
    private String class_name;//类名
    //方法名
    private String method_name;//方法名
    //参数
    private String param;//参数
    //访问的url
    private String url;//访问的url
    //操作人ip
    private String ip;//操作人ip
    //创建人id
    private String create_user_id;//创建人id
    //创建时间
    private Date create_time;//创建时间
    //执行开始时间
    private Date state_time;//执行开始时间
    //执行结束时间
    private Date end_time;//执行结束时间
    //耗时
    private String long_time;//耗时
    //请求方式GET、POST...
    private String method;//请求方式GET、POST...
    //操作模块描述
    private String module_name;//操作模块描述 //操作模块描述
    //返回值
    private String return_value;//返回值
    //当前操作的浏览器
    private String browser;//当前操作的浏览器
    //是否删除 0、未删除 1、删除
    private Integer is_delete;//是否删除 0、未删除 1、删除
    private String state;//操作模块描述

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public Date getState_time() {
        return state_time;
    }

    public void setState_time(Date state_time) {
        this.state_time = state_time;
    }

    public Date getEnd_time() {
        return end_time;
    }

    public void setEnd_time(Date end_time) {
        this.end_time = end_time;
    }
}

ログを収集するインターセプター

idはredisによって生成され、他のものを使用できます

新しい文はここに投稿されません

次の操作クエリのテーブルを配置します

他の人はテーブルを置きます

package com.web.common.intercept;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.web.common.controller.BaseController;
import com.web.entity.TbLogging;
import com.web.entity.TbLoggingSelect;
import nl.bitwalker.useragentutils.UserAgent;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import redis.clients.jedis.Jedis;
import web.dao.hsdao.TbLoggingMapper;
import web.dao.hsdao.TbLoggingSelectMapper;
import web.util.JedisUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * @ClassName SginAop
 * @Description
 * @Author heng
 * @Date 2020/4/26 10:41
 * @Version 1.0
 */

public class LogInterceptor extends HandlerInterceptorAdapter {
  

    private final String redisKey = "LOG:LOGGING_KEY";
    private final static Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);
    //请求开始时间标识
    private static final String LOGGER_SEND_TIME = "_send_time";
    //请求日志实体标识
    private static final String LOGGER_ENTITY = "_logger_entity";

    @Autowired
    private TbLoggingSelectMapper tbLoggingSelectMapper;

    @Autowired
    private TbLoggingMapper tbLoggingMapper;
  public Long incr(String key) {
        Jedis jedis =JedisUtil.getJedis();
        try {
            return jedis.incr(key);
        } finally {
            if (null != jedis) {
                jedis.close();
            }
        }
    }
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
            try {

                TbLogging tbLogging = new TbLogging();
                Long start_long_time = System.currentTimeMillis();
                tbLogging.setState_time(DateUtil.date(start_long_time));
                //获取ip
                tbLogging.setIp(getRemoteHost(request));

                //获取控制器的名字
                tbLogging.setClass_name(((HandlerMethod) handler).getBean().getClass().getName());
                //获取方法名
                tbLogging.setMethod_name(((HandlerMethod) handler).getMethod().getName());
                //获取请求参数信息
                String param = JSON.toJSONString(request.getParameterMap(),
                        SerializerFeature.DisableCircularReferenceDetect,
                        SerializerFeature.WriteMapNullValue);
                tbLogging.setParam(param);
                try {
                    tbLogging.setCreate_user_id(new BaseController().obtainLoginUserId(request));
                }catch (Exception ex){
                    LOGGER.info("拿到当前登录人失败");
                }
                //请求方法
                tbLogging.setMethod(request.getMethod());
                //请求url到后端的url
                tbLogging.setUrl(request.getRequestURI());
                //浏览器
                //获取浏览器信息
                String ua = request.getHeader("User-Agent");
               //转成UserAgent对象
                UserAgent userAgent = UserAgent.parseUserAgentString(ua);
                tbLogging.setBrowser(userAgent.toString());
                //获取返回值
                //tbLogging.setReturn_value(response.getWriter().toString());
                //设置请求开始时间
                request.setAttribute(LOGGER_SEND_TIME, start_long_time);

                //设置请求实体到request内,方便afterCompletion方法调用
                request.setAttribute(LOGGER_ENTITY, tbLogging);

            } catch (Exception e) {
                LOGGER.info("日志添加失败");
            }

        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        try {

        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();

        if (StringUtils.length(contextPath) > 0) {
            contextPath = StringUtils.substring(uri, contextPath.length());
        }
        TbLogging tbLogging = (TbLogging) request.getAttribute(LOGGER_ENTITY);

        //获取请求错误码
        int status = response.getStatus();

        //当前时间
        long currentTime = System.currentTimeMillis();

        //请求开始时间
        long time = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString());

        //获取本次请求日志实体

        tbLogging.setState(status+"");

        //设置请求时间差
        tbLogging.setLong_time((currentTime - time)+"");
        tbLogging.setEnd_time(DateUtil.date(currentTime));
        tbLogging.setCreate_time(DateUtil.date(currentTime));
           // Long longId =  IdUtil.createSnowflake(1, 1).nextId();
            Long longId = incr(redisKey);
            tbLogging.setId(longId.intValue());
            if(tbLogging.getClass_name().indexOf("TbLoggingController") == -1){
        if (contextPath.indexOf("search_") == -1
                && !tbLogging.getMethod_name().startsWith("search")
                && !tbLogging.getMethod_name().startsWith("get")
                && !tbLogging.getMethod_name().startsWith("query")
                && !tbLogging.getMethod_name().startsWith("find")
                && !tbLogging.getMethod_name().startsWith("select")
                &&  !tbLogging.getMethod_name().equals("index")) {
        //执行将日志写入数据库,可以根据实际需求进行保存
        // sysLogRepo.save(sysLog);
            tbLoggingMapper.insertTbLogging(tbLogging);
        }else {
            TbLoggingSelect select = new TbLoggingSelect();
            //把tbLogging的值给select

            BeanUtils.copyProperties(select,tbLogging);
            tbLoggingSelectMapper.insertTbLoggingSelect(select);
         }
     }
        }catch (Exception e){
            LOGGER.info("日志添加失败");
        }
    }

    public int difference(Date nowDate, String decrypted){
        return Math.abs((int)(nowDate.getTime()-Long.valueOf(decrypted))/1000);
    }


    /**
     * @Title: getRemoteHost
     * @Description: 获取Ip地址
     * @return: String
     * @version V1.0
     */
    public String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }
}

 次の操作を使用してクエリを実行します

mapper.xml

  /**
     * 用于分表分页查询
     * @param map
     * @return
     */
    List<TbLogging> pageListTbLoggingSelectByObj(Map<String,Object> map);
    int pageListTbLoggingSelectByObjCount(Map<String,Object> map);





 <select id="pageListTbLoggingSelectByObj" parameterType="map" resultMap="BaseResultMap2">
        SELECT <include refid="Base_Column_List" />
        FROM tb_logging_select
        <where>
            is_delete = 0
            <if test ='null != create_time and create_time != ""'>
                AND  date_format(create_time,'%Y-%m-%d') =  #{create_time}
            </if>
            <if test ='null != maxId and maxId != "" '>
                AND  id  &gt; #{maxId}
            </if>
            <if test ='null != minId and minId != ""'>
                AND  id  &lt; #{minId}
            </if>
        </where>
        <if test ='null != maxId and maxId != "" '>
             order by id asc
        </if>
        <if test ='null != minId and minId != ""'>
              order by id desc
        </if>
        <if test ='(minId == null or minId == "") and (maxId == "" or maxId ==null) '>
            order by id desc
        </if>
        LIMIT #{pageSize}
    </select>
    <select id="pageListTbLoggingSelectByObjCount" parameterType="map" resultType="int">
        SELECT count(1)
        FROM tb_logging_select
        <where>
            is_delete = 0
            <if test ='null != create_time and create_time != ""'>
                AND  date_format(create_time,'%Y-%m-%d') =  #{create_time}
            </if>
        </where>
    </select>
   /**
     * 用于分表分页查询
     * @param map
     * @return
     */
    List<TbLogging> pageListTbLoggingByObj(Map<String,Object> map);
    int pageListTbLoggingByObjCount(Map<String,Object> map);




    <select id="pageListTbLoggingByObj" parameterType="map" resultMap="BaseResultMap2">
        SELECT <include refid="Base_Column_List" />
        FROM tb_logging
        <where>
            is_delete = 0
            <if test ='null != create_time and create_time != "" '>
                AND  date_format(create_time,'%Y-%m-%d') =  #{create_time}
            </if>
            <if test ='null != maxId and maxId != "" '>
                AND  id  &gt; #{maxId}
            </if>
            <if test ='null != minId and minId != ""'>
                AND  id  &lt; #{minId}
            </if>
        </where>
        <if test ='null != maxId and maxId != "" '>
            order by id asc
        </if>
        <if test ='null != minId and minId != ""'>
            order by id desc
        </if>
        <if test ='minId == "" and maxId == ""'>
            order by id desc
        </if>
        LIMIT #{pageSize}
    </select>
    <select id="pageListTbLoggingByObjCount" parameterType="map" resultType="int">
        SELECT count(1)
        FROM tb_logging
        <where>
            is_delete = 0
            <if test ='null != create_time and create_time != "" '>
                AND  date_format(create_time,'%Y-%m-%d') =  #{create_time}
            </if>
        </where>
    </select>

 

 

サービス

package web.service.logging;

import com.web.common.util.PropertyValueChangeUtil;
import com.web.common.util.web.BeanRefUtil;
import com.web.entity.TbLogging;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import web.dao.hsdao.TbLoggingMapper;
import web.dao.hsdao.TbLoggingSelectMapper;
import web.util.ResultUtils;

import java.util.*;

/**
 * 项目名称:
 * 类 名 称:TbLoggingService
 * 类 描 述:TODO
 * 创建时间:2020/6/12 17:25
 * 创 建 人:heng
 */
@Service
public class TbLoggingService {
    @Autowired
    private TbLoggingMapper tbLoggingMapper;
    @Autowired
    private TbLoggingSelectMapper tbLoggingSelectMapper;

    public ResultUtils findLoging(Map<String,Object> map){
      Integer pageSize =  Integer.valueOf( map.get("pageSize").toString());
      List<TbLogging> tbLoggings = tbLoggingMapper.pageListTbLoggingByObj(map);
      List<TbLogging> tbLoggingSelects = tbLoggingSelectMapper.pageListTbLoggingSelectByObj(map);
     int count1 = tbLoggingMapper.pageListTbLoggingByObjCount(map);
     int count2 = tbLoggingSelectMapper.pageListTbLoggingSelectByObjCount(map);
      tbLoggings.addAll(tbLoggingSelects);
        List<TbLogging> list = new ArrayList<>();
      if (map.get("maxId") != null){
          Collections.sort(tbLoggings, new Comparator<TbLogging>() {
              @Override
              public int compare(TbLogging o1, TbLogging o2) {
                  if (o1.getId()> o2.getId()){
                      return  1;
                  }
                  if(o1.getId()< o2.getId()){

                      return  -1;
                  }
                  return 0;
              }
          });
          if (tbLoggings.size() >= pageSize){
              list = tbLoggings.subList(0,pageSize);
          }else {
              list = tbLoggings;
          }
          Collections.sort(list, new Comparator<TbLogging>() {
              @Override
              public int compare(TbLogging o1, TbLogging o2) {
                  if (o1.getId()< o2.getId()){
                      return  1;
                  }
                  if(o1.getId()> o2.getId()){

                      return  -1;
                  }
                  return 0;
              }
          });
      }else{
          Collections.sort(tbLoggings, new Comparator<TbLogging>() {
              @Override
              public int compare(TbLogging o1, TbLogging o2) {
                  if (o1.getId()< o2.getId()){
                      return  1;
                  }
                  if(o1.getId()> o2.getId()){

                      return  -1;
                  }
                  return 0;
              }
          });
          if (tbLoggings.size() >= pageSize){
              list = tbLoggings.subList(0,pageSize);
          }else {
              list = tbLoggings;
          }

      }


        List<Map> mapRows = new ArrayList<Map>();
        for (TbLogging d : list) {
            BeanRefUtil beanRefUtil = new BeanRefUtil();
            Map map1 = beanRefUtil.transBean2Map(d);
            // 2.自定义按钮设置在此处
            map1.put("maxId",list.get(0).getId());
            map1.put("minId",list.get(list.size()-1).getId());
            //下面的方法是将对象中的枚举值改为枚举描述。如stat为0时表示无效。则将map中的stat的值从0改为0-无效,方便前端显示,但是该方法需要完善Dto的PropertyEnum方法
            PropertyValueChangeUtil.dateValue2Desc(map1 );
            mapRows.add(map1);
        }
        return new ResultUtils(mapRows,count1+count2);
    }
}

ここでのコントローラーのmaxIdとminIdはフロントエンドに格納されます。最初のクエリは空であり、すべてがクエリされます。

次に、マージとページング用にそれぞれ10個のアイテムを並べ替えます。最初のクエリの後、マージされた最大IDと最小IDがフロントエンドなどに保存されます。前または次のページが2回クリックされると、渡されます。

次のページをクリックすると、minIdが渡されます。前のページをクリックすると、maxIdが渡されます。descsortingであるため、1つしか渡すことができません。前のページまたは次のページをクリックしてください。

package com.web.controller;

import com.web.common.controller.BaseController;
import com.web.common.exception.BusinessException;
import com.web.common.util.ConstantValue;
import com.web.common.util.web.PagingObject;
import com.web.common.util.web.PangingUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import web.service.logging.TbLoggingService;
import web.util.ResultUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 项目名称:
 * 类 名 称:TbLoggingController
 * 类 描 述:TODO
 * 创建时间:2020/6/12 17:15
 * 创 建 人:heng
 */
@Controller
@RequestMapping("logging")
public class TbLoggingController {
    @Autowired
    TbLoggingService tbLoggingService;
    /***
     * 查询实体TbLoggingDto的分页列表
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value="/search_TbLogging.do")
    public ResultUtils getListData(HttpServletRequest request , HttpServletResponse response)throws Exception {
        try {

            PagingObject init_pg = PangingUtils.getPagingObjectFormRequest(request);
            Map<String,Object> map = new HashedMap();
            map.put("create_time",request.getParameter("create_time"));
            map.put("maxId",request.getParameter("maxId"));
            map.put("minId",request.getParameter("minId"));
            map.put("pageSize",10);
            return tbLoggingService.findLoging(map);
        } catch (Exception ex) {
            logger.error("操作错误",ex);
            ex.printStackTrace();
            throw new BusinessException(ConstantValue.SYSTEM_ERROR_CODE,ConstantValue.SYSTEM_EROR_MESSAGE);
        }
    }

}

 

おすすめ

転載: blog.csdn.net/qq_39313596/article/details/106780770