SpringBoot combat email alarm based on exception log

SpringBoot combat email alarm based on exception log

I believe that all the small partners who are struggling on the front line will be very concerned about the operation of their own systems. Generally speaking, companies with complete infrastructure will have a complete alarm plan. If we are a small company, it cannot be because of lack of infrastructure. , just lose the perception ability of the object; if there are a lot of abnormalities in our system but cannot reach us in real time, then there will only be one result - kill a programmer and sacrifice to the sky

This article briefly introduces an implementation idea, based on the error log to realize the email alarm scheme

<!-- more -->

I. Project Environment

1. Project dependencies

This project is developed with the help of SpringBoot 2.2.1.RELEASE+ maven 3.5.3+IDEA

Open a web service for testing

<dependencies>
    <!-- 邮件发送的核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
</dependencies>

2. Configuration

The mail-related configuration is as follows, pay attention to use your own username + authorization code to fill in the missing configuration below

spring:
  #邮箱配置
  mail:
    host: smtp.163.com
    from: [email protected]
    # 使用自己的发送方用户名 + 授权码填充
    username:
    password:
    default-encoding: UTF-8
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true

II. Email alerts for abnormal logs

1. Design ideas

The main starting point of the next plan is that when a large number of exceptions occur in the program, it indicates that most of the applications have problems and need to be sent to the project owner immediately.

To realize this solution, the key point is the perception and reporting of abnormal occurrences

  • Capture exceptions and output logs
    • For this perception, it can be achieved with the help of logback's extension mechanism, which will be described later.
  • Abnormal reporting: Email sending

Regarding the use posture of email, it is recommended to refer to the introduction to the email sending posture of the SpringBoot series of blog posts

2. Custom appenders

Define an Appender for error sending, as follows

public class MailUtil extends AppenderBase<ILoggingEvent> {

    public static void sendMail(String title, String context) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        //邮件发送人
        simpleMailMessage.setFrom(ContextUtil.getEnvironment().getProperty("spring.mail.from", "[email protected]"));
        //邮件接收人,可以是多个
        simpleMailMessage.setTo("[email protected]");
        //邮件主题
        simpleMailMessage.setSubject(title);
        //邮件内容
        simpleMailMessage.setText(context);

        JavaMailSender javaMailSender = ContextUtil.getApplicationContext().getBean(JavaMailSender.class);
        javaMailSender.send(simpleMailMessage);
    }

    private static final long INTERVAL = 10 * 1000 * 60;
    private long lastAlarmTime = 0;

    @Override
    protected void append(ILoggingEvent iLoggingEvent) {
        if (canAlarm()) {
            sendMail(iLoggingEvent.getLoggerName(), iLoggingEvent.getFormattedMessage());
        }
    }

    private boolean canAlarm() {
        // 做一个简单的频率过滤
        long now = System.currentTimeMillis();
        if (now - lastAlarmTime >= INTERVAL) {
            lastAlarmTime = now;
            return true;
        } else {
            return false;
        }
    }
}

3. Spring container

In the above email sending, you need to use JavaMailSenderand write a simple SpringContext tool class to get Bean/Propertiy

@Component
public class ContextUtil implements ApplicationContextAware, EnvironmentAware {

    private static ApplicationContext applicationContext;

    private static Environment environment;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ContextUtil.applicationContext = applicationContext;
    }

    @Override
    public void setEnvironment(Environment environment) {
        ContextUtil.environment = environment;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Environment getEnvironment() {
        return environment;
    }
}

4. logback configuration

The next step is to use the Appender we defined above in the log configuration

logback-spring.xmlThe contents of the file are as follows:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d [%t] %-5level %logger{36}.%M\(%file:%line\) - %msg%n</pattern>
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="errorAlarm" class="com.git.hui.demo.mail.util.MailUtil">
        <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>


    <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
    <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
    <!-- additivity=false 表示匹配之后,不再继续传递给其他的logger-->
    <logger name="com.git.hui" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="errorAlarm"/>
    </logger>

    <!-- 控制台输出日志级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

5. Test the demo

Next, let's demonstrate whether it can meet our expectations

@Slf4j
@RestController
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @GetMapping("div")
    public String div(int a, int b) {
        try {
            return String.valueOf(a / b);
        } catch (Exception e) {
            log.error("div error! {}/{}", a, b, e);
            return "some error!";
        }
    }
}

5. Summary

This blog post mainly provides an idea, with the help of the extension mechanism of logback, to realize the binding of error log and warning email, and realize a simple application exception monitoring

The above implementation is only a prototype, it can be regarded as an introduction, there are more details that can be enriched, such as

  • Feishu/Dingding notification (with the help of Feishu's Dingding machine to alarm, it is more sensitive than email)
  • According to the type of abnormality, make the distinction of early warning
  • More advanced frequency limiting, etc.

Here I recommend an early warning system that I have open sourced before, which can realize flexible early warning scheme configuration, frequency limit, importance upgrade, etc.

III. Source code and related knowledge points that cannot be missed

0. Project

Recommended related blog posts

1. A gray blog

It is not as good as a letter. The above content is purely from the family. Due to limited personal ability, it is inevitable that there will be omissions and mistakes. If you find bugs or have better suggestions, you are welcome to criticize and correct them.

The following is a gray personal blog, recording all blog posts in study and work, welcome everyone to visit

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324064837&siteId=291194637