ELK日志分析平台
ELK日志分析系统是Logstash、Elastcsearch、Kibana开源软件的集合,对外是作为一个日志管理系统的开源方案,它可以从任何来源、任何格式进行日志搜索、分析与可视化展示。
1.ELK日志分析系统组成
elasticsearch (es) :通过搭建群集;存储日志数据,索引日志数据。 logstash :收集日志,收集到了后给es存储。 kibana :视图形式展现日志信息,更加人性化。
2.日志处理步骤
将日志进行集中化管理。 将日志格式化(Logstash)并输出到Elasticsearch。 对格式化后的数据进行索引和存储(Elasticsearch)。 前端数据的展示(Kibana)。
软件简介
一、Elasticsearch
1.Elasticsearch的概述
提供了一个分布式多用户能力的全文搜索引擎。
2.Elasticsearch核心概念
2.1接近实时(NRT)
elasticsearch是一个接近实时的搜索平台,这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒)。
2.2集群(cluster)
一个集群就是由一个或多个节点组织在一起,它们共同持有你整个的数据,并一起提供索引和搜索功能。其中一个节点为主节点,这个主节点是可以通过选举产生的,并提供跨节点的联合索引和搜索的功能。集群有一个唯一性标示的名字,默认是elasticsearch,集群名字很重要,每个节点是基于集群名字加入到其集群中的。因此,确保在不同环境中使用不同的集群名字。
—个集群可以只有一个节点。强烈建议在配置elasticsearch时,配置成集群模式。
es具有集群机制,节点通过集群名称加入到集群中,同时在集群中的节点会有一个自己的唯一身份标识(自己的名称)。
2.3节点(node)
节点就是一台单一的服务器,是集群的一部分,存储数据并参与集群的索引和搜索功能。像集群一样,节点也是通过名字来标识,默认是在节点启动时随机分配的字符名。当然,你可以自己定义。该名字也很重要,在集群中用于识别服务器对应的节点。
节点可以通过指定集群名字来加入到集群中。默认情况,每个节点被设置成加入到elasticsearch集群。如果启动了多个节点,假设能自动发现对方,他们将会自动组建一个名为elasticsearch的集群。
2.4索引 (type)
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类!分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。
类型相对于关系型数据库的表 ——》索引(库)-》类型(表)-》文档(记录)
2.5文档(document)
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation))格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,只要你想,你可以存储任意多的文档。注意,虽然一个文档在物理上位于一个索引中,实际上一个文档必须在一个索引内被索引和分配一个类型。文档相对于关系型数据库的列。
2.6分片和副本(shards & replicas)
在实际情况下,索引存储的数据可能超过单个节点的硬件限制。如一个10亿文档需1TB空间可能不适合存储在单个节点的磁盘上或者从单个节点搜索请求太慢了。为了解决这个问题,elasticsearch提供将索引分成多个分片的功能。当在创建索引时,可以定义想要分片的数量。每一个分片就是一个全功能的独立的索引,可以位于集群中任何节点上。
分片的两个最主要原因:
- a.水平分割扩展,增大存储量
- b.分布式并行跨分片操作,提高性能和吞吐量
分布式分片的机制和搜索请求的文档如何汇总完全是有elasticsearch控制的,这些对用户而言是透明的。
网络问题等等其它问题可以在任何时候不期而至,为了健壮性,强烈建议要有一个故障切换机制,无论何种故障以防止分片或者节点不可用。为此,elasticsearch让我们将索引分片复制一份或多份,称之为分片副本或副本。
副本也有两个最主要原因:
- a.高可用性,以应对分片或者节点故障。出于这个原因,分片副本要在不同的节点上。
- b.能增大吞吐量,搜索可以并行在所有副本上执行。
二、Filebeat
Filebeat 是一个轻量级的传送器,用于转发和集中日志数据。Filebeat 作为代理安装在您的服务器上,监控您指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或 Logstash以进行索引。
Filebeat 的工作原理如下:当您启动 Filebeat 时,它会启动一个或多个输入,这些输入会在您为日志数据指定的位置中查找。对于 Filebeat 找到的每个日志,Filebeat 都会启动一个收割机。每个收割机读取新内容的单个日志,并将新日志数据发送到 libbeat,后者聚合事件并将聚合数据发送到您为 Filebeat 配置的输出。
三、Redis
1.Redis简介
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
2.Redis优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
3.Redis与其他key-value存储有什么不同?
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
四、Logstash
1.Logstash介绍
- —款强大的数据处理工具
- 可实现数据传输、格式处理、格式化输出
- 数据输入(从业务输入)、数据加工(如过滤、改写等)以及数据输出(输出到Elasticsearch群集)
2.Logstash的主要组件
- shipper:日志收集者,负责监控本地日志文件的变化,及时把日志文件的最新内容收集起来。通常,远程代理端(agent)只需要运行这个组件即可
- indexer:日志存储者,负责接收日志并写入到本地文件
- broker:日志hub,负责连接多个shipper和多个indexer
- search and storage:允许对事件进行搜索和存储
- web interface:基于wWeb的展示界面
五、Kibana
1.Kibana介绍
- 一个针对Elasticsearch的开源分析及可视化平台
- 搜索、查看存储在Elasticsearch索引中的数据
- 通过各种图表进行高级数据分析及展示
2.Kibana主要功能
- Elasticsearch无缝之集成
- 整合数据,复杂数据分析
- 让更多团队成员受益
- 接口灵活,分享更容易
- 配置简单,可视化多数据源
- 简单数据导出
环境介绍:
192.168.1.21
2核4G
es-master21
filebeat、redis、logstash、elasticsearch、elasticsearch-head、kibana
192.168.1.22
1核2G
es-node22
elasticsearch
192.168.1.23
1核2G
es-node23
elasticsearch
注意:
Linux内核:3.10.0-862.el7.x86_64(不低于3.10.0)。
ELK Filebeat软件版本均为7.10.1,redis为最新latest,插件为elasticsearch-head:5版本。
首先 logstash 具有日志采集、过滤、筛选等功能,功能完善但同时体量也会比较大,消耗系统资源自然也多。filebeat作为一个轻量级日志采集工具,虽然没有过滤筛选功能,但是仅仅部署在应用服务器作为我们采集日志的工具可以是说最好的选择。但我们有些时候可能又需要logstash的过滤筛选功能,所以我们在采集日志时用filebeat,然后交给logstash过滤筛选。
其次,logstash的吞吐量是有限的,一旦短时间内filebeat传过来的日志过多会产生堆积和堵塞,对日志的采集也会受到影响,所以在filebeat与logstash中间又加了一层kafka消息队列来缓存或者说解耦,当然redis也是可以的。这样当众多filebeat节点采集大量日志直接放到kafka/redis中,logstash慢慢的进行消费,两边互不干扰。
说明:
WEB服务日志代表收集的对象,由Filebeat收集日志后发送至Redis消息队列,然后Logstash将Redis中的数据拿出来由ElasticSearch收集处理并由Kibana进行可视化显示。(在生产中可以将各个功能单点进行扩展,例如将Redis和Logstash集群化。
)
企业级日志分析平台ELK部署
一、环境准备
1.修改主机名
代码语言:javascript复制[root@localhost ~]# echo es-master21 > /etc/hostname //永久修改主机名(重启生效),临时修改可以直接hostname es-master21,重新打开远程终端即可
[root@localhost ~]# echo es-node22 > /etc/hostname
[root@localhost ~]# echo es-node23 > /etc/hostname
2.关闭防火墙及selinux
代码语言:javascript复制[root@es-master21/es-node22/23 ~]# systemctl stop firewalld && systemctl disable firewalld
[root@es-master21/es-node22/23 ~]# setenforce 0 //临时关闭
[root@es-master21/es-node22/23 ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config //永久关闭
3.配置主机名解析
代码语言:javascript复制[root@es-master21/es-node22/23 ~]# cat >> /etc/hosts << EOF
> 192.168.1.21 es-master21
> 192.168.1.22 es-node22
> 192.168.1.23 es-node23
> EOF
[root@es-master21/es-node22/23 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.21 es-master21
192.168.1.22 es-node22
192.168.1.23 es-node23
4.系统参数优化
代码语言:javascript复制[root@es-master21 ~]# cat >> /etc/security/limits.conf << EOF
> * soft nofile 65536
> * hard nofile 131072
> * soft nproc 2048
> * hard nproc 4096
> EOF
[root@es-master21 ~]# for i in {22..23}
> do
> scp /etc/security/limits.conf root@192.168.1.$i:/etc/security/
> done
-----------------------------------------
[root@es-master21 ~]# vim /etc/sysctl.conf
vm.max_map_count=655360
[root@es-master21 ~]# for i in {22..23}
> do
> scp /etc/sysctl.conf root@192.168.1.$i:/etc/
> done
[root@es-node22/23 ~]# cat /etc/sysctl.conf //优化内核,对es支持
vm.max_map_count=655360
[root@es-node22/23 ~]# sysctl -p //使配置生效
vm.max_map_count = 655360
-----------------------------------------
[root@es-master21 ~]# vim /etc/security/limits.d/20-nproc.conf //设置普通用户最大打开进程数为65535(默认root用户打开进程数不限制,普通用户最大打开进程数4096)
* soft nproc 65535
* hard nproc 65535
root soft nproc unlimited
[root@es-master21 ~]# for i in {22..23}
> do
> scp /etc/security/limits.d/20-nproc.conf root@192.168.1.$i:/etc/security/limits.d/
> done
[root@es-node22/23 ~]# cat /etc/security/limits.d/20-nproc.conf
* soft nproc 65535
* hard nproc 65535
root soft nproc unlimited
[root@es-master21 ~]# ulimit -u //查询用户最大可用的进程数
65535
5.安装docker和docker compose
一文搞懂Docker与Docker Engine的安装 一文学会配置Docker 国内镜像加速器 一文学会Docker Compose安装
代码语言:javascript复制#查看docker安装后版本
[root@es-master21/es-node22/23 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.11
API version: 1.41
Go version: go1.16.9
Git commit: dea9396
Built: Thu Nov 18 00:38:53 2021
OS/Arch: linux/amd64
Context: default
......
#配置镜像加速器与修改docker默认存储路径
[root@es-master21/es-node22/23 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://xxxjf6.mirror.aliyuncs.com"],
"graph": "/mnt/data" //修改docker默认存储路径
}
[root@es-master21/es-node22/23 ~]# docker info
......
Docker Root Dir: /mnt/data //docker存储路径已修改
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://xxxx3jf6.mirror.aliyuncs.com/ //镜像加速器地址
Live Restore Enabled: false
#安装docker compose
[root@es-master21/es-node22/23 ~]# curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
[root@es-master21/es-node22/23 ~]# chmod x /usr/local/bin/docker-compose
[root@es-master21/es-node22/23 ~]# docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
----->这此以上的环境配置安装步骤所有主机都需要做!!!
6.下载各个服务的镜像
代码语言:javascript复制[root@es-master21/es-node22/23 ~]# docker pull elasticsearch:7.10.1
[root@es-master21 ~]# docker pull kibana:7.10.1
[root@es-master21 ~]# docker pull redis:latest
[root@es-master21 ~]# docker pull mobz/elasticsearch-head:5
[root@es-master21 ~]# docker pull logstash:7.10.1
[root@es-master21 ~]# docker pull store/elastic/filebeat:7.10.1
二、搭建Elasisearch集群
1.宿主机es-master21操作
[root@es-master21 ~]# mkdir -p /mnt/elasticsearch/data
[root@es-master21 ~]# cd /mnt/
[root@es-master21 mnt]# vim docker-compose.yml (使用时删除配置文件中所有的#注释信息,否则可能格式报错)
version: '2.2'
services:
elasticsearch: #服务名称
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1 #使用的镜像及版本
container_name: elasticsearch #容器名称
restart: always #失败自动重启策略
environment:
- cluster.name=myes-cluster #集群名称,相同名称为一个集群,三个es节点必须一致。
- node.name=es01 #节点名称,集群模式下每个节点名称唯一
- network.publish_host=192.168.1.21 #用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP。
- discovery.seed_hosts=192.168.1.21,192.168.1.22,192.168.1.23 #写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点。
- cluster.initial_master_nodes=192.168.1.21,192.168.1.22,192.168.1.23 #初始化一个新的集群时需要此配置来选举master
- bootstrap.memory_lock=true #内存交换的选项,官网建议设置为true。
ulimits: #栈内存的上限
memlock:
soft: -1 #不限制
hard: -1 #不限制
volumes:
- /mnt/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml #将容器中es的配置文件映射到本地
- /mnt/elasticsearch/data:/usr/share/elasticsearch/data #将es容器内存放数据路径映射到本地
ports:
- 9200:9200 #http端口,可以直接浏览器访问。
- 9300:9300 #es集群之间相互访问的端口,jar之间就是通过此端口进行tcp协议通信,遵循tcp协议。
elasticsearch-head: #elasticsearch可视化插件
image: mobz/elasticsearch-head:5
container_name: elasticsearch-head
restart: always
ports:
- 9100:9100 #http端口,可以直接浏览器访问。
----->编写elasticsearch.yml文件<-----
||
[root@es-master21 ~]# cd /mnt/elasticsearch
[root@es-master21 elasticsearch]# vim elasticsearch.yml
cluster.name: "myes-cluster" #es集群名称,相同名称为一个集群,三个es节点必须一致
network.host: 0.0.0.0 #设置服务绑定的IP地址,0.0.0.0表示所有地址
http.cors.enabled: true #是否支持跨域
http.cors.allow-origin: "*" #表示支持所有域名
[root@es-master21 mnt]# docker-compose -f docker-compose.yml up -d #启动elasticsearch集群节点
[root@es-master21 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
elasticsearch-head /bin/sh -c grunt server Up 0.0.0.0:9100->9100/tcp,:::9100->9100/tcp
2.宿主机es-node22操作
[root@es-node22 ~]# mkdir -p /mnt/elasticsearch/data
[root@es-node22 ~]# cd /mnt/
[root@es-node22 mnt]# vim docker-compose.yml
version: '2.2'
services:
elasticsearch: #服务名称
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1 #使用的镜像及版本
container_name: elasticsearsh #容器名称
restart: always #失败自动重启策略
environment:
- cluster.name=myes-cluster #集群名称,相同名称为一个集群,三个es节点必须一致
- node.name=es02 #节点名称。集群模式下每个节点名称唯一
- network.publish_host=192.168.1.22 #用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP。
- discovery.seed_hosts=192.168.1.21,192.168.1.22,192.168.1.23 #写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点
- cluster.initial_master_nodes=192.168.1.21,192.168.1.22,192.168.1.23 #初始化一个新的集群时需要此配置来选举master
- bootstrap.memory_lock=true #内存交换的选项,官网建议为true。
ulimits: #栈内存的上限
memlock:
soft: -1 #不限制
hard: -1 #不限制
volumes:
- /mnt/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml #将容器中es的配置文件映射到本地
- /mnt/elasticsearch/data:/usr/share/elasticsearch/data #将es容器内存放数据路径映射到本地
ports:
- 9200:9200 #http端口,可以直接浏览器访问
- 9300:9300 #es集群之间相互访问的端口,jar之间就是通过此端口进行tcp协议通信,遵循tcp协议。
----->编写elasticsearch.yml文件<-----
||
[root@es-node22 ~]# cd /mnt/elasticsearch
[root@es-node22 elasticsearch]# vim elasticsearch.yml
cluster.name: "myes-cluster" #es集群名称,相同名称为一个集群,三个es节点必须一致。
network.host: 0.0.0.0 #设置服务绑定的IP地址,0.0.0.0表示所有地址
http.cors.enabled: true #是否支持跨域
http.cors.allow-origin: "*" #表示支持所有域名
[root@es-node22 mnt]# docker-compose -f docker-compose.yml up -d #启动elasticsearch集群节点
[root@es-node22 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
3.宿主机es-node23操作
[root@es-node23 ~]# mkdir -p /mnt/elasticsearch/data
[root@es-node23 ~]# cd /mnt/
[root@es-node23 mnt]# vim docker-compose.yml
version: '2.2'
services:
elasticsearch: #服务名称
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1 #使用的镜像及版本
container_name: elasticsearsh #容器名称
restart: always #失败自动重启策略
environment:
- cluster.name=myes-cluster #集群名称,相同名称为一个集群,三个es节点必须一致
- node.name=es03 #节点名称。集群模式下每个节点名称唯一
- network.publish_host=192.168.1.23 #用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP。
- discovery.seed_hosts=192.168.1.21,192.168.1.22,192.168.1.23 #写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点
- cluster.initial_master_nodes=192.168.1.21,192.168.1.22,192.168.1.23 #初始化一个新的集群时需要此配置来选举master
- bootstrap.memory_lock=true #内存交换的选项,官网建议为true
hostname: elasticsearch #服务hostname
ulimits: #栈内存的上限
memlock:
soft: -1 #不限制
hard: -1 #不限制
volumes:
- /mnt/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml #将容器中es的配置文件映射到本地
- /mnt/elasticsearch/data:/usr/share/elasticsearch/data #将es容器内存放数据路径映射到本地
ports:
- 9200:9200 #http端口,可以直接浏览器访问。
- 9300:9300 #es集群之间相互访问的端口,jar之间就是通过此端口进行tcp协议通信,遵循tcp协议。
----->编写elasticsearch.yml文件<-----
||
[root@es-node23 ~]# cd /mnt/elasticsearch
[root@es-node23 elasticsearch]# vim elasticsearch.yml
cluster.name: "myes-cluster" #es集群名称,相同名称为一个集群,三个es节点必须一致
network.host: 0.0.0.0 #设置服务绑定的IP地址,0.0.0.0表示所有地址
http.cors.enabled: true #是否支持跨域
http.cors.allow-origin: "*" #表示支持所有域名
[root@es-node23 mnt]# docker-compose -f docker-compose.yml up -d #启动elasticsearch集群节点(执行此命令要在docker-compose.yml文件路径下执行)
[root@es-node23 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
访问Elasticsearch集群
三、搭建Filebeat
宿主机es-master21操作
注意: Filebeat要采集的日志目录必须挂载至Filebeat容器中,不然可能无法正常采集。
代码语言:javascript复制---Nginx日志---
[root@es-master21 ~]# ll -h /var/log/nginx/
总用量 69M
-rwxr-xr-x. 1 root root 68M 12月 13 15:15 access.log
-rwxr-xr-x. 1 root root 1.8M 12月 7 23:09 error.log
[root@es-master21 ~]# mkdir -p /mnt/filebeat/
[root@es-master21 ~]# cd /mnt/
[root@es-master21 mnt]# vim docker-compose.yml
......
......
filebeat:
image: store/elastic/filebeat:7.10.1 #镜像依然选择与elk的版本一致
container_name: filebeat
restart: always
volumes:
- /var/log/nginx/:/var/log/nginx #filebeat需要采集的nginx日志目录(必须要挂载至容器中)
- /mnt/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro #filebeat的配置文件
- /etc/localtime:/etc/localtime
----->编写filebeat.yml文件<-----
||
[root@es-master21 mnt]# cd filebeat/
[root@es-master21 filebeat]# vim filebeat.yml (使用时删除文件中带#的配置项,不然yml文件格式不对)
filebeat.inputs: #inputs为复数,表名type可以有多个
#- type: log #输入类型
# access:
# enabled: true #启用这个type配置
# max_bytes: 20480 #单条日志的大小限制,建议限制(默认为10M,queue.mem.events * max_bytes 将是占有内存的一部分)
# paths:
# - /var/log/nginx/access.log #监控nginx的access日志,建议采集日志时先采集单一nginx的access日志。
# close_rename: true #重命名后,文件将不会继续被采集信息
# tail_files: true #配置为true时,filebeat将从新文件的最后位置开始读取,如果配合日志轮循使用,新文件的第一行将被跳过
# fields: #额外的字段(表示在filebeat收集Nginx的日志中多增加一个字段source,其值是nginx-access-21,用来在logstash的output输出到elasticsearch中判断日志的来源,从而建立相应的索引,也方便后期再Kibana中查看筛选数据,结尾有图)
# source: nginx-access-21
- type: log
access:
enabled: true
paths:
- /var/log/nginx/error.log
fields:
source: nginx-error-21 #额外的字段(表示在filebeat收集Nginx的日志中多增加一个字段source,其值是nginx-error-21,用来在logstash的output输出到elasticsearch中判断日志的来源,从而建立相应的索引,也方便后期再Kibana中查看筛选数据,结尾有图)
setup.ilm.enabled: false
output.redis: #输出到redis
hosts: ["192.168.1.21:6379"] #redis地址及端口
password: "123456" #redis密码
db: 0 #redis的库
key: "nginx_log" #定义输入到redis的key名
[root@es-node22 mnt]# docker-compose -f docker-compose.yml up -d
[root@es-master21 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
elasticsearch-head /bin/sh -c grunt server Up 0.0.0.0:9100->9100/tcp,:::9100->9100/tcp
filebeat /usr/local/bin/docker-entr ... Up
注意:
不同的应用日志使用不同的redis的key值,使用output.redis中的keys值,官方例子:
代码语言:javascript复制output.redis:
hosts: ["localhost"]
key: "default_list"
keys:
- key: "error_list" #如果“message”字段包含error,则发送到error_list
when.contains:
message: "error"
- key: "debug_list" #如果“message”字段包含debug,则发送到debug_list
when.contains:
message: "DEBUG"
- key: "%{[fields.list]}"
说明:默认的key值是default_list,keys的值是动态分配创建的,当redis接收到的日志中message字段的值包含有error字段,则创建key为error_list,当包含有DEBUG字段,则创建key为debug_list。 问题的解决方法是在每个应用的输出日志中新增一个能够区分这个日志的值,然后再在keys中设置,这样一来就能够把不同应用的日志输出到不同的redis的key中。
四、搭建Redis
宿主机es-master21操作
[root@es-master21 ~]# mkdir -p /mnt/redis/data
[root@es-master21 ~]# mkdir -p /mnt/redis/conf
[root@es-master21 ~]# mkdir -p /mnt/redis/log
[root@es-master21 ~]# cd /mnt/
[root@es-master21 mnt]# vim docker-compose.yml
......
......
redis:
image: redis
restart: always
container_name: redis
environment:
- TZ=Asia/Shanghai
ports:
- 6379:6379
volumes:
- /mnt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /mnt/redis/data/:/data
- /mnt/redis/log/redis.log:/var/log/redis/redis.log
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
----->编写redis.conf文件<-----
||
[root@es-master21 mnt]# vim redis/conf/redis.conf
bind 0.0.0.0
port 6379
requirepass 123456
save ""
pidfile /var/run/redis/redis.pid
#logfile /var/log/redis/redis.log
[root@es-master21 mnt]# docker-compose -f docker-compose.yml up -d
[root@es-master21 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
elasticsearch-head /bin/sh -c grunt server Up 0.0.0.0:9100->9100/tcp,:::9100->9100/tcp
filebeat /usr/local/bin/docker-entr ... Up
logstash /usr/local/bin/docker-entr ... Up 0.0.0.0:5044->5044/tcp,:::5044->5044/tcp,
9600/tcp
redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp,:::6379->6379/tcp
`查看Redis中由Filebeat采集后写进来的nginx日志数据`
代码语言:javascript复制[root@es-master21 mnt]# docker exec -it redis bash
root@d5a4be90c7f6:/# redis-cli -h 192.168.1.21
192.168.1.21:6379> AUTH 123456
OK
192.168.1.21:6379> SELECT 0
OK
192.168.1.21:6379> KEYS * #创建的key为nginx_log
1) "nginx_log"
192.168.1.21:6379> LLEN nginx_log
(integer) 7167 #可以看到redis的nginx_log中有7167条数据未被消费
五、搭建Logstash
宿主机es-master21操作
[root@es-master21 ~]# mkdir -p /mnt/logstash/data
[root@es-master21 ~]# mkdir -p /mnt/logstash/config
[root@es-master21 ~]# cd /mnt/
[root@es-master21 mnt]# vim docker-compose.yml
......
......
logstash:
image: docker.elastic.co/logstash/logstash:7.10.1
container_name: logstash
hostname: logstash
restart: always
environment:
TZ: "Asia/Shanghai"
ports:
- 5044:5044
volumes:
- /mnt/logstash/config/logstash.conf:/usr/share/logstash/conf.d/logstash.conf
- /mnt/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
- /mnt/logstash/data:/usr/share/logstash/data
- /etc/localtime:/etc/localtime
depends_on:
- elasticsearch #依赖es服务,必须先启动es才会启动logstash
----->编写logstash.yml与logstash.conf文件<-----
||
[root@es-master21 mnt]# cd logstash/
[root@es-master21 logstash]# vim logstash.yml
http.host: "0.0.0.0"
path.config: /usr/share/logstash/conf.d/*.conf
path.logs: /var/log/logstash
xpack.monitoring.enabled: true #默认情况下logstash禁用监控,设置为true以启用X-Pack监控。
xpack.monitoring.elasticsearch.hosts: ["192.168.1.21:9200","192.168.1.22:9200","192.168.1.23:9200"] #为es服务器列表以及端口号,用于将数据存储到es
#pipeline.batch.size: 3000 #指发送到Elasticsearch的批量请求的大小,值越大,处理则通常更高效,但增加了内存开销
#pipeline.batch.delay: 200 #指调整Logstash管道的延迟,过了该时间则logstash开始执行过滤器和输出
[root@es-master21 logstash]# vim config/logstash.conf (使用时删除文件中带#的配置项,不然yml文件格式不对)
input {
redis {
port => "6379"
host => "192.168.1.21"
password => "123456"
data_type => "list"
db => "0"
key => "nginx_log"
}
}
output {
elasticsearch {
hosts => ["http://192.168.1.21:9200","http://192.168.1.22:9200","http://192.168.1.23:9200"]
}
stdout { codec => rubydebug }
}
[root@es-node22 mnt]# docker-compose -f docker-compose.yml up -d
[root@es-master21 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
elasticsearch-head /bin/sh -c grunt server Up 0.0.0.0:9100->9100/tcp,:::9100->9100/tcp
filebeat /usr/local/bin/docker-entr ... Up
logstash /usr/local/bin/docker-entr ... Up 0.0.0.0:5044->5044/tcp,:::5044->5044/tcp,
9600/tcp
查看Logstash日志,输出从Redis消费并处理的日志数据
代码语言:javascript复制[root@es-master21 mnt]# docker-compose logs -f logstash
...
...
logstash | "message" => "2021/10/23 01:06:00 [alert] 27214#0: *357982 write() to "/usr/local/nginx/logs/access.log" client: 209.14.12.185, server: localhost, request: "GET /config/getuser?index=0 HTTP/1.1", host: "39.98.155.11:80""
logstash | }
logstash | {
logstash | "log" => {
logstash | "file" => {
logstash | "path" => "/var/log/nginx/error.log"
logstash | },
logstash | "offset" => 1863165
logstash | },
logstash | "@timestamp" => 2021-12-27T09:22:37.192Z,
logstash | "host" => {
logstash | "name" => "7fddb131a96b"
logstash | },
logstash | "fields" => {
logstash | "source" => "nginx-error-21"
logstash | },
logstash | "@version" => "1",
logstash | "input" => {
logstash | "type" => "log"
logstash | },
logstash | "ecs" => {
logstash | "version" => "1.6.0"
logstash | },
logstash | "agent" => {
logstash | "hostname" => "7fddb131a96b",
logstash | "version" => "7.10.1",
logstash | "name" => "7fddb131a96b",
logstash | "id" => "95b7e319-228c-4eed-b9c8-26fad0c59d3b",
logstash | "type" => "filebeat",
logstash | "ephemeral_id" => "76ec6bc4-39e9-4364-94fb-20f0a7f49122"
logstash | },
logstash | "message" => "2021/10/23 01:29:28 [alert] 27216#0: *357983 write() to "/usr/local/nginx/logs/access.log" failed (28: No space left on device) while logging request, client: 83.25.20.34, server: localhost, request: "GET / HTTP/1.1", host: "39.98.155.11""
logstash | }
logstash | {
logstash | "log" => {
logstash | "file" => {
logstash | "path" => "/var/log/nginx/error.log"
logstash | },
logstash | "offset" => 1863404
logstash | },
logstash | "@timestamp" => 2021-12-27T09:22:37.192Z,
logstash | "fields" => {
logstash | "source" => "nginx-error-21"
logstash | },
logstash | "host" => {
logstash | "name" => "7fddb131a96b"
logstash | },
logstash | "@version" => "1",
logstash | "input" => {
logstash | "type" => "log"
logstash | },
logstash | "ecs" => {
logstash | "version" => "1.6.0"
logstash | },
logstash | "agent" => {
logstash | "hostname" => "7fddb131a96b",
logstash | "version" => "7.10.1",
logstash | "name" => "7fddb131a96b",
logstash | "id" => "95b7e319-228c-4eed-b9c8-26fad0c59d3b",
logstash | "type" => "filebeat",
logstash | "ephemeral_id" => "76ec6bc4-39e9-4364-94fb-20f0a7f49122"
logstash | },
logstash | "message" => "2021/10/23 01:36:39 [alert] 27214#0: *357985 write() to "/usr/local/nginx/logs/access.log" client: 119.108.53.121, server: localhost, request: "GET / HTTP/1.1", host: "saas.weizujikeji.com""
查看Elasticsearch集群中是否有日志数据写入
六、搭建Kibana
宿主机es-master21操作
[root@es-master21 ~]# mkdir -p /mnt/kibana/config
[root@es-master21 ~]# mkdir -p /mnt/kibana/data
[root@es-master21 ~]# mkdir -p /mnt/kibana/plugins
[root@es-master21 ~]# cd /mnt/
[root@es-node23 mnt]# vim docker-compose.yml
......
......
kibana:
image: kibana:7.10.1
container_name: kibana
environment:
- elasticsearch.hosts=http://192.168.1.21:9200
- TZ=Asia/Shanghai
hostname: kibana
depends_on:
- elasticsearch #依赖es服务,必须先启动es才会启动kibana
restart: always
ports:
- 5601:5601
volumes:
- /mnt/kibana/config:/usr/share/kibana/config
- /mnt/kibana/data:/usr/share/kibana/data
- /mnt/kibana/plugins:/usr/share/kibana/plugins
----->编写kibana.yml文件<-----
||
[root@es-node23 mnt]# cd kibana/
[root@es-node23 kibana]# vim config/kibana.yml
server.name: kibana #Kibana实例对外展示的名称
server.host: "0.0.0.0" #指定后端服务器的主机地址,0.0.0.0代表全部地址
elasticsearch.hosts: ["http://192.168.1.21:9200","http://192.168.1.22:9200","http://192.168.1.23:9200"] #设置连接的es节点
monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN" #kibana6.7以后支持配置中文汉化
[root@es-master21 mnt]# docker-compose -f docker-compose.yml up -d
[root@es-master21 mnt]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
elasticsearch /tini -- /usr/local/bin/do ... Up 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
elasticsearch-head /bin/sh -c grunt server Up 0.0.0.0:9100->9100/tcp,:::9100->9100/tcp
filebeat /usr/local/bin/docker-entr ... Up
kibana /usr/local/bin/dumb-init - ... Up 0.0.0.0:5601->5601/tcp,:::5601->5601/tcp
logstash /usr/local/bin/docker-entr ... Up 0.0.0.0:5044->5044/tcp,:::5044->5044/tcp,
9600/tcp
redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp,:::6379->6379/tcp