Springboot 之 利用logback发送异常警告邮件


利用logback自动将异常邮件发送到运维邮箱里。

简书地址

logback作为默认的日志实现在springboot项目里很多,尤其是有了lombok。

log打到配置文件里,并且分sql、info、error这些都太easy,随后我会附上我的配置。

那么怎么用这东西将异常邮件发送给运维人员呢?

properties配置

logback.logdir=/opt/chuangke/log/pre/api
logback.appname=mobileoffice

spring.mail.host=smtp.exmail.qq.com
spring.mail.username=mailtest@3vyd.com
spring.mail.password=xxx
spring.mail.default-encoding=UTF-8
spring.mail.error.subject=[ERROR] in project name
spring.mail.error.to=marvin.ma@3vyd.com,303764416@qq.com

多人时,邮箱之间用英文逗号分隔

logback文件

跟发送邮件相关的时这几句

    <!-- 邮件配置 -->
    <springProperty scope="context" name="smtpHost" source="spring.mail.host" />
    <springProperty scope="context" name="username" source="spring.mail.username" />
    <springProperty scope="context" name="password" source="spring.mail.password" />
    <springProperty scope="context" name="mailSubject" source="spring.mail.error.subject" />
    <springProperty scope="context" name="mailTo" source="spring.mail.error.to" />

    <appender name="MAIL" class="ch.qos.logback.classic.net.SMTPAppender">
        <smtpHost>$&#123;smtpHost&#125;</smtpHost>
        <smtpPort>25</smtpPort>
        <username>$&#123;username&#125;</username>
        <password>$&#123;password&#125;</password>
        <SSL>false</SSL>
        <asynchronousSending>true</asynchronousSending>
        <to>$&#123;mailTo&#125;</to>
        <from>$&#123;username&#125;</from>
        <subject>$&#123;mailSubject&#125;: %logger&#123;0&#125; </subject>
        <charsetEncoding>UTF-8</charsetEncoding>
        <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
            <!-- 每个电子邮件只发送一个日志条目 -->
            <bufferSize>1</bufferSize>
        </cyclicBufferTracker>
        <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

<logger name="com.hczt" level="INFO" additivity="false">
    <appender-ref ref="fileInfoLog" />
    <appender-ref ref="fileErrorLog" />
    <appender-ref ref="MAIL"/>
</logger>

在哪个级别或者包上需要将异常发送邮件,就appender上MAIL就可以了。

完整的logback-spring.xml文件

<configuration>
    <!-- application.properties 传递参数,不能使用logback自带的<property>标签 -->
    <springProperty scope="context" name="appname" source="logback.appname" />
    <springProperty scope="context" name="logdir" source="logback.logdir" />

    <contextName>$&#123;appname&#125;</contextName>
    
    <!-- 邮件配置 -->
    <springProperty scope="context" name="smtpHost" source="spring.mail.host" />
    <springProperty scope="context" name="username" source="spring.mail.username" />
    <springProperty scope="context" name="password" source="spring.mail.password" />
    <springProperty scope="context" name="mailSubject" source="spring.mail.error.subject" />
    <springProperty scope="context" name="mailTo" source="spring.mail.error.to" />

    <appender name="MAIL" class="ch.qos.logback.classic.net.SMTPAppender">
        <smtpHost>$&#123;smtpHost&#125;</smtpHost>
        <smtpPort>25</smtpPort>
        <username>$&#123;username&#125;</username>
        <password>$&#123;password&#125;</password>
        <SSL>false</SSL>
        <asynchronousSending>true</asynchronousSending>
        <to>$&#123;mailTo&#125;</to>
        <from>$&#123;username&#125;</from>
        <subject>$&#123;mailSubject&#125;: %logger&#123;0&#125; </subject>
        <charsetEncoding>UTF-8</charsetEncoding>
        <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
            <!-- 每个电子邮件只发送一个日志条目 -->
            <bufferSize>1</bufferSize>
        </cyclicBufferTracker>
        <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>


    <!-- 开发环境 全部输出到控制台-->
    <springProfile name="dev">
        <!-- 输出到控制台 -->
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d&#123;HH:mm:ss.SSS&#125; [%thread] %-5level %logger&#123;36&#125; - %msg%n</pattern>
            </layout>
        </appender>
        <!-- 指定最基础的日志输出级别 -->
        <root level="INFO">
            <appender-ref ref="STDOUT"/>
        </root>
    </springProfile>
    
    <!-- 测试环境+准生产环境+生产环境 输出到文件 -->
    <springProfile name="test,pre,prod">
        <!-- 输出到文件-info级别 -->
        <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 如果只是想要Info级别的日志,只是过滤info还是会输出Error日志,因为Error的级别高,使用filter,可以避免输出Error日志 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!--过滤 Error-->
                <level>ERROR</level>
                <!--匹配到就禁止-->
                <onMatch>DENY</onMatch>
                <!--没有匹配到就允许-->
                <onMismatch>ACCEPT</onMismatch>
            </filter>
            
            <!-- 日志名称,如果没有File属性,那么只会使用FileNamePattern的文件路径规则
                 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期
                 即,<File>的日志都是当天的
            -->
            <File>$&#123;logdir&#125;/info.$&#123;appname&#125;.log</File>
            
            <!-- 滚动策略,按照时间滚动 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 文件路径,定义了日志的切分方式
                     把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间
                -->
                <FileNamePattern>$&#123;logdir&#125;/info.$&#123;appname&#125;.%d&#123;yyyy-MM-dd&#125;.log</FileNamePattern>
            </rollingPolicy>
            
            <!-- 日志输出编码格式化 -->
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d&#123;yyyy-MM-dd HH:mm:ss.SSS&#125; %-5level %logger Line:%-3L [%X&#123;requestId&#125;] - %msg%n</pattern>
            </encoder>
        </appender>
        
        <!-- 输出到文件-error -->
        <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>Error</level>
            </filter>
            <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
                如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。
                即,<File> 的日志都是当天的。
            -->
            <File>$&#123;logdir&#125;/error.$&#123;appname&#125;.log</File>
            <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
                <FileNamePattern>$&#123;logdir&#125;/error.$&#123;appname&#125;.%d&#123;yyyy-MM-dd&#125;.log</FileNamePattern>
            </rollingPolicy>
            <!--日志输出编码格式化-->
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d&#123;yyyy-MM-dd HH:mm:ss.SSS&#125; %-5level %logger Line:%-3L [%X&#123;requestId&#125;] - %msg%n</pattern>
            </encoder>
        </appender>
        
        <appender name="sqlLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>$&#123;logdir&#125;/sql.$&#123;appname&#125;.log</File>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>$&#123;logdir&#125;/sql.$&#123;appname&#125;.%d&#123;yyyy-MM-dd&#125;.log</FileNamePattern>
                <!--只保留最近7天的日志-->
                <maxHistory>7</maxHistory>
            </rollingPolicy>
            <!--日志输出编码格式化-->
            <encoder>
                <charset>UTF-8</charset>
                <pattern>%d&#123;yyyy-MM-dd HH:mm:ss.SSS&#125; %-5level %logger Line:%-3L [%X&#123;requestId&#125;] - %msg%n</pattern>
            </encoder>
        </appender>

        <logger name="com.hczt" level="INFO" additivity="false">
            <appender-ref ref="fileInfoLog" />
            <appender-ref ref="fileErrorLog" />
            <appender-ref ref="MAIL"/>
        </logger>
        <logger name="com.haier" level="INFO" additivity="false">
            <appender-ref ref="fileInfoLog" />
            <appender-ref ref="fileErrorLog" />
            <appender-ref ref="MAIL"/>
        </logger>
        <logger name="org" level="ERROR" additivity="false">
            <appender-ref ref="fileErrorLog" />
            <appender-ref ref="MAIL"/>
        </logger>
        <logger name="p6spy" level="INFO" additivity="false">
            <appender-ref ref="sqlLog" />
        </logger>
        <root level="ERROR">
            <appender-ref ref="fileErrorLog" />
            <appender-ref ref="MAIL"/>
        </root>
    </springProfile>
</configuration>

附上截图
error

完美!!


评论
  目录