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

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

  • 需求
  • 实现
  • 打完收工!


需求

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

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


实现

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

@Service
@Slf4j
@EnableConfigurationProperties(MonitorConfig.class)
public class MonitorExceptionService {@Resourceprivate JavaMailSender mailSender;@Resourceprivate 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<>();@Asyncsynchronized 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);}
}

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

打完收工!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/670047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我在项目中使用Redis的几个场景

目录 缓存 会话存储 分布式锁 消息队列 位统计 计数器 排行榜 缓存 缓存的目的是为了提高系统响应速度、减少数据库等资源的压力&#xff0c;redis作为键值对形式的内存数 据库&#xff0c;可以提供非常快速的读取速度&#xff0c;使得它成为存储热点数据或频繁访问数…

使用PDFBox实现pdf转其他图片格式

最近在做一个小项目&#xff0c;项目中有一个功能要把pdf格式的图片转换为其它格式&#xff0c;接下来看看用pdfbox来如何实现吧。 首先导入pdfbox相关依赖&#xff1a; <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</a…

3、类型系统:boolean、string、number、bigint、symbol、object、undefined、null

JavaScript 语言&#xff08;注意&#xff0c;不是 TypeScript&#xff09;将值分成8种类型。 booleanstringnumberbigintsymbolobjectundefinednull TypeScript 继承了 JavaScript 的类型设计&#xff0c;以上8种类型可以看作 TypeScript 的基本类型。 注意&#xff0c;上面…

5-3、S曲线生成器【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍步进电机S曲线生成器的计算以及使用 一.计算原理 根据上一节内容&#xff0c;已经计算了一条任意S曲线的函数。在步进电机S曲线加减速的控制中&#xff0c;需要的S曲线如图1所示&#xff0c;横…

关于RabbitMQ常见的十道面试题

RabbitMQ是如何组成的&#xff1f;它有哪些重要的组件&#xff1f; RabbitMQ主要由以下几个重要组件组成&#xff1a; Broker&#xff1a;这是消息代理&#xff0c;主要负责接收、存储和转发消息Exchanges&#xff1a;交换器&#xff0c;它的主要作用是根据一定的规则匹配消息…

如何在Windows系统上部署docker

上次在Windows系统上部署成功Ubuntu系统&#xff0c;这次准备在Windows上部署docker desktop应用 这个应用软件类似于虚拟机&#xff0c;可以在该应用软件上部署多个镜像容器。其最直观的表现就是可以借用Windows和Ubuntu终端来访问docker“模拟的系统”。 Docker简介 Docke…

【数据结构与算法】之排序系列-20240205

这里写目录标题 一、1346. 检查整数及其两倍数是否存在二、1365. 有多少小于当前数字的数字三、1460. 通过翻转子数组使两个数组相等四、1491. 去掉最低工资和最高工资后的工资平均值五、1502. 判断能否形成等差数列 一、1346. 检查整数及其两倍数是否存在 简单 给你一个整数数…

关于RabbitMQ面试题汇总

什么是消息队列&#xff1f;消息队列有什么用&#xff1f; 消息队列是一种在应用程序之间传递消息的通信机制。它是一种典型的生产者-消费者模型&#xff0c;其中生产者负责生成消息并将其发送到队列中&#xff0c;而消费者则从队列中获取消息并进行处理。消息队列的主要目的是…

Vivado-IP核

Vivado-IP核 主程序 timescale 1ns / 1ps ////module ip_clk_wiz(input sys_clk,input sys_rst_n,output clk_out1,output clk_out2,output clk_out3,output clk_out4,output locked);clk_wiz_0 instance_name(// Clock out ports.clk_out1(clk_out1), // output clk_out…

typeof的语法和使用总结

typeof的语法和使用总结 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将深入探讨JavaScript中typeof操作符的语法和使用&#xff0c;帮助大家…

数字孪生:智慧城市的核心技术与发展

一、引言 随着城市化进程的加速&#xff0c;智慧城市的概念和实践逐渐成为全球关注的焦点。智慧城市利用先进的信息通信技术&#xff0c;提升城市治理水平&#xff0c;改善市民的生活质量。而数字孪生作为智慧城市的核心技术&#xff0c;为城市管理、规划、应急响应等方面提供…

sklearn模型指标和特征贡献度查看

文章目录 算法介绍r2_scoretrain_test_splitDecisionTreeRegressor参考文献支持快速查看traget和特征之间的关系 # -*- coding: utf-8 -*- import pandas as pd pd.set_option(display.max_columns, None) pd.set_option

Django部署到服务器后无法获取到静态元素 The requested resource was not found on this server

问题描述 写了一个Django项目&#xff0c;部署到云主机后&#xff0c;访问发现图片无法访问&#xff0c;报错The requested resource was not found on this server 图片是一个词云图&#xff0c;根据爬虫爬取的信息生成的&#xff0c;根据爬取的信息会改变&#xff0c;所以没…

python_蓝桥杯刷题记录_笔记_全AC代码_入门5

前言 关于入门地刷题到现在就结束了。 题单目录 1.P1579 哥德巴赫猜想&#xff08;升级版&#xff09; 2.P1426 小鱼会有危险吗 1.P1579 哥德巴赫猜想&#xff08;升级版&#xff09; 一开始写的代码是三重循环&#xff0c;结果提交上去一堆地TLE&#xff0c;然后我就给减少…

无人零售模式下,“IoT+鸿蒙”实现零代码搭建自动售货机监控大屏的可能性摸索

前言 新零售模式下&#xff0c;对loT的探索与应用还在继续。 而数字时代&#xff0c;数字化转型在零售行业中蔓延&#xff0c;而对于新的消费方式的探索&#xff0c;也在如火如荼的进行中。于是&#xff0c;一种新零售的形式——无人零售逐渐形成概念。 如果说&#xff0c;人…

【教3妹学编程-算法题】1696. 跳跃游戏 VI

3妹&#xff1a;好冷啊&#xff0c; 冻得瑟瑟发抖啦 2哥 : 没想到都立春了还这么冷啊~ 3妹&#xff1a;暴雪、冻雨、大雨&#xff0c;这天气还让不让人活啦&#xff01;&#xff01;&#xff01; 2哥 :哎&#xff0c;好多人都滞留的高铁站了&#xff0c;没法回家了 3妹&#xf…

nvm报错解决:配置最新淘宝镜像源

nvm修改配置的淘宝镜像 问题&#xff1a; 原因&#xff1a;原先配置的淘宝镜像已经不被使用 修改&#xff1a; 找到\nvm\nvm\settings.txt文件&#xff0c;配置如下 node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 配置成…

复习单向,双向链表,并且实现两种链表的增加和删除功能。

单链表头插 Linklist insert_head(datatype element,Linklist head) {//创建新节点 Linklist screate_node();if(NULLs)return head; s->dataelement;//1,判断链表为空if(NULLhead){heads;}else //链表不为空{s->nexthead;heads;}return head; } 单链表尾插 Linklist …

汽车信息安全--SHE中的密钥管理(一)

目录 1.HTA基本概述 2.SHE架构及密钥管理 2.1 分清SHE和EVTIA HSM 2.2 SHE架构 3.

linker list

linker list是利用lds 描述符实现同类型数据连续排布的一种机制。 下面是uboot里面的应用说明 lds文件里面需要增加section描述&#xff1a; . ALIGN(4);.u_boot_list : {KEEP(*(SORT(.u_boot_list*)));}linker_list.h: /* SPDX-License-Identifier: GPL-2.0 */ /** include…