SpringBoot项目接入阿里云SLS日志并配置监控告警

一、前言

关于日志平台的选型请看juejin.cn/post/739433... ,此篇记录下SpringBoot项目接入阿里云SLS以及配置相应的业务监控。

二、日志接入

首先需要到阿里云官网开通SLS日志服务并建立project, 建好projet后根据我们需要的环境数量建立logstore

值得注意的一点是,日志保存时间可以选短一点,根据需求权衡,一般7天足够了,默认是30天。

当服务开通并建好各项配置后,开始着手项目配置这块,此处日志采集使用Aliyun Log Logback Appender,官网还支持如log4j2其他方式,按自己项目实际情况引入对应依赖即可,此处多引入了Sleuth,方便把TraceId也打印到日志中。

xml 复制代码
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>aliyun-log-logback-appender</artifactId>
    <version>0.1.18</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

依赖版本应该会升级,最新版本参照官方GitHub配置github.com/aliyun/aliy...

在项目resource目录下建立logback-spring.xml文件,下面是参照官方logback.xml修改后的多环境配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--为了防止进程退出时,内存中的数据丢失,请加上此选项-->
    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>


        <!-- 测试环境error日志 -->
        <appender name="log-error-test" class="com.aliyun.openservices.log.logback.LoghubAppender">
            <!--必选项-->
            <!-- 账号及网络配置 -->
            <endpoint>cn-hangzhou.log.aliyuncs.com</endpoint>
            <accessKeyId>阿里云keyId</accessKeyId>
            <accessKeySecret>阿里云Secret</accessKeySecret>

            <!-- sls 项目配置 -->
            <project>sls控制台中建的项目名称</project>
            <logStore>sls控制台中建立的logStore名称</logStore>
            <!--必选项 (end)-->

            <!-- 可选项 -->
            <!--        <topic>topic1</topic>-->
            <!--        <source>source1</source>-->

            <!-- 可选项 详见 '参数说明'-->
            <totalSizeInBytes>104857600</totalSizeInBytes>
            <maxBlockMs>60000</maxBlockMs>
            <ioThreadCount>8</ioThreadCount>
            <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
            <batchCountThreshold>4096</batchCountThreshold>
            <lingerMs>2000</lingerMs>
            <retries>10</retries>
            <baseRetryBackoffMs>100</baseRetryBackoffMs>
            <maxRetryBackoffMs>100</maxRetryBackoffMs>

            <filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 打印WARN,ERROR级别的日志 -->
                <level>WARN</level>
            </filter>

            <mdcFields>THREAD_ID,MDC_KEY</mdcFields>
        </appender>

        <!-- 测试环境debug日志 -->
        <appender name="log-debug-test" class="com.aliyun.openservices.log.logback.LoghubAppender">
            <!--必选项-->
            <!-- 账号及网络配置 -->
            <endpoint>cn-hangzhou.log.aliyuncs.com</endpoint>
            <accessKeyId>xxx</accessKeyId>
            <accessKeySecret>xxx</accessKeySecret>

            <!-- sls 项目配置 -->
            <project>xxx</project>
            <logStore>xxx</logStore>
            <!--必选项 (end)-->

            <!-- 可选项 -->
            <!--        <topic>topic2</topic>-->
            <!--        <source>source2</source>-->

            <!-- 可选项 详见 '参数说明'-->
            <totalSizeInBytes>104857600</totalSizeInBytes>
            <maxBlockMs>0</maxBlockMs>
            <ioThreadCount>8</ioThreadCount>
            <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
            <batchCountThreshold>4096</batchCountThreshold>
            <lingerMs>2000</lingerMs>
            <retries>10</retries>
            <baseRetryBackoffMs>100</baseRetryBackoffMs>
            <maxRetryBackoffMs>50000</maxRetryBackoffMs>

            <!-- 可选项 通过配置 encoder 的 pattern 自定义 log 的格式 -->
            <encoder>
                <pattern>%d %-5level [%thread] [%X{traceId},%X{spanId}] %logger{0}: %msg</pattern>
            </encoder>

            <!-- 可选项 设置时间格式 -->
            <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
            <!-- 可选项 设置时区 -->
            <timeZone>Asia/Shanghai</timeZone>


            <mdcFields>THREAD_ID,MDC_KEY</mdcFields>
        </appender>


    <!-- 正式环境error日志 -->
    <appender name="log-error-prod" class="com.aliyun.openservices.log.logback.LoghubAppender">
        <!--必选项-->
        <!-- 账号及网络配置 -->
        <endpoint>cn-hangzhou.log.aliyuncs.com</endpoint>
        <accessKeyId>xxx</accessKeyId>
        <accessKeySecret>xxx</accessKeySecret>


        <!-- sls 项目配置 -->
        <project>xxx-project</project>
        <logStore>xxx-error-prod</logStore>
        <!--必选项 (end)-->

        <!-- 可选项 -->
        <!--        <topic>topic1</topic>-->
        <!--        <source>source1</source>-->

        <!-- 可选项 详见 '参数说明'-->
        <totalSizeInBytes>104857600</totalSizeInBytes>
        <maxBlockMs>60000</maxBlockMs>
        <ioThreadCount>8</ioThreadCount>
        <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
        <batchCountThreshold>4096</batchCountThreshold>
        <lingerMs>2000</lingerMs>
        <retries>10</retries>
        <baseRetryBackoffMs>100</baseRetryBackoffMs>
        <maxRetryBackoffMs>100</maxRetryBackoffMs>

        <encoder>
            <pattern>%d %-5level [%X{clientIp}] [%thread] [%X{traceId},%X{spanId}] %logger{0}: %msg</pattern>
        </encoder>

        <!-- 可选项 设置时间格式 -->
        <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
        <!-- 可选项 设置时区 -->
        <timeZone>Asia/Shanghai</timeZone>

        <filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 打印WARN,ERROR级别的日志 -->
            <level>WARN</level>
        </filter>

        <mdcFields>THREAD_ID,MDC_KEY</mdcFields>
    </appender>
    <!-- 正式环境debug日志 -->
    <appender name="log-debug-prod" class="com.aliyun.openservices.log.logback.LoghubAppender">
        <!--必选项-->
        <!-- 账号及网络配置 -->
        <endpoint>cn-hangzhou.log.aliyuncs.com</endpoint>
        <accessKeyId>xxx</accessKeyId>
        <accessKeySecret>xxx</accessKeySecret>

        <!-- sls 项目配置 -->
        <project>xxx-project</project>
        <logStore>xxx-debug-prod</logStore>
        <!--必选项 (end)-->

        <!-- 可选项 -->
        <!--        <topic>topic2</topic>-->
        <!--        <source>source2</source>-->

        <!-- 可选项 详见 '参数说明'-->
        <totalSizeInBytes>104857600</totalSizeInBytes>
        <maxBlockMs>60000</maxBlockMs>
        <ioThreadCount>8</ioThreadCount>
        <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
        <batchCountThreshold>4096</batchCountThreshold>
        <lingerMs>2000</lingerMs>
        <retries>10</retries>
        <baseRetryBackoffMs>100</baseRetryBackoffMs>
        <maxRetryBackoffMs>50000</maxRetryBackoffMs>

        <!-- 可选项 通过配置 encoder 的 pattern 自定义 log 的格式 -->
        <encoder>
            <pattern>%d %-5level [%X{clientIp}] [%thread] [%X{traceId},%X{spanId}] %logger{0}: %msg</pattern>
        </encoder>

        <!-- 可选项 设置时间格式 -->
        <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
        <!-- 可选项 设置时区 -->
        <timeZone>Asia/Shanghai</timeZone>


        <mdcFields>THREAD_ID,MDC_KEY</mdcFields>
    </appender>


    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 编码器的类型是ch.qos.logback.classic.encoder.PatternLayoutEncoder默认情况下 -->
        <encoder>
            <pattern>[ %-5level] [%X{clientIp}] [%thread] [%date{yyyy-MM-dd HH:mm:ss}] [%X{traceId},%X{spanId}] %logger{96} [%line] -
                %msg%n
            </pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
    </appender>


    <!-- 可用来获取StatusManager中的状态 -->
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>


    <!-- 解决debug模式下循环发送的问题 -->
    <logger name="org.apache.http.impl.conn.Wire" level="WARN"/>


    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <!-- 测试环境 -->
        <springProfile name="test">
            <appender-ref ref="log-debug-test"/>
            <appender-ref ref="log-error-test"/>
        </springProfile>
        <!-- 预发环境 -->
<!--        <springProfile name="release">-->
<!--            <appender-ref ref="log-debug-test"/>-->
<!--            <appender-ref ref="log-error-test"/>-->
<!--        </springProfile>-->
        <!-- 正式环境 -->
        <springProfile name="prod">
            <appender-ref ref="log-error-prod"/>
            <appender-ref ref="log-debug-prod"/>
        </springProfile>
    </root>


    <logger name="heartbeat" level="ERROR"/>
    <logger name="timer" level="ERROR"/>
    <logger name="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor" level="ERROR"/>
    <logger name="org.elasticsearch.client.RestClient" level="ERROR"/>
</configuration>

上面配置了test和prod两个环境,项目会根据我们启动时指定生效的环境执行相应的appender, project配置项可以使用同一个(sls收费中也会按project数量来算,所以尽量共用一个),logStore配置项不同的环境为了不同日志级别隔离开需要配置不一样。

当项目配置完成以后,启动项目。需要建立日志索引才能进行日志搜索查询操作,需要到sls控制台中点击对应环境logstore,点击开启索引

默认选择的是全文索引,如果日志中有中文,需要把包含中文开启,不然会出现中文无法精确搜索情况。 确认以后等待两到三分钟,就可以在控制台看到近实时的日志并搜索查询了。

三、配置业务监控告警

到现在我们已经配置好了日志采集和查询,而我们做这项工作的目的一方面是为了在业务出现问题后能快速排查,另一方面我们可以在业务出现问题时第一时间收到通知,sls提供了告警功能,在命中我们指定的规则日志以后,可以马上通过多种方式如短信,电话,钉钉机器人方式告知指定人员。

点击告警模块。

点击新建告警。

核心需要配置检查频率,查询统计规则,输出目标。 查询统计中可参考对应语法,比如下面为查询error关键字并忽略一下不重要的错误。

接下来配置通知策略,点击sls通知方式,新增行动策略。

此处通知方式选择钉钉。

新增Webhook集成。

配置完成后可手动在项目打一些错误日志测试告警规则是否触发成功。

此处点击查看详情可直接跳到对应报错日志界面。

四、注意点

如果项目流量比较大,尽量减少不必要的日志打印,最好是只有核心交易接口打,像一些触发比较频繁的业务异常, 热点查询接口,异常抛到前台就行了,日志一行都别打,避免造成不必要的高额日志存储费用,索引费用,在logsotre建立索引时,可以关闭默认全文索引,自己指定重要字段索引。

五、结论

以上记录了阿里云SLS日志服务的一些使用经验,希望能给有需要的小伙伴一点启发。

最后

① 感谢阅读~

② 如果对于文中所持观点有不同的看法,欢迎大佬指点,交流~

相关推荐
qq_17448285756 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍7 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦7 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727577 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦7 小时前
Scala中的集合复习(1)
开发语言·后端·scala
代码小鑫8 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖8 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶8 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
uzong9 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
飞升不如收破烂~10 小时前
Spring boot常用注解和作用
java·spring boot·后端