Logging Intercepter例子

public class LoggingInterceptor {


    private final static Logger log = LoggerFactory.getLogger("MethodLogging");


    public final static String IO_LOGGER_KEY = "method";
    
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        Method method = getMethod(point);
        LogIgnore ignore = method.getAnnotation(LogIgnore.class);


        if (ignore == null && method != null) {
            logInputMessage(point, method);
        }


        Object output = point.proceed();


        if (ignore == null && method != null) {
            logOutputMessage(point, method, output);
        }


        return output;
    }


    protected void logInputMessage(JoinPoint jp, Method method) {
        boolean mdc = false;
        
        try {
            InputLog ann = method.getAnnotation(InputLog.class);


            // check whether need to log input arguments
            if (ann != null && !ArrayUtils.isEmpty(jp.getArgs())) {
                // if LogIgnore applied on method, will ignored whole method
                // log
                Object[] args = jp.getArgs();
                Annotation[][] anns = method.getParameterAnnotations();


                for (int i = 0; i < args.length; i++) {
                    LogMask mask = null;


                    if (anns != null) {
                        LogIgnore ignore = getParameterAnnotation(anns[i], LogIgnore.class);
                        if (ignore != null) {
                            continue; // ignore output the parameter log
                        }


                        mask = getParameterAnnotation(anns[i], LogMask.class);
                    }


                    StringBuilder text = new StringBuilder();
                    String prefix = ann.prefix();


                    // build object log
                    Object body = buildLogMessageBody(args[i], mask, text);


                    String logPrefix = getInputPrefix(jp, method, prefix, i);
                    String loggerText = getLoggerText(jp, method);
                    
                    putLoggerText(loggerText);
                    mdc = true;
                    
                    outputMessage(logPrefix, body, ann.value());
                }
            }
        } catch (Throwable t) {
            log.warn("exception occured when logging input {}", t.toString());
        }finally{
            if(mdc){
                removeLoggerText();
            }
        }
    }


    protected void logOutputMessage(JoinPoint jp, Method method, Object output) {
        boolean mdc = false;
        
        try {
            OutputLog ann = method.getAnnotation(OutputLog.class);


            if (ann != null) {
                StringBuilder text = new StringBuilder();


                String prefix = ann.prefix();


                // build object log
                LogMask mask = method.getAnnotation(LogMask.class);
                Object body = buildLogMessageBody(output, mask, text);


                String logPrefix = getOutputPrefix(jp, method, prefix);
                String loggerText = getLoggerText(jp, method);
                
                putLoggerText(loggerText);
                mdc = true;
                
                outputMessage(logPrefix, body, ann.value());
            }
        } catch (Throwable t) {
            log.warn("exception occured when logging output {}", t.toString());
        }finally{
            if(mdc){
                removeLoggerText();
            }
        }
    }


    protected Object buildLogMessageBody(Object arg, LogMask mask, StringBuilder text) {
        Object body = null;


        if (arg != null && LogUtils.isSimpleType(arg.getClass())) {
            // for simple types, log as string way
            if (mask != null) {
                if (mask.value() == LogMaskType.SimpleMask) {
                    // for simple mask, mark some chars
                    text = text.append(LogUtils.markString(String.valueOf(arg), LogMaskType.SimpleMask.getMask()));
                } else {
                    // for full mask, mask all chars with mask chars
                    text = text.append(LogUtils.markFullString(String.valueOf(arg), LogMaskType.FullMask.getMask()));
                }
            } else {
                // no mask, output object directly
                text = text.append(String.valueOf(arg));
            }


            body = text;
        } else {
            // output object
            body = arg;
        }


        return body;
    }


    protected String getLoggerText(JoinPoint jp, Method method){
        return StringUtils.join(new Object[] {jp.getTarget().getClass().getCanonicalName(), ".", method.getName()});
    }
    
    protected String getInputPrefix(JoinPoint jp, Method method, String prefix, int index) {
        String text = prefix;
        if (StringUtils.isBlank(prefix)) {
//            text = StringUtils.join(new Object[] { jp.getTarget().getClass().getCanonicalName(), ".", method.getName(),
//                    " args[", index, "]->" });
            text = StringUtils.join(new Object[] { "input args[", index, "]->" });
        }
        return text;
    }


    protected String getOutputPrefix(JoinPoint jp, Method method, String prefix) {
        String text = prefix;
        if (StringUtils.isBlank(prefix)) {
//            text = StringUtils.join(new Object[] { "==>", jp.getTarget().getClass().getCanonicalName(), ".", method.getName(),
//                    " output->" });
            text = StringUtils.join(new Object[] { "output==>"});       }
        return text;
    }


    protected void outputMessage(String prefix, Object text, LogLevel level) {
        if (level == LogLevel.INFO) {
            log.info("{}[{}]", prefix, text);
        } else if (level == LogLevel.DEBUG) {
            log.debug("{}[{}]", prefix, text);
        } else if (level == LogLevel.WARN) {
            log.warn("{}[{}]", prefix, text);
        } else if (level == LogLevel.ERROR) {
            log.error("{}[{}]", prefix, text);
        } else if (level == LogLevel.TRACE) {
            log.trace("{}[{}]", prefix, text);
        }
    }


    protected void putLoggerText(String loggerText){
        MDC.put(IO_LOGGER_KEY, loggerText);
    }
    
    protected void removeLoggerText(){
        MDC.remove(IO_LOGGER_KEY);
    }
    
    @SuppressWarnings("unchecked")
    private <T extends Annotation> T getParameterAnnotation(Annotation[] anns, Class<T> c) {
        T t = null;


        if (!ArrayUtils.isEmpty(anns)) {
            for (Annotation ann : anns) {
                if (ann.annotationType() == c) {
                    t = (T) ann;
                    break;
                }
            }
        }


        return t;
    }


    private Method getMethod(JoinPoint jp) {
        Method method = null;
        Signature signature = jp.getSignature();


        if (signature instanceof MethodSignature) {
            MethodSignature ms = (MethodSignature) jp.getSignature();
            method = AopUtils.getMostSpecificMethod(ms.getMethod(), jp.getTarget().getClass());
        }


        return method;
    }
}

你可能感兴趣的:(log,logback,slf4j,log拦截器)