Collection of annotations and AOP implementation logs

The background is: the project is a distributed project deployed with spring cloud eureka service system, which is separated before and after, and the front-end node s directly call each service interface.

The principle is to start and end the log collection of recording request, response and operation information in the handle with annotation as the starting point.

The difficulty is: the operation of distributed log record warehousing is considered to be abstract at the beginning, but the persistence operation depends on the service container. Each service module cannot share a running container. The solution is that each service provides a sub method to realize log persistence.

Code implementation:

1. Create a new annotation (pointcut)

package com.ww.common.annotation;

import java.lang.annotation.*;

/**
 * System logging
 *
 * @author: Ace Lee
 * @create: 2019-04-11 14:59
 */
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebLog {

}

2. Add @ WebLog annotation to the method of collecting logs

3. Provide a common parent class for logging information

package com.ww.common.filter;

import com.google.common.base.Throwables;
import com.ww.common.constant.Result;
import com.ww.common.constant.UserInfo;
import com.ww.common.constant.WwCommonInfo;
import com.ww.common.json.JacksonUtil;
import com.ww.common.web.PtaqCzrzWithBLOBs;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.Date;
import java.util.UUID;

/**
 * Log collection
 *
 * @author: Ace Lee
 * @create: 2019-04-12 09:57
 */
@Aspect
@Component
@Slf4j
public abstract class BaseAspect {

    protected PtaqCzrzWithBLOBs doBefore(HttpServletRequest request){
        // Receive request, record request content
        PtaqCzrzWithBLOBs consumer=new PtaqCzrzWithBLOBs();
        Date now = new Date();
        consumer.setWW_CZSJ(now);
        consumer.setWW_QQSJ(now);

        // Record the request
        consumer.setWW_QQDX(request.getRequestURL().toString());
        consumer.setWW_QQIP(request.getRemoteAddr());
        return consumer;
    }


    protected void  doAfterReturning(Object object,PtaqCzrzWithBLOBs consumer,HttpServletRequest request,String bz){
        if(null!=consumer){
            try {
                consumer.setWW_XYSJ(new Date());

                // After processing the request, return the content
                String response="";
                if (null!=object){
                    Result result = (Result) object;
                    response = JacksonUtil.bean2Json(object);
                    consumer.setWW_XYBW(response);
                    if (result.isSuccess()){
                        consumer.setWW_XYJG(WwCommonInfo.IS_SUCCESS_YES);
                    }else {
                        consumer.setWW_XYJG(WwCommonInfo.IS_SUCCESS_NO);
                        consumer.setWW_XYMS(result.getError());
                    }
                }
                log.info("response param: {}",response);

                long elapsedTime = consumer.getWW_XYSJ().getTime() - consumer.getWW_QQSJ().getTime();
                log.info("elapsed time : {} ms",elapsedTime);
                consumer.setWW_XYSC(BigDecimal.valueOf(elapsedTime));
                log.info("========HTTP  END=========");
                //Set operator
                String method = request.getMethod();

                switch (method){
                    case "POST": case "post":
                        consumer.setWW_QQBW(getBody(request));
                        consumer.setWW_CZ("Newly added");
                        break;
                    case "PUT": case "put":
                        consumer.setWW_QQBW(getBody(request));
                        consumer.setWW_CZ("edit");
                        break;
                    case "DELETE": case "delete":
                        consumer.setWW_CZ("delete");
                        break;
                    case "GET": case "get":
                        consumer.setWW_QQBW(getUrlParams(request));
                        consumer.setWW_CZ("query");
                        break;
                    default:
                        consumer.setWW_QQBW(getUrlParams(request));
                        consumer.setWW_CZ("query");
                        break;
                }
                consumer.setWW_QQFS(method);

                Object oTable = request.getAttribute(WwCommonInfo.KEY_TABLE_NAME);
                if (null!=oTable){
                    consumer.setWW_ZYDX((String) oTable);
                }
                Object oId = request.getAttribute(WwCommonInfo.KEY_ENTITY_ID);
                if (null!=oId){
                    consumer.setWW_QQID((String) oId);
                }
                Object oUser = request.getAttribute(WwCommonInfo.KEY_USER_INFO);
                if (null!=oUser){
                    UserInfo userInfo = (UserInfo) oUser;
                    consumer.setWW_CZR(userInfo.getId());
                    consumer.setWW_CZRDW(userInfo.getUnitId());
                }
                consumer.setWW_CJSJ(new Date());
                consumer.setWW_BZ(bz);
                consumer.setWW_XH(String.valueOf(UUID.randomUUID()));
                log.info(">>>>>>log info :{}",JacksonUtil.bean2Json(consumer));
                saveConsumerLog(consumer);
            } catch (Exception e) {
                log.error(">>>>>>set log info error: {}", Throwables.getStackTraceAsString(e));
            }
        }
    }

    /**
     * Save operation log
     *
     * @param consumer
     */
    protected abstract void saveConsumerLog(PtaqCzrzWithBLOBs consumer);


    /**
     * Get request body
     *
     * @param request
     * @return body
     */
    private String getBody(HttpServletRequest request) {
        String body="";
        Object attribute = request.getAttribute(WwCommonInfo.KEY_BODY_INFO);
        if (null!=attribute){
            body = (String) attribute;
        }
        return body;
    }

    /**
     * Get request url parameters
     *
     * @param request
     * @return body
     */
    private String getUrlParams(HttpServletRequest request) {
        String body="";
        String attribute = request.getQueryString();
        if (!StringUtils.isEmpty(attribute)){
            body = URLDecoder.decode(attribute);
        }
        return body;
    }

}

4. Provide subclasses of faceted classes on each service module

The starting point here is our annotation class. The parameter passing before and after the request uses ThreadLocal. To store parameter values and abstract methods, we need to implement the warehousing operation in each service module.

package com.ww.config;

import com.google.common.base.Throwables;
import com.ww.common.filter.BaseAspect;
import com.ww.common.web.PtaqCzrzWithBLOBs;
import com.ww.dao.PtaqCzrzMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


/**
 * Implement the log aspect of Web layer
 *
 * @author liyazhou
 * @version v.0.1
 */
@Aspect
@Component
@Order(1)
@Slf4j
public class WebLogAspect extends BaseAspect {

    @Autowired
    private PtaqCzrzMapper ptaqCzrzMapper;

    ThreadLocal<PtaqCzrzWithBLOBs> consumerThreadLocal = new ThreadLocal<>();

    /**
     * Define an entry point
     *
     */
    @Pointcut("@annotation(com.ww.common.annotation.WebLog)")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint){
        log.info("========HTTP START=========");

        // Receive request, record request content
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        consumerThreadLocal.set(doBefore(request));
    }

    @AfterReturning(value = "webLog()",returning = "object")
    public void  doAfterReturning(Object object){
        PtaqCzrzWithBLOBs consumer = consumerThreadLocal.get();
        consumerThreadLocal.remove();
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        doAfterReturning(object,consumer,request,"OPEN");
    }



    /**
     * Save operation log
     *
     * @param consumer
     */
    @Override
    protected void saveConsumerLog(PtaqCzrzWithBLOBs consumer) {
        try {
            ptaqCzrzMapper.insertSelective(consumer);
            log.info(">>>>>>insert log info success");
        } catch (Exception e) {
            log.error(">>>>>>insert log info error: {}",Throwables.getStackTraceAsString(e));
        }
    }

}

 

 

 

Keywords: Attribute Java Google Lombok

Added by aleksandra on Wed, 27 Nov 2019 18:36:19 +0200