Design of platform user operation log module

Posted by stueee on Thu, 23 May 2019 00:05:35 +0200

This paper mainly describes the implementation of log module of general platform from three parts.

  • Development tools: spring Mvc 4.3, jdk8, mybatis 3.3
  1. Summary
The logs here mainly record the user's operation on the platform and the results of the operation. Implementing ideas will focus on recording
 The user sends part of the data in the request and the result returned after execution gets the controller return data before writing the response body. Save the data of these two parts to the corresponding log table
  1. The table is structured as follows:
-- ----------------------------------------------------------------
-- User Operations Log Table
-- ----------------------------------------------------------------
DROP TABLE IF EXISTS `LOG`;
CREATE TABLE `LOG` (
  `ID` INT(12) NOT NULL AUTO_INCREMENT COMMENT 'Log number',
  `LOG_MODULE` VARCHAR(50)  COMMENT 'Operation module',
  `REQUEST_IP` VARCHAR(20) COMMENT 'request IP',
  `USER_ID` INT(11) NOT NULL  COMMENT 'User number',
  `ROLE_NAME` VARCHAR(50)   COMMENT 'Role name',
  `USER_NAME` VARCHAR(50)   COMMENT 'User name',
  `LOG_ACTION` VARCHAR(50)   COMMENT  'Operation behavior',
  `LOG_RESULT` VARCHAR(20) DEFAULT NULL COMMENT 'Request result',
  `LOG_TIME` TIMESTAMP  COMMENT  'Request time',
  PRIMARY KEY (`ID`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;
-- ----------------------------------------------
-- Requests for user log records are initially as follows
-- ----------------------------------------------
DROP TABLE IF EXISTS `LOG_ACTION`;
CREATE TABLE `LOG_ACTION` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Jurisdiction ID',
  `ACTION_URI` VARCHAR(100)  COMMENT 'URI',
  `ACTION_MODULE` VARCHAR(100)   COMMENT 'The module to which the operation belongs',
  `ACTION_DESC` VARCHAR(200)  COMMENT 'Action description',
  UNIQUE INDEX index_action(ACTION_URI),
  PRIMARY KEY (`ID`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;
--  The following initial data can be inserted
insert into log_action(action_uri,action_Module,action_desc) values ('/abc/bcd.do','User center','New user');
....etc.
  • Relevant Notes: LOG tables are used for logging, while log_action tables are used to record requests that require logging module to record.
  1. Code module
  • Note: About the entity class LogAction (uri corresponding description of platform log), RequestModel (to save log details). Their entity classes and corresponding mybatis dao operations are no longer described here
  • Platform Start Cached Data Class
/**
 * Copyright: Copyright (c) 2017 LanRu-Caifu
 * @author 
 * @ClassName: ActionUrlCache.java
 * @Description: Cache initialization requires intercepting requests to be saved to the log
 * @version: v1.0.0
 */
public final class ActionUrlCache {

private ActionUrlCache(){}
    
    //Cache Area Service Address
    private static final ConcurrentHashMap<String, String> actionCache = new ConcurrentHashMap<>();
    //Get cache
    public static ConcurrentHashMap<String, String> getActionCache(){
        
        return actionCache;
    }
    //Add Service Address
    public static void  addService(String k ,String v){
        //Repeated coverage
        actionCache.put(k,v);
    }
    //Does the specified key exist?
    public static boolean isExist(String k){
        return actionCache.containsKey(k);
    }
    //Interpret whether the current cache is empty
    public static boolean isEmpyt(){
        return actionCache.size()<=0;
    }
    . . . ellipsis
}
  • The initialization data here can be customized (inheriting the spring InitializingBean interface) to save the way you need to look up later.
/**
 * Copyright: Copyright (c) 2017 LanRu-Caifu
 * @author 
 * @ClassName: InitServiceUrl.java
 * @Description: Platform startup initializes some data
 * @version: v1.0.0
 */
@Component
public class InitServiceUrl implements InitializingBean {
    private static final Logger LOGGER = Logger.getLogger(InitServiceUrl.class);
    @Resource
    private LogActionService lAS;
    //Initialization method
    @Override
    public void afterPropertiesSet() throws Exception {
        List<LogAction> logActions = lAS.getAllAction();
        if(null == logActions){
            LOGGER.error("No log interception information is configured");
            return ;
        }
        for(LogAction logAction:logActions){
            ActionUrlCache.addService(logAction.getActionUri(), logAction.getActionDesc());
        }
    }
}
  • In the interceptor, part of the data in the request is encapsulated into the log entity class requestMoudel.
@Repository
public class AccessInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = Logger.getLogger(AccessInterceptor.class);
. . . Ellipsis part
@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
            . . . Ellipsis part
            String request_uri = request.getRequestURI();
            //The uri is presupposed and handled by spring MVC Controller
             if (ActionUrlCache.isExist(request_uri) && handler instanceof HandlerMethod) { 
                 RequestModel requestModel = new RequestModel();
                 requestModel.setRequestIp(getIpAddr(request));//ip
                 requestModel.setUserName(user.getUserName());
                 requestModel.setUserId(user.getUserId());;
                 requestModel.setUri(request_uri);
                 Role role = (Role)request.getSession().getAttribute("role");
                 requestModel.setRoleName(role != null?role.getRoleName():null);
                 requestModel.setLogTime(TimeUtil.getCurrentDate());//date
                 RequestModel.setRequestModel(requestModel);  
            }  
            return true;
        }
. . . Ellipsis part
  • The following class is pre-processed when the response is written to the body, and you can get the Controller. Spring's RespseBodyAdvice interface needs to be implemented and injected into the spring container
/**
 * Copyright: Copyright (c) 2017 LanRu-Caifu
 * @author xzg
 * @ClassName: LogResponseBodyAdvice.java
 * @Description: The return data in Controller can be retrieved by pre-processing when the response is written to the body
 * @version: v1.0.0
 */
@ControllerAdvice  
public class LogResponseBodyAdvice implements ResponseBodyAdvice<Object>{  
    @Resource  
    private OperateLogService operateLogService;  
      
    @Override  
    public Object beforeBodyWrite(Object result, MethodParameter returnType, MediaType selectedContentType,  
            Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {  
        //Gets the object placed in the ApiInterceptor as a thread local variable for the specified request parameters  
        RequestModel model = RequestModel.getRequestModel();  
        //Remove thread local variables and release memory  
        RequestModel.removeRequestModel();  
        //Save log  
        operateLogService.saveLog(model, result);  
        return result;  
    }  
. . . ellipsis
  • The following are the interfaces used, the specific implementation classes and DAO s that operate the database, which are not described here.
Log url service interface to obtain platform initialization data
public interface LogActionService {
    public List<LogAction> getAllAction();
}

 Log operation interface to save log information. RequestModel is an entity class for log information
public interface LogModuleService {
    public Result getLog(Map<String,Object> params);
    public void addLog(RequestModel rm);
}

Operational Logging Method as Response Processing
public interface OperateLogService {
    public void saveLog(RequestModel model,Object result);
}

Topics: Spring Java Mybatis Database