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日志服务的一些使用经验,希望能给有需要的小伙伴一点启发。

最后

① 感谢阅读~

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

相关推荐
程序员爱钓鱼1 小时前
Go语言实战案例-创建模型并自动迁移
后端·google·go
javachen__1 小时前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql
uzong6 小时前
技术故障复盘模版
后端
GetcharZp7 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程7 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研7 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi8 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国9 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy9 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
喂完待续9 小时前
Apache Hudi:数据湖的实时革命
大数据·数据仓库·分布式·架构·apache·数据库架构