springboot+logback日志来发送异常信息邮件

系统异常了,上篇是通过在全局异常中通过调用发送邮件的处理器代码进行邮件的发送,总是觉得还不那么优雅

这篇是通过扩展 logback 的日志插件来处理 err 级别的日志异常信息来发送邮件的

通过这篇的学习,可以掌握如何扩展 logback 的日志类,来实现自己不可告人的目的。

下面直接上代码

首先自定义一个日志处理处理类  wlcLogLogbackAppender

 

import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;
import com.handler.WlcAsyncHandler;
import com.utils.SpringContextUtil;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 描述: 自定义日志处理类 <br>
 * 时间: 2021-07-01 11:11  <br>
 * 作者:IT学习道场
 */
public class wlcLogLogbackAppender extends AppenderBase<LoggingEvent> {

    @Override
    protected void append(LoggingEvent eventObject) {
        if(eventObject instanceof LoggingEvent){
            LoggingEvent loggingEvent = (LoggingEvent)eventObject;
            //拿到ThrowableProxy
            ThrowableProxy throwableProxy = (ThrowableProxy) loggingEvent.getThrowableProxy();
            if (Objects.nonNull(throwableProxy)) {
                //获取 throwable 顶级异常
                Throwable throwable = throwableProxy.getThrowable();
                //获取log的msg
                String formattedMessage = loggingEvent.getFormattedMessage();
                //获取请求request
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                        .getRequestAttributes()).getRequest();
                //获取spring的spring.mail.enable属性值,下面的逻辑你也可以自己根据想法自己玩也行
                String mailEnableProperty = SpringContextUtil.getEnvironmentProperty("spring.mail.enable");
                mailEnableProperty = (mailEnableProperty == null) ? "false" : mailEnableProperty;
                boolean mailEnable = Boolean.valueOf(mailEnableProperty);
                if (mailEnable){
                    //获取邮件的处理类
                    WlcAsyncHandler emailHandler = SpringContextUtil.getBean(WlcAsyncHandler.class);
                    emailHandler.handle(formattedMessage, throwable, request);
                }

            }
        }
        super.doAppend(eventObject);
    }

}

自定义的日志处理类搞完了,剩下的就是在logback-spring.xml中配置下就行,配置级别是 error 级别


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 修改一下路径-->
    <property name="PATH" value="./log"></property>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%-50logger{50}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n</Pattern>-->
            <Pattern>%d{ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/trace/trace.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/trace/trace.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--因为 FileNamePattern 配置规则是yyyy-MM-dd,就是天,所以maxHistory代表多少天-->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!--maxHistory生效必须加 <cleanHistoryOnStart>true</cleanHistoryOnStart>-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
    </appender>

    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/error/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/error/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--配置自定义的日志处理了-->
    <appender name="WlcLog" class="com.logback.wlcLogLogbackAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    

    <!--ERROR级别调用-->
    <root level="ERROR">
        <appender-ref ref="ERROR_FILE" />
        <appender-ref ref="WlcLog" />
    </root>

    <root level="TRACE">
        <appender-ref ref="TRACE_FILE" />
    </root>

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

当然由于

判断了异常不为空时,想要进去判断,就需要在log输出日志时,要注入 Throwable

如下

必须用  log.error("这是一个日志msg", e); 

这样 

ThrowableProxy throwableProxy = (ThrowableProxy) loggingEvent.getThrowableProxy();

throwableProxy 就不等于 null

像 log.error("这是一个日志msg"); 

throwableProxy 就等于 null

这样自定义一个日志处理处理类  wlcLogLogbackAppender 就生效了

你可以  wlcLogLogbackAppender  在里面你可以拿到日志信息,做一些自己想做的事情。比如我这边就是在里面发送邮件,当然你可以做任何事

发邮件的代码就不分享了,有兴趣的可以去看上一篇文章。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT学习道场

为你的进步加点油!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值