Springboot常用于spring-cloud中,大家在使用spring-cloud多服务的时候常常会存在一个问题,就是某个服务报错了,去捞日志的时候要一个一个服务去监控或者捞日志排查错误信息,这样很耗时耗力,Elasticsearch查询数据非常方便,如果能够将日志保存到Elasticsearch中,出现问题时根据相关关键字和时间对查询日志会节省大量时间,通过Kibana或者head插件通过浏览器查询,不需要登录到服务端,操作简单方便,本文实现了springboot+log4j2+ELK(Elasticsearch+Logstash+Kibana)将日志集成到Elasticsearch中,ELK如何安装部署可以参考作者之前的文章:

ELK(Elasticsearch+Logstash+Kibana)安装、使用_醉酒横刀的博客-CSDN博客

1、Springboot搭建

        sprignboot搭建大家可以在网上找到很多例子,此处不再赘述。

2、Springboot集成log4j2

        集成log4j需要以下几个步骤

        1)引入pom依赖

        需要将starter和stater-web中引入的log包排除,再引入log4j2依赖包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.1.5.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.5.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>

        2)配置文件修改

        在appliction.yml中新增如下配置

logging:

  config: classpath:log4j2.xml
  level:
    com:
      test: debug

        2)配置文件修改

        log4j2.xml配置文件中内容

<?xml version="1.0" encoding="UTF-8"?>
<!--      Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
     当设置成trace时,可以看到log4j2内部各种详细输出
-->
<!-- monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数 -->
<configuration monitorInterval="5">
    <!-- 日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!-- 变量配置 -->
    <Properties>
        <!--
            格式化输出:
            %d表示日期,
            %thread表示线程名,
            %-5level:级别从左显示5个字符宽度
            %msg:日志消息,%n是换行符
            %logger{36} 表示 Logger 名字最长36个字符
        -->
        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level}[%thread] %style{%logger{36}}{cyan} : %msg%n" />

        <!-- 定义日志存储的路径,不要配置相对路径 -->
        <property name="FILE_PATH" value="./logs" />
        <!-- 服务名 -->
        <property name="FILE_NAME" value="order-service" />
    </Properties>

    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/>
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>

        <!--
          这个会打印出所有的info及以下级别的信息,每次大小超过size,
          则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档
        -->
        <RollingFile name="RollingFileInfo"
                     fileName="${FILE_PATH}/info.log"
                     filePattern="${FILE_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-INFO_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖 -->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn"
                     fileName="${FILE_PATH}/warn.log"
                     filePattern="${FILE_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-WARN_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError"
                     fileName="${FILE_PATH}/error.log"
                     filePattern="${FILE_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd_HH}-ERROR_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>
        <Socket name="logstash" host="192.168.36.129" port="4560" protocol="TCP">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Socket>
    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="top.fate" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="logstash"/>
        </root>
    </loggers>
</configuration>

3、logstash配置修改及启动

         1)配置文件修改

                在logstash的bin目录新建spring-boot-logstash.yml文件,具体内容如下

                /logstash-7.11.0/config/spring-boot-logstash.yml

                注意修改ip地址和端口号,output中的index会根据配置的命名规则自动创建

                

input {
  tcp {
    #模式选择为server
    mode => "server"
    #ip和端口根据自己情况填写,端口默认4560,对应下文logback.xml里appender中的destination
    host => "192.168.36.129"
    port => 4560
    #格式json
    codec => json_lines
  }
}
filter {
  #过滤器,根据需要填写
}
output {
  elasticsearch {
    action => "index"
    #这里填写es的地址,多个es要写成数组的形式
    hosts  => ["192.168.36.129:9200","192.168.36.130:9200","192.168.36.130:9200"]
    #存放的索引名称,这里每天会创建一个新的索引保存当天的日志
    index => "springfate-log-%{+YYYY.MM.dd}"
  }
}

         2)logstash启动

       切换到bin目录下进行启动, 启动命令:

        cd ../logstash/bin

./logstash -f /opt/ELK7.11.0/logstash-7.11.0/config/spring-boot-logstash.yml

        启动成功后日志如下图:

        

 

4、log4j2连接logstash

        log4j2连接logstash需要在log4j2.xml中配置如下图所示即可,具体配置在上面的配置中有

 

5、Kibana查询日志数据

        启动springboot项目,启动Elasticsearch、Logstash、Kibana,防火墙关闭或者开放相应端口

之后可以监控logstash的日志发现springboot的日志会抽取到es中

       1)spring启动日志

        我在springboot打印日志,每隔20秒打印一次日志

        2)logstash抽取数据日志

        在logstah日志中可以监测到日志抽取,(我这边日志json格式转换有问题,还未解决)

 

        3)Kibana查看Elasticsearh中新建的index

        在kibana中可以看到以日期为单位新建的索引,日志在里面

 

        4)Kibana查询日志数据

        登录Kibana

 按照之前新建的查询规则进行搜索可以搜索出相关日志新星

至此,springboot+log4j2+ELK(Elasticsearch+Logstash+Kibana)简单整合已完成。

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐