ELK 日志采集系统搭建
一般我们需要进行日志分析场景:直接在日志文件中 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.16Logstash
: 6.8.16Kibana
: 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, 它 不香吗?