Springboot(五十五)SpringBoot整合ELK实现日志可视化

222 阅读3分钟

首先我们先来解析一下,什么是ELK:E:elasticsearch、L:logstash、K:kibana

 

关于他们的部署,请移步

docker(十五)docker-compose部署elasticsearch配置账号密码登录

要先部署elasticsearch,在部署logstash,部署logstash需要用到es的账号和密码。

docker(二十一)docker部署logstash

再部署kibana

docker(二十二)docker部署kibana

这里需要注意一下,ELK的版本需要一致,我这里使用的事7.17.3版本。

 

ELK部署完成之后,下边我记录一下我在Springboot框架中集成的全过程。

 

Springboot框架默认集成logback作为默认的日志框架,具体请移步《SpringBoot(三)集成日志

 

一:添加POM依赖

<!-- 向logstash推送日志数据-->
<!-- https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder -->
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.5</version>
</dependency>
<!-- Logback Classic Module -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>

 

这里需要注意一下,logstash-logback-encoder确保使用的是与Logstash服务器兼容的版本。

 

二:yml配置

spring:
  elasticsearch:
    ip: 127.0.0.1
    port: 9200
    protocol: http
    username: xxxxxx
password: xxxxxx

 

这里只需要配置elasticsearch就可以。我的es是有用户名密码的,如果你的es没有,那就不需要。

 

三:创建logstash.xml配置文件

文件位置在resource目录下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--======================================= 本地变量 ======================================== -->
    <!--在没有定义${LOG_HOME}系统变量的时候,可以设置此本地变量。提交测试、上线时,要将其注释掉,使用系统变量。 -->
    <!-- <property name="LOG_HOME" value="D:/data/logs" /> -->

    <!-- 引入spirng boot默认的logback配置文件 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 应用名称:和统一配置中的项目代码保持一致(小写) -->
    <property name="APP_NAME" value="base" />
    <!--日志文件保留天数 -->
    <property name="LOG_MAX_HISTORY" value="180" />
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
    <!--应用日志文件保存路径 -->
    <!--<property name="LOG_APP_HOME" value="${catalina.home}/${APP_NAME}/app" />-->

    <!-- 控制台彩色输出  -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} - %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--logback输出到logstash-->
    <appender name="STASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>39.99.144.212:5044</destination>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <!--打印行号、方法名,官方不建议在生产环境开启此配置,默认为fa1s(关闭),具网友测试开启后的耗时是未开启的大约360倍的时间(业务量小的 -->
            <includeCallerData>true</includeCallerData>
            <!--   设置时区  -->
            <timeZone>UTC</timeZone>
            <!--日期格式化-->
            <!--<timestampPattern>yyyy-MM-dd'T'HH:mm:ss.SSS</timestampPattern>-->
            <!-- 添加自定义属性,这里的server_name.是服务名-->
            <customFields>{"server_name":"server-bcd"}</customFields>
        </encoder>

        <!-- 此日志文件只记录error级别的 -->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>-->
    </appender>

    <!--=========================== 按照每天生成日志文件:默认配置=================================== -->
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
<!--    &lt;!&ndash; 按照每天生成日志文件:主项目日志 &ndash;&gt;-->
<!--    <appender name="APP"-->
<!--              class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!--        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!--            &lt;!&ndash;日志文件输出的文件名 &ndash;&gt;-->
<!--            <FileNamePattern>${LOG_APP_HOME}/base.%d{yyyy-MM-dd}.log-->
<!--            </FileNamePattern>-->
<!--            &lt;!&ndash;日志文件保留天数 &ndash;&gt;-->
<!--            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>-->
<!--        </rollingPolicy>-->
<!--        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">-->
<!--            &lt;!&ndash;格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 &ndash;&gt;-->
<!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{500} - %msg%n</pattern>-->
<!--        </encoder>-->
<!--    </appender>-->
<!--    &lt;!&ndash; SENTINEL日志 &ndash;&gt;-->
<!--    <appender name="SENTINEL" class="ch.qos.logback.core.FileAppender">-->
<!--        <file>./sentinel-logs/%d{yyyy-MM-dd}.log</file>-->
<!--        <encoder>-->
<!--            <pattern>%date [%thread] %-5level %logger{50} - %msg%n</pattern>-->
<!--        </encoder>-->
<!--    </appender>-->
    <!--=============================== 定义各个框架的输出级别 ====================================== -->
    <logger name="org.springframework">
        <level value="WARN" />
    </logger>
    <logger name="org.apache.shiro">
        <level value="WARN" />
    </logger>
    <logger name="freemarker">
        <level value="WARN" />
    </logger>
    <logger name="org.hibernate">
        <level value="WARN" />
    </logger>
    <logger name="org.hibernate.SQL">
        <level value="DEBUG" />
    </logger>
<!--    <logger name="com.alibaba.csp.sentinel.log.sentinel.SentinelLog" level="INFO" additivity="false">-->
<!--        <appender-ref ref="SENTINEL"/>-->
<!--    </logger>-->

    <!-- 本地开发可以使用DEBUG  线上生产环境建议修改成INFO   -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="STASH"/>
<!--        <appender-ref ref="APP" />-->
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

 

这里需要注意一下,将文件中“你的ip”换成你服务器的ip,并且端口号5044要与Logstash服务器配置的监听端口一致。

 

四:logstash控制台

到这里,Springboot就配置完成了,启动项目。打开logstash控制台,发现如下输出:

[2023-12-10T12:23:02,915][ERROR][logstash.outputs.elasticsearch][main] Failed to install template {:message=>"Got response code '400' contacting Elasticsearch at URL 'http://39.99.144.212:9200/_template/application-log'":exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError:backtrace=>["/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb:84:in `perform_request'""/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/pool.rb:324:in `perform_request_to_url'""/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/pool.rb:311:in `block in perform_request'""/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/pool.rb:398:in `with_connection'""/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/pool.rb:310:in `perform_request'",
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client/pool.rb:318:in `block in Pool'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client.rb:408:in `template_put'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/http_client.rb:85:in `template_install'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/template_manager.rb:29:in `install'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch/template_manager.rb:17:in `install_template'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch.rb:494:in `install_template'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch.rb:318:in `finish_register'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/outputs/elasticsearch.rb:283:in `block in register'", 
 "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-11.4.1-java/lib/logstash/plugin_mixins/elasticsearch/common.rb:149:in `block in after_successful_connection'"]}

 

信息显示,在elasticsearch中创建索引模板失败。这里如果代码创建不成,就需要在kibana中手动进行创建。

 

五:配置kibana

按照上边的配置,启动项目,应该就能在kibana中看到对应日期的日志索引,如下图所示:

1.jpg

Logstash控制台报创建索引模板失败。接下来我来手动创建索引模板。

流程如下图所示:

这两步一定要操作,要跟我上图中显示的大概一致。

4.jpg

5.jpg

6.jpg

*这里需要注意一下,创建索引模式的名称要和已经存在的索引能匹配上,如上图所示,表示匹配后边任意字符。

创建成功如下图所示:

7.jpg

 

接下来我们去查看项目日志,如下图所示:

8.jpg

9.jpg

 

至此,Springboot集成ELK实现日志可视化就完成了。

 

有好的建议,请在下方输入你的评论。