ELK 日志采集系统搭建

JavaFamily

共 8048字,需浏览 17分钟

 · 2021-08-19

 ELK是Elasticsearch+Logstash+Kibana简称。


      一般我们需要进行日志分析场景:直接在日志文件中 grep、awk 就可以获得自己想要的信息。但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。需要集中化的日志管理,所有服务器上的日志收集汇总。

      常见解决思路是建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。一般大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。ELK提供了一整套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用。目前主流的一种日志系统。

1. 架构

ELK是Elasticsearch+Logstash+Kibana简称.

  • Elasticsearch 是一个分布式的搜索和分析引擎,可以用于全文检索、结构化检索和分析,并能将这三者结合起来。Elasticsearch 基于 Lucene 开发,现在是使用最广的开源搜索引擎之一。

  • Logstash 简单来说就是一根具备实时数据传输能力的管道,负责将数据信息从管道的输入端传输到管道的输出端,与此同时这根管道还可以让你根据自己的需求在中间加上滤网,Logstash提供了很多功能强大的滤网以满足你的各种应用场景。

  • Kibana 是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看、交互存放在Elasticsearch索引里的数据,使用各种不同的图标、表格、地图等,kibana能够很轻易的展示高级数据分析与可视化。

一个简单的 ELK 架构图如下:

在这种架构中,Logstash 通过输入插件从多种数据源(比如日志文件、标准输入 Stdin 等)获取数据,再经过滤插件加工数据,然后经 Elasticsearch 输出插件输出到 Elasticsearch,通过 Kibana 进行可视化展示。

这种架构非常简单,使用场景也有限。初学者可以搭建这个架构,了解 ELK 工作模式, 但是生产环境中并不推荐. 如要有以下问题:

  • Logstash 依赖 java、在数据量大的时候,Logstash 进程会消耗过多的系统资源,这将严重影响业务系统的性能。因此官网现已经推荐通过 filebeat 代替 Logstash Agent。

  • Logstash 将资源耗尽系统或者其自身出故障的问题时,日志数据将会出现丢失等问题,因此引入 Kafka 集群作为消息缓冲队列以提高数据传输的可靠性和稳定性。

如此一来, 此架构特别适合大型集群、海量数据的业务场景,它通过将前端 Logstash Agent 替换成 filebeat,有效降低了收集日志对业务系统资源的消耗。同时,消息队列使用kafka集群架构,有效保障了收集数据的安全性和稳定性,而后端Logstash和Elasticsearch均采用集群模式搭建,从整体上提高了ELK系统的高效性、扩展性和吞吐量。推荐的架构图如下:

2. 环境搭建

本文首先采用最简单的架构方式进行搭建, 后续博文将一步一步完善到生产环境集成消息队列的架构方式. 本次环境采用 Docker 或者 DockerCompose 搭建, 如果还不能熟练使用麻溜去看帅帅之前发布的 Docker 全家桶系列视频教程:

版本如下:

  • Elasticsearch: 6.8.16

  • Logstash: 6.8.16

  • Kibana: 6.8.16

2.1 拉取镜像创建网络

docker pull elasticsearch:6.8.16
docker pull kibana:6.8.16
docker pull docker.elastic.co/logstash/logstash:6.8.16
# 创建 ELK 运行的网络
docker network create elastic

2.2 ElasticSearch

  • 配置 elasticsearch.yml

cluster.name: "es-docker-cluster"
network.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
  • 安装与启动

通过如下 Docker 命令:

docker run -d --name elasticsearch --network elastic \
-p 9200:9200 -p 9300:9300 \
-e node.name=esNode -e cluster.name=es-docker-cluster -e discovery.type=single-node \
-e bootstrap.memory_lock=true -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" \
-v ${CONF_DIR}/es:/usr/share/elasticsearch/config \
-v ${VOLUME_DATA_DIR}/es:/usr/share/elasticsearch/data \
-v ${LOGS_DIR}/es:/usr/share/elasticsearch/logs \
elasticsearch:6.8.16

      其中, CONF_DIR, VOLUME_DATA_DIR, LOGS_DIR 是我本地配置的环境变量, 指向一个固定的文件夹用于挂载 Docker 容器的配置文件, 数据卷和日志文件.

  • 测试

访问 http://localhost:9200/ 看到如下界面就表示 Elasticsearch 启动成功.

2.3 Kibana

  • 配置 kibana.yml

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
  • 安装

docker run -d --name kibana --network elastic \
-p 5601:5601 \
--link elasticsearch:elasticsearch \
-e ELASTICSEARCH_URL=http://elasticsearch:9200 \
-e ELASTICSEARCH_HOSTS='["http://elasticsearch:9200"]' \
-v ${CONF_DIR}/kibana:/usr/share/kibana/config \
kibana:6.8.16
  • 测试

访问 http://localhost:5601/ 看到如下界面就表示 Kibana 启动成功.

2.4 Logstash

  • 配置 logstash.yml

http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.enabled: true
  • 配置 pipeline/logstash.conf 指定 logstash 输入输出

# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
tcp {
id => "toEs"
mode => "server"
host => "0.0.0.0"
port => 9600
codec => json_lines
}
}

filter {
}

output {
stdout {
codec => rubydebug
}

elasticsearch {
hosts => ["elasticsearch:9200"]
action => "index"
index => "applog"
}
}

从 9600 端口获取数据并做两个输出, 一个输出到标准输出, 一个是通过 Elasticsearch 插件写入 Elasticsearch, 且写入 Elasticsearch 时索引名为 <applog>

  • 启动

docker run -d --name logstash --network elastic \
-p 5044:5044 -p 9600:9600 \
--link elasticsearch:elasticsearch \
-v ${CONF_DIR}/logstash/config/:/usr/share/logstash/config/ \
-v ${CONF_DIR}/logstash/pipeline/:/usr/share/logstash/pipeline/ \
docker.elastic.co/logstash/logstash:6.8.16
  • 检查是否启动成功


    • 通过 logstash 启动日志查看


    • 通过 KIbana: 进入 Kibana 的 monitoring 视图

      当在 Kibana 中看到 Elasticsearch, Kibana, Logstash 都启动成功就表明我们 ELK 环境搭建就完成了.

3. 集成 SpringBoot, 并将日志写入 ELK

准备一个 SpringBoot 测试环境:

  • SpringBoot 版本: 2.4.1

  • logback 版本: 1.2.4

3.1 引入依赖

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

      需要特别注意的是 Spring boot web 环境中携带了 spring-boot-starter-logging, logback-core, logback-classic, logback-access 这几个必要包, 但是版本可能和 Logstash 不匹配, 因此最好是在 dependencyManagement 中对版本进行管理控制.

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>

</dependencies>
</dependencyManagement>

3.2 配置 logback

在 类路径 resources 下新建 logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<include resource="org/springframework/boot/logging/logback/base.xml" />
<contextName>logback</contextName>
<!-- 指定日志写入本机 9600 端口 -->
<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>127.0.0.1:9600</destination>
<!-- encoder必须配置,有多种可选 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>

<root level="info">
<appender-ref ref="stash" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

3.3 编写测试方法

@RestController
public class TestLoggingController {

@GetMapping("/logging")
public void testLogging() {
LOGGER.info("Come in test logging...");

LOGGER.debug("这是一个 Debug 级别的日志");
LOGGER.info("这是一个 INFO 级别的日志");
LOGGER.warn("这是一个 WARN 级别的日志");
LOGGER.error("这是一个 ERROR 级别的日志");
LOGGER.error("这是一个 ERROR 级别的日志, 并携带了一个 Exception.",
new UnsupportedOperationException("暂不支持操作的异常!"));
}

3.4 测试

访问 http://localhost/logging (端口改为了 80)

  • Logstash 后台可以看到如下输出(因为logstash.conf引入了标准输出组件)

  • Kibana/Management 可以看到索引 applog 已经被创建, 加入 Index Pattern

进入 Discover 即可看到日志已经在 Kibana 中可以可视化

至此, ELK 日志采集系统便已经成功搭建完成.

4. 下一步

      后面我们会对这个架构所存在的问题逐一进行验证和解决, 最终达到一个生产环境高可用的架构模式. 大家持续关注!


      既然大侠已经看到这里了, 那小弟也不藏着掖着了, 公众号后台回复ELK 即可拿到帅帅整理好的 ELK docker compose 配置文件, 一个 up 命令启动 ELK, 一个 down 命令停止 ELK, 它 不香吗?





        如果有任何相关的问题都可以加入 QQ/微信群一起讨论, 学习, 进步. 此外如果有任何对于本公众号的意见和建议也欢迎大家留言积极批评指正, 最后, 愿你我都能成为更好的自己. 


        我是帅帅, 一个集帅气, 幽默与内涵, 并且热爱编程, 拥抱开源, 喜欢烹饪与旅游的暖男, 我们下期再见. 拜了个拜! 

      老规矩别忘了哦, 点击原文链接跳转到我们官方的博客平台哦.


悄悄话




每文一句



Don't aim for success if you really want it. Just stick to what you love and believe in, and it will come naturally.

少一些功利主义的追求, 多一些不为什么的坚持.


日常求赞

      你们白漂的力量就是我拖更的史诗级动力, 点赞, 评论, 再看, 赞赏, 看都看到这了, 随便点一个咯.



关注加好友


拉你进大佬交流群




浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报