Spring Cloud + ELK分布式统一日志系统搭建
2020-02-24 / 大向

Spring Cloud + ELK分布式统一日志系统搭建

##ELK统一日志系统搭建

ELK是Elasticsearch、Logstash、Kibana的简称,这三者是核心套件,但并非全部。

Elasticsearch是实时全文搜索和分析引擎,提供搜集、分析、存储数据三大功能;是一套开放REST和JAVA API等结构提供高效搜索功能,可扩展的分布式系统。它构建于Apache Lucene搜索引擎库之上。

Logstash是一个用来搜集、分析、过滤日志的工具。它支持几乎任何类型的日志,包括系统日志、错误日志和自定义应用程序日志。它可以从许多来源接收日志,这些来源包括 syslog、消息传递(例如 RabbitMQ)和JMX,它能够以多种方式输出数据,包括电子邮件、websockets和Elasticsearch。

Kibana是一个基于Web的图形界面,用于搜索、分析和可视化存储在 Elasticsearch指标中的日志数据。它利用Elasticsearch的REST接口来检索数据,不仅允许用户创建他们自己的数据的定制仪表板视图,还允许他们以特殊的方式查询和过滤数据

注:ELK 一套用于数据搜集分析的工具集 ,可用于搜集分析mysql,nginx,tomcat等日志信息

环境搭建

安装Elasticsearch

安装Logstash
1、下载解压

[root@localhost ~]# wget https://artifacts.elastic.co/downloads/logstash/logstash-7.3.0.tar.gz
[root@localhost ~]# tar -zxvf logstash-7.3.0.tar.gz

2、要测试Logstash安装成功,运行最基本的Logstash管道。 执行以下的命令

[root@localhost ~]# /usr/local/logstash-7.3.0/bin/logstash -e 'input { stdin { } } output { stdout {} }'

-e标志使您可以直接从命令行指定配置。
通过在命令行指定配置,可以快速测试配置,而无需在迭代之间编辑文件。
示例中的管道从标准输入stdin获取输入,并以结构化格式将输入移动到标准输出stdout。
启动Logstash后,等到看到“Pipeline main started”,然后在命令提示符下输入hello world,显示的如下:

hello world
{
          "host" => "VM_0_13_centos",
       "message" => "hello world",
      "@version" => "1",
    "@timestamp" => 2019-07-02T06:26:28.684Z
}

3、配置logstash输出到elasticsearch
修改logstash的安装目录的config目录下的logstash-sample.conf文件

[root@localhost ~]# vim /usr/local/logstash-7.3.0/config/logstash-sample.conf

修改完配置如下:

input {
  beats {
    port => 5044
  }
  tcp {
    port => 4569
    codec => "json"
  }
}

output {
  if[appname] != "" {
    elasticsearch {
      hosts => ["http://192.168.0.123:9200"]
      index => "%{[appname]}-%{+YYYY.MM.dd}"
    }
  } else {
    elasticsearch {
      hosts => ["http://192.168.0.146:9200"]
      index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
    }
  }
}

beats为结合filebeat使用。
tcp为通过tcp协议的通道。注意codec为json格式。por为请求的端口号。
elasticsearch 为输出到elasticsearch ,也可以配置其他。更多详细见下面文档
配置详细解释
可以参考该logstash手册:https://doc.yonyoucloud.com/doc/logstash-best-practice-cn/get_start/hello_world.html

安装Kibana

kinaba是用来查看日志的安装在本地即可,下载kibana压缩包解压,点击运行kibana.bat文件即可运行

运行前需修改配置文件

# 访问端口
server.port: 5601
# es地址
elasticsearch.hosts: ["http://192.168.0.123:9200"]
# kibana 汉化
i18n.locale: "zh-CN"

使用kibana
http://localhost:5601/app/kibana#/home

可以先使用项目打印输出日志到elasticsearch后再来安装kibana查看效果

logstash结合filebeat使用

filebeat主要是从文件内读取日志信息,发送给logstash,

logstash结合filebeat
在分布式系统中,一台主机可能有多个应用,应用将日志输出到主机的指定目录,这时由logstash来搬运日志并解析日志,然后输出到elasticsearch上。由于于
logstash是java应用,解析日志是非的消耗cpu和内存,logstash安装在应用部署的机器上显得非常的笨重。最常见的做法是用filebeat部署在应用的机器上,logstash单独部署,然后由
filebeat将日志输出给logstash解析,解析完由logstash再传给elasticsearch。

SpringCloud + logstash结合logbak使用

引入pom依赖

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>5.2</version>
</dependency>

修改logback-spring.xml日志配置文件

<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <param name="Encoding" value="UTF-8"/>
    <!-- logstash服务器ip -->
    <remoteHost>192.168.0.123</remoteHost>
    <!-- logstash tcp 端口-->
    <port>4569</port>
    <!-- 日志输出编码 -->
    <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <timestamp><timeZone>UTC</timeZone></timestamp>
            <pattern>
                <pattern>
                 {
                     "severity": "%level",
                     "service": "${APP_NAME:-}",
                     "trace": "%X{X-B3-TraceId:-}",
                     "span": "%X{X-B3-SpanId:-}",
                     "exportable": "%X{X-Span-Export:-}",
                     "pid": "${PID:-}",
                     "thread": "%thread",
                     "class": "%logger{40}",
                     <!--"message": "%message",-->
                     "message": "%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{cname}:%X{cid},%X{uname}:%X{uid}]  %contextName [%thread] %-5level %logger{36} %L - %msg%n",
                     "appname":"springboot-logs"
                 }
                </pattern>
            </pattern>
            <stackTrace>
                <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                    <maxDepthPerThrowable>30</maxDepthPerThrowable>
                    <maxLength>2048</maxLength>
                    <!--<shortenedClassNameLength>20</shortenedClassNameLength>-->
                    <exclude>sun\.reflect\..*\.invoke.*</exclude>
                    <exclude>net\.sf\.cglib\.proxy\.MethodProxy\.invoke</exclude>
                    <!--<evaluator class="myorg.MyCustomEvaluator"/>-->
                    <rootCauseFirst>true</rootCauseFirst>
                </throwableConverter>
            </stackTrace>
        </providers>
    </encoder>
</appender>

其他配置信息可参考此网址:
https://github.com/logstash/logstash-logback-encoder/tree/logstash-logback-encoder-5.2

其中”appname”:”springboot-logs”对应logstash配置文件中的appname,为创建的索引名。
可以在Kibana索引管理中根据名称进行分区搜索。

kibana查看日志信息

查看日志需要先创建索引
创建索引步骤:管理》Kibana 索引模式》创建索引模式 》
使用Discover查看日志
Alt text

logstash获取日志,时间戳相差8小时

由于logstash在获取时区的时候,默认获取的是UTC默认时间,同时elasticsearch在创建索引的时候,统一使用UTC时间,因此实际上在创建索引的时候,会将今天实际时间的前8个小时的日志文件输出至昨天的索引中,因为中国使用的为东8时区,源数据和实际创建的索引数据会相差8个小时。
对于页面查看,ELK的解决方案是在kibana上,读取浏览器的当前时区,然后在页面上进行转换,显示时间内容。

1、修改string_interpolation.rb文件

vim /data/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-event-2.4.1-java/lib/logstash/string_interpolation.rb

将.withZone(org.joda.time.DateTimeZone::UTC)修改为.withZone(org.joda.time.DateTimeZone.getDefault())

2、修改timestamp的配置文件

vim  /data/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-event-2.4.1-java/lib/logstash/timestamp.rb

将@time = time.utc修改为@time = time

xxx
本文链接:https://chenylwork.gitee.io/2020/02/24/Spring%20Cloud%20+%20ELK%E5%88%86%E5%B8%83%E5%BC%8F%E7%BB%9F%E4%B8%80%E6%97%A5%E5%BF%97%E7%B3%BB%E7%BB%9F%E6%90%AD%E5%BB%BA/