Java监控程序异常并发送报警邮件(可监控异常、响应时长)

本文主要通过java Aop面向切面的思想进行访问程序的监控,话不多说,先上代码。

1.导入包:

 
      org.aspectj
      aspectjweaver
      1.8.13
 

2.定义切面代码:

package com.meiyibao.aop;

import com.carrotsearch.sizeof.RamUsageEstimator;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.meiyibao.easycoal.framework.metadata.MybData;
import com.meiyibao.constants.MybConstants;
import com.meiyibao.email.EmailUtil;
import com.meiyibao.util.encryption.ExceptionUtil;
import com.meiyibao.util.json.JSONHelper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 用来处理异常信息的切面
 *
 * @author root
 */
@Component
@Aspect
@Slf4j
public class ExceptionAop {

    @ApolloConfig
    private Config config;

    @Autowired
    private EmailUtil emailUtil;

    @Around("execution(* com.meiyibao.controller..*.*(..))")//这里可以通过你的项目包名进行配置
    public Object around(ProceedingJoinPoint pj) throws Throwable {
        long starttime=System.currentTimeMillis();
        try {
            log.info("---------------------API请求参数:【"+getMessage(pj, null)+ "】");
            Object obj = pj.proceed();
            long size = RamUsageEstimator.sizeOf(obj);
            if(size<2*1024){
                //2kb
                log.info("---------------------API返回值:【" +"类名:{},方法名:{};返回值:{}】",pj.getTarget().getClass().getSimpleName(),pj.getSignature().getName(),JSONHelper.convertToJSON(obj));
            }
             return obj;
        } catch (MethodArgumentNotValidException e) {
            e.getBindingResult().getGlobalErrors();
            return MybData.error("请求参数验证失败");
        } catch (SocketTimeoutException e) {
            concatError(starttime, getMessage(pj, e));
            return MybData.error(MybConstants.EXCEPTION_TIMEOUT_ERROR);
        } catch (Exception e) {
            concatError(starttime, getMessage(pj, e));
            return MybData.error(MybConstants.EXCEPTION_BUSY);
        }
    }

    private void concatError(long starttime, String message) {
        StringBuilder stringBuilder=new StringBuilder( "

接口耗时:

"); stringBuilder.append("接口花费时间:").append(System.currentTimeMillis()-starttime).append("ms
"); stringBuilder.append(message); sendErrorNotice(stringBuilder.toString()); } private String getMessage(ProceedingJoinPoint pj, Exception e) { if (e != null) { log.error(e.getMessage(), e); } RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); String token = request.getHeader(MybConstants.AUTHORIZATION); String userInfo = request.getHeader(MybConstants.HEAD_USER_INFO); StringBuilder joiner = new StringBuilder("

链接:

") .append(request.getRequestURI()) .append("

token:

") .append((token == null ? "" : token)) .append("

user phone info:

") .append((userInfo == null ? "" : userInfo)) .append(";

类名:

") .append(pj.getTarget().getClass().getSimpleName()) .append(";

方法:

") .append(pj.getSignature().getName()) .append(";

参数:

"); Object[] args = pj.getArgs(); List objects=new ArrayList<>(); for(Object object:args){ if(object instanceof MultipartFile || object instanceof File ){ continue; } objects.add(object); } joiner.append(JSONHelper.convertToJSON(objects)); if (Objects.nonNull(e)) { joiner .append(";

message:

") .append(e.getMessage()) .append(";

异常:

") .append(ExceptionUtil.getMsg(e)); } return joiner.toString(); } private void sendErrorNotice(String content) { log.error(content); boolean enable = config.getBooleanProperty("exception.sendemail.enable", false); if (enable) { emailUtil.send(content);//发送邮件,具体邮件配置可以参考我的资源中的邮件发送 源码 } } }

 

你可能感兴趣的:(java面向切面,切面监控)