【手记】基于SpringCloud搭建ELK分布式日志追踪

  • Post author:
  • Post category:其他




简介


  • ELK:

    是 Elasticsearch、Logstrash 和 Kibana 的缩写,它们代表的是一套成熟的日志管理系统,ELK Stack已经成为目前最流行的集中式日志解决管理方案。

  • Elasticsearch:

    分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通常被用作某些应用的基础搜索引擎,使其具有复杂的搜索功能;

  • Logstash:

    数据收集引擎。它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到用户指定的位置。

  • Kibana:

    数据分析和可视化平台。通常与 Elasticsearch 配合使用,对其中数据进行搜索、分析和以统计图表的方式展示。

  • Filebeat:

    ELK 协议栈的新成员,一个轻量级开源日志文件数据搜集器,性能优秀,基于 Logstash-Forwarder 源代码开发(基于Java开发,解析日志耗费性能)是对它的替代。在需要采集日志数据的服务上安装 Filebeat,并指定日志目录或日志文件后,Filebeat就能读取日志文件数据,迅速发送到 Logstash进行解析,或直接发送到 Elasticsearch进行集中式存储和分析。



使用版本(基于Linux搭建)



Elasticsearch 搭建



下载

 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.0-linux-x86_64.tar.gz



解压

tar -zxvf elasticsearch-7.3.0-linux-x86_64.tar.gz



创建 elsearch 组并给新创建用户文件夹执行权限


重点:这里必须搞个用户,root用户无法运行的,并且ES自带的环境变量ES_HOME 目录就是该用户的文件目录

groupadd elsearch
useradd  elsearch(用户名) -g elsearch(组名) -p elsearch(密码)
chown -R elsearch:elsearch /home/elsearch/elasticsearch-7.3.0



修改Elasticsearch 的配置文件

cd /home/elsearch/elasticsearch-7.3.0/config
vim elasticsearch.yml


官方自带的配置文件都是注释的,故我们自行在末尾自行添加一下配置就OK。

# 如果需要部署集群,集群需要同样的集群名
 cluster.name: my-es-application
#
# # 每个 node 的名字需要唯一
 node.name: node-1
#
# # 注意一定要是路径后面加上/var/lib/elasticsearch/nodes,要不然无法加入集群,单机不需要
# # path.data: /var/lib/elasticsearch/nodes
# # path.logs: /var/log/elasticsearch
#
# # 配置服务器的内网地址,有文档配置的 0.0.0.0 或 localhost,但是后面出现了问题,暂未研究什么原因
 network.host: 192.168.1.239
#
# # 配置端口号,默认 9200
 http.port: 9200
#
# # 配置集群节点,多个服务器["node-1", "node-2"]
 cluster.initial_master_nodes: ["node-1"]
 # # 配置集群的主机和端口地址
# # discovery.seed_hosts: ["192.168.0.146", "192.168.0.147", "192.168.0.148"]
#
# # 解决跨域 
 http.cors.enabled: true

这里是单实例Elasticsearch,如果要搭建集群,

请参考



启动

 # 刷新环境变量
 echo "export ES_HOME=/home/elsearch/elasticsearch-7.3.0" >> .bashrc
 echo "export PATH=$ES_HOME/bin:$PATH" >> .bashrc
 # 如果解压的包不在/home/elsearch/下面,需要拿过来
 # 切换用户
 su elsearch
 cd elasticsearch-7.3.0/bin/
 sh elasticsearch &

在这里插入图片描述


如果出现启动失败,排查下内存是否足够,是否是root启动,是否文件句柄数足够,是否堆栈虚拟内存是否足够,具体修改方式,一捞一大把。



访问

!](https://img-blog.csdnimg.cn/fc71bb922dfb4467978bb338fb847fb9.png)



可视化界面-head(老古董)


注意:安装 head 需要安装 node 和 npm 下载地址:https://github.com/mobz/elasticsearch-head.git 下载后执行:

# 安装 module
npm install
# 运行 head 插件
npm run start

在网页上访问http://192.168.0.158:9100/ 得到以下界面,(我的以下界面,已经添加了日志)

导图一张:

在这里插入图片描述



可视化界面-klibana(新玩意)

至此,ES搭建成功,下面重点讲如何部署这个klibana



klibana搭建



下载以及解压

cd /home/elsearch
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.3.0-linux-x86_64.tar.gz
tar -zxvf kibana-7.3.0-linux-x86_64.tar.gz



修改配置文件

cd kibana-7.3.0/config/
vim kibana.yml


配置文件修改如下

# 端口
server.port: 5601
# 指定本机 ip 让外部能访问
server.host: "0.0.0.0"
# 请求数据指向的 elasticsearch 服务器
elasticsearch.hosts: ["http://192.168.1.258:9200"]



启动

在其安装的bin目录下执行

# nohup保证后台运行,如果直接运行脚本,界面退出后,会自动退出
nohup ./kibana --allow-root > kibana.log 2>&1


日志如下


在这里插入图片描述

访问 http://192.168.0.258:5601, 得到以下页面,代表启动成功。


在这里插入图片描述


索引列表


在这里插入图片描述


自定义索引模式


在这里插入图片描述


查看日志


在这里插入图片描述


具体操作细节,一捞一大把,这里不一一阐述了 下面继续来搞日志追踪



logstash 搭建



下载以及解压

cd /home/elsearch
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.3.0.tar.gz
tar -zxvf logstash-7.3.0.tar.gz
  • stash 第一个事件


    Logstash 管道有两个必需元素,输入和输出,以及一个可选元素 filter。输入插件使用来自源的数据,过滤器插件在您指定时修改数据,输出插件将数据写入目标。


    要测试 Logstash 安装成功,运行最基本的 Logstash 管道。执行以下的命令
 bin/logstash -e 'input { stdin { } } output { stdout {} }'

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


如图代表测试成功


在这里插入图片描述



修改配置文件

  • 配置 logstash 输出到 elasticsearch
cd logstash-7.3.0/config/
vim logstash-sample.conf
  • 完整的配置文件如下
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
  beats {
    port => 5044
  }
  #日志文件配置地址
  tcp  {
    port => 4569
    codec => "json"
  }
}
# 分析、过滤插件,可以多个
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}"}
    }
    geoip {
        source => "clientip"
    }
}

output {
  elasticsearch {
    hosts => ["http://192.168.1.258:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
    #user => "elastic"
    #password => "changeme"
  }
}

更多配置

参照官网教程:


其中:

  • beats 为结合 filebeat 使用。
  • tcp 为通过 tcp 协议的通道。注意 codec 为 json 格式。por 为请求的端口号。
  • elasticsearch 为输出到 elasticsearch ,也可以配置其他。更多详细见下面文档 配置详细解释 可以参考 :


    logstash 手册



启动

# 在其安装的bin目录下执行
# 配置文件和启动项放在同一目录,习惯管理
mv ../conf/logstash-sample.conf logstash-sample.conf
# 保证后台运行
nohup ./logstash -f logstash-sample.conf  > runlogstash.log 2>&1 &


如图代表启动成


在这里插入图片描述



filebeat搭建



目的

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



下载以及解压

cd /home/elsearch
wget  https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.0-linux-x86_64.tar.gz
tar -zxvf filebeat-7.3.0-linux-x86_64.tar.gz



修改配置文件

cd /filebeat-7.3.0-linux-x86_64/
vim filebeat.yml


配置文件修改如下

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
     # 当前目录下的所有.log文件
    - /home/elearning/jar/logs/*.log
    #- c:\programdata\elasticsearch\logs\*
  multiline.pattern: ^\[
  multiline.negate: true
  multiline.match: after
  
  # 日志配置方式
- type: tcp
  enabled: true
  max_message_size: 10MiB
  host: "0.0.0.0:9000"
#============================= Filebeat modules ===============================

filebeat.config.modules:
  # Glob pattern for configuration loading
  path: ${path.config}/modules.d/*.yml

  # Set to true to enable config reloading
  reload.enabled: false

  # Period on which files under path should be checked for changes
  #reload.period: 10s

#==================== Elasticsearch template setting ==========================

setup.template.settings:
  index.number_of_shards: 1
  #index.codec: best_compression
  #_source.enabled: false

#----------------------------- Logstash output --------------------------------
output.logstash:
  # The Logstash hosts
  hosts: ["192.168.1.258:5044"]

processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~


格式一定要对齐。



启动

在其安装的目录下执行

# nohup保证后台运行,如果直接运行脚本,界面退出后,会自动退出
nohup ./filebeat -e >filebeat.log 2>&1 &


启动成功日志如下


在这里插入图片描述


推送日志到logstash截图如下


在这里插入图片描述


回头看klibana是否回显日志


在这里插入图片描述


我的日志目前已经在测试环境上,接下来看springcloud结合log4j整合filebeat



SpringCloud + filebeat结合 log4j 使用

  • 废话不多说,上核心依赖
 		<!-- Logstash -->
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
        </dependency>
  • 日志xml核心配置
<!-- 环境变量ELK_MODE=true 启动elk日志推送 -->
<if condition='property("ELK_MODE").toUpperCase().contains("TRUE")'>
        <then>
            <!-- 推送日志至elk -->
            <appender name="STDOUT_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
            	 <!-- DESTINATION 就是我们的地址filebeat地址192.168.1.258:9000 -->
                <destination>${DESTINATION}</destination>
                <!-- 日志输出编码 -->
                <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                    <providers>
                        <timestamp>
                            <timeZone>UTC</timeZone>
                        </timestamp>
                        <pattern>
                            <pattern>
                                {
                                "traceId": "%X{traceId}",
                                "logLevel": "%level",
                                "serviceName": "${springAppName:-SpringApp}",
                                "pid": "${PID:-}",
                                "thread": "%thread",
                                "class": "%logger{40}",
                                "line":"%L",
                                "message": "%message"
                                }
                            </pattern>
                        </pattern>
                    </providers>
                </encoder>
            </appender>
        </then>
          <!-- 或者 logstash 设置 -->
  <!--  <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <param name="Encoding" value="UTF-8"/>
        &lt;!&ndash; logstash 服务器 ip &ndash;&gt;
        <remoteHost>127.0.0.1</remoteHost>
        &lt;!&ndash; logstash tcp 端口&ndash;&gt;
        <port>4569</port>
        &lt;!&ndash; <filter class="com.program.interceptor.ELKFilter >//引入过滤类"/>
        Zencoder is required  &ndash;&gt;
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
          &lt;!&ndash;  <customFields>{"appname":"ceshi"}</customFields>&ndash;&gt;
        </encoder>
    </appender>-->
       </if>
            <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="${STDOUT_APPENDER}"/>
    </root>
  • 日志核心启动类
public class LoggerStartupListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {

	@Override
	public void start() {
		//获取日志组件上下文,并对其动态赋值
		Context context = getContext();
		context.putProperty("ELK_MODE", "FALSE");
		context.putProperty("STDOUT_APPENDER", "STDOUT");
		context.putProperty("INFO_APPENDER", "INFO");
		context.putProperty("ERROR_APPENDER", "ERROR");
		context.putProperty("DESTINATION", "127.0.0.1:9000");
		// 环境变量配置的filebeat/logstash地址 192.168.1.258:9000
		//ElkPropsUtil 获取环境变量工具类,大家自行封装就好
		String destination = ElkPropsUtil.getDestination();
		if (StringUtil.isNotBlank(destination)) {
			context.putProperty("ELK_MODE", "TRUE");
			context.putProperty("STDOUT_APPENDER", "STDOUT_LOGSTASH");
			context.putProperty("INFO_APPENDER", "INFO_LOGSTASH");
			context.putProperty("ERROR_APPENDER", "ERROR_LOGSTASH");
			context.putProperty("DESTINATION", destination);
		}
	}



小结:


至此整合完毕,这里只是简单的介绍了 ELK 的基础安装使用,更多的高级功能,还需要小伙伴自己去玩。如果有什么问题,欢迎留言讨论。



版权声明:本文为NICVSY原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。