Spring Boot项目监控异常,发送邮件

Spring Boot项目监控异常,发送邮件


需求

之前博客有提到,就是需要监控程序异常,因为这个是后台运行,无法监控程序异常,所以需要监控应用异常是否出现大面积报错。

应用每天记录报错次数,如果大于预定次数,则发送邮件通知团队处理,发送之后就不需要进行记录了,当天不需要进行通知了,隔天再进行通知。


实现

直接上代码,比较简单,记录一下:

@Service
@Slf4j
@EnableConfigurationProperties(MonitorConfig.class)
public class MonitorExceptionService {
   

    @Resource
    private JavaMailSender mailSender;

    @Resource
    private MonitorConfig monitorConfig;

    @Value("${spring.profiles.active:test}")
    private String profile;

    private volatile LocalDate lastDate;
    private volatile int errorTimes = 0;
    private volatile boolean mailFlag = false;
    private final Map<String, List<String>> ERROR_STACK = new ConcurrentHashMap<>();

    @Async
    synchronized public void recordError(Exception e) {
   
        LocalDate now = LocalDate.now(ZoneId.of("Asia/Shanghai"));
        if (Objects.isNull(lastDate) || now.isAfter(lastDate)) {
   
            lastDate = now;
            errorTimes = 0;
            mailFlag = false;
            ERROR_STACK.clear();
            log.info("clear old data done!");
        }
        if (mailFlag) {
   
            return;
        }
        errorTimes ++;

        String exceptionName = e.getClass().getName();
        List<String> list = ERROR_STACK.get(exceptionName);
        if (Objects.isNull(list)) {
   
            list = new ArrayList<>();
            ERROR_STACK.put(exceptionName, list);
        }
        list.add(e.getMessage());

        if (errorTimes >= monitorConfig.getMaxErrorTimes()) {
   
            try {
   
                sendEmail();
            } catch (MessagingException ex) {
   
                log.error("send mail notification error", ex);
            }
        }

    }

    private void sendEmail() throws MessagingException {
   
        log.info("start send email");
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true, StandardCharsets.UTF_8.name());
        messageHelper.setFrom(monitorConfig.getMailFrom());
        messageHelper.setTo(monitorConfig.getMailTo());
        messageHelper.setSubject(buildSubject());
        messageHelper.setText(monitorConfig.getMailTemplate());
        messageHelper.addAttachment("error.txt", new ByteArrayDataSource(buildAttachment(), "application/octet-stream"));
        mailSender.send(mimeMessage);
        log.info("end send email");
        mailFlag = true;
    }

    private byte[] buildAttachment() {
   
        StringBuilder sb = new StringBuilder();
        ERROR_STACK.forEach((err, list) -> {
   
            sb.append(err).append(": \n");

            for (int i = 0; i < list.size(); i++) {
   
                sb.append("   ").append(i).append(". ").append(list.get(i)).append("\n");
            }
            sb.append("\n");
        });

        return sb.toString().getBytes(StandardCharsets.UTF_8);
    }

    private String buildSubject() {
   
        String format = LocalDate.now(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ISO_LOCAL_DATE);

        return String.format("SYSTEM ERROR at %s (%s)",profile, format);
    }
}

程序是异步处理,但是需要上锁,因为是单节点,只需要这一个就够了,双节点问题也不大,就是发送两次而已,也可以换成分布式锁,没有条件的话可以换成数据库的锁即可。

打完收工!

相关推荐

  1. Spring Boot项目监控异常发送邮件

    2024-02-06 08:22:01       51 阅读
  2. springboot发送邮件

    2024-02-06 08:22:01       26 阅读
  3. thinkphp项目发送邮件

    2024-02-06 08:22:01       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-06 08:22:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-06 08:22:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-06 08:22:01       82 阅读
  4. Python语言-面向对象

    2024-02-06 08:22:01       91 阅读

热门阅读

  1. 【PyTorch】实现迁移学习框架DaNN

    2024-02-06 08:22:01       52 阅读
  2. seatunnel数据集成(二)数据同步

    2024-02-06 08:22:01       55 阅读
  3. Uni-app 学习笔记

    2024-02-06 08:22:01       55 阅读
  4. 【无标题】summarizations onMysql

    2024-02-06 08:22:01       51 阅读
  5. Linux服务器设置 SSH 通过密钥登录(免密登录)

    2024-02-06 08:22:01       50 阅读
  6. ubuntu22.04挂载磁盘的步骤

    2024-02-06 08:22:01       52 阅读
  7. 【RK3288 Android6 T2pro 支持移远和有方4G模块切换】

    2024-02-06 08:22:01       48 阅读
  8. ubuntu 自动挂载NFS配置

    2024-02-06 08:22:01       47 阅读
  9. Spring和Spring Boot的区别

    2024-02-06 08:22:01       47 阅读
  10. Qt应用软件【协议篇】MQTT协议介绍

    2024-02-06 08:22:01       47 阅读
  11. 算法专题:滑动窗口

    2024-02-06 08:22:01       46 阅读
  12. Python学习之路-Tornado基础:安全应用

    2024-02-06 08:22:01       42 阅读
  13. SpringMVC-响应数据

    2024-02-06 08:22:01       52 阅读
  14. 【计算机二级考试C语言】C排序算法

    2024-02-06 08:22:01       57 阅读
  15. sql常用函数积累(非窗口函数)

    2024-02-06 08:22:01       53 阅读